gpt4 book ai didi

Python:YACC 的问题

转载 作者:行者123 更新时间:2023-11-28 18:55:27 24 4
gpt4 key购买 nike

我正在使用 PLY 来解析如下句子:

"CS 2310 or equivalent experience"

期望的输出:

[[("CS", 2310)], ["equivalent experience"]]

YACC 分词器符号:

tokens = [
'DEPT_CODE',
'COURSE_NUMBER',
'OR_CONJ',
'MISC_TEXT',
]

t_DEPT_CODE = r'[A-Z]{2,}'
t_COURSE_NUMBER = r'[0-9]{4}'

t_OR_CONJ = r'or'

t_ignore = ' \t'

terms = {'DEPT_CODE': t_DEPT_CODE,
'COURSE_NUMBER': t_COURSE_NUMBER,
'OR_CONJ': t_OR_CONJ}

for name, regex in terms.items():
terms[name] = "^%s$" % regex

def t_MISC_TEXT(t):
r'\S+'
for name, regex in terms.items():
# print "trying to match %s with regex %s" % (t.value, regex)
if re.match(regex, t.value):
t.type = name
return t

return t

(MISC_TEXT 用于匹配其他术语未捕获的任何内容。)

解析器的一些相关规则:

precedence = (
('left', 'MISC_TEXT'),
)


def p_statement_course_data(p):
'statement : course_data'
p[0] = p[1]

def p_course_data(p):
'course_data : course'
p[0] = p[1]


def p_course(p):
'course : DEPT_CODE COURSE_NUMBER'
p[0] = make_course(p[1], int(p[2]))


def p_or_phrase(p):
'or_phrase : statement OR_CONJ statement'
p[0] = [[p[1]], [p[3]]]


def p_misc_text(p):
'''text_aggregate : MISC_TEXT MISC_TEXT
| MISC_TEXT text_aggregate
| text_aggregate MISC_TEXT '''
p[0] = "%s %s" % (p[0], [1])

def p_text_aggregate_statement(p):
'statement : text_aggregate'
p[0] = p[1]

不幸的是,这失败了:

# works as it should
>>> token_list("CS 2110 or equivalent experience")
[LexToken(DEPT_CODE,'CS',1,0), LexToken(COURSE_NUMBER,'2110',1,3), LexToken(OR_CONJ,'or',1,8), LexToken(MISC_TEXT,'equivalent',1,11), LexToken(MISC_TEXT,'experience',1,22)]

# fails. bummer.
>>> parser.parse("CS 2110 or equivalent experience")
Syntax error in input: LexToken(MISC_TEXT,'equivalent',1,11)

我做错了什么?我不完全明白如何设置优先规则。

此外,这是我的错误函数:

def p_error(p):
print "Syntax error in input: %s" % p

有没有办法查看解析器在失败时尝试的规则?或者其他一些让解析器打印规则其尝试的方法?

更新 token_list() 只是一个辅助函数:

def token_list(string):
lexer.input(string)
result = []
for tok in lexer:
result.append(tok)
return result

更新 2:这是我想要进行的解析:

Symbol Stack                                Input Tokens                                                Action
DEPT_CODE COURSE_NUMBER OR_CONJ MISC_TEXT MISC_TEXT
DEPT_CODE COURSE_NUMBER OR_CONJ MISC_TEXT MISC_TEXT Shift DEPT_CODE
DEPT_CODE COURSE_NUMBER OR_CONJ MISC_TEXT MISC_TEXT Shift COURSE_NUMBER
course OR_CONJ MISC_TEXT MISC_TEXT Reduce course : DEPT_CODE COURSE_NUMBER
course_data OR_CONJ MISC_TEXT MISC_TEXT Reduce course_data : course
statement OR_CONJ MISC_TEXT MISC_TEXT Reduce statement : course_data
statement OR_CONJ MISC_TEXT MISC_TEXT Shift OR_CONJ

statement OR_CONJ MISC_TEXT MISC_TEXT Shift MISC_TEXT
statement OR_CONJ text_aggregate MISC_TEXT Reduce text_aggregate : MISC_TEXT
statement OR_CONJ text_aggregate MISC_TEXT Shift MISC_TEXT
statement OR_CONJ text_aggergate Reduce text_aggregate : text_aggregate MISC_TEXT

statement OR_CONJ statement Reduce statement : TEXT_AGGREGATE
or_phrase Reduce or_phrase : statement OR_CONJ statement
statement Reduce statement : or_phrase

我添加了这个解析 Action :

def p_misc_text_singleton(p):
'text_aggregate : MISC_TEXT'
p[0] = p[1]

当我尝试构建解析器时,我得到了这个输出:

Generating LALR tables
WARNING: 2 shift/reduce conflicts
WARNING: 3 reduce/reduce conflicts
WARNING: reduce/reduce conflict in state 8 resolved using rule (text_aggregate -> MISC_TEXT MISC_TEXT)
WARNING: rejected rule (text_aggregate -> MISC_TEXT) in state 8

如上所述,解析仍然因语法错误而失败。

最佳答案

我无法重现您的错误,而是在“或”上出现语法错误。您没有包含使用 or_phrase 的规则。当我包含一个时,我不会出错。

我认为这不是优先级问题。如果您应该设置日志记录,这样您就可以看到 PLY 正在采取的步骤并将其与您想要发生的事情进行比较,这将有所帮助。为此,将 debug=1 传递给解析函数(您可能还必须将其传递给 yacc)。如果无法进行调试,请查看 PLY 的 yacc.py

reduce/reduce 冲突的发生是因为它不明确是应该将 MISC_TEXT MISC_TEXT 减少到 text_aggregate MISC_TEXT 还是应该减少 MISC_TEXT MISC_TEXTtext_aggregate

在无法重现问题的情况下,我最好的猜测是将 p_misc_text 规则更改为:


'''text_aggregate : MISC_TEXT
| text_aggregate MISC_TEXT'''

我想你也可以删除 precedence 元组。

关于Python:YACC 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2936130/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com