我一直在使用 ply 编写一个 LALR 解析器,并且在尝试解析乘法时遇到了不一致。
由于完整的解析器链接长达数千行,我不会在此处包含它,但我创建了一个简单的演示:
import ply.lex as lex
import ply.yacc as yacc
tokens = (
'int',
'times',
'plus',
)
precedence = (
('left', 'plus'),
('left', 'times'),
)
t_ignore = ' \t\n '
t_int = r' \d+ '
t_plus = r' \+ '
t_times = ' \* '
def p_int(args):
'expr : int'
args[0] = int(args[1])
def p_times(args):
'''expr : expr times expr
| expr expr %prec times'''
if len(args) == 3:
args[0] = args[1] * args[2]
elif len(args) == 4:
args[0] = args[1] * args[3]
def p_plus(args):
'expr : expr plus expr'
args[0] = args[1] + args[3]
lex.lex()
parser = yacc.yacc()
while True:
s = raw_input('>> ')
print " = ", parser.parse(s)
PLY 没有报告移位/减少冲突或减少/减少冲突,但我得到以下不一致:
>> 1 + 2 3
= 9
>> 1 + 2 * 3
= 7
这对我来说似乎很奇怪,因为显式和隐式时间规则具有相同的优先级。但我认为这可能是因为 PLY 为“times”令牌分配了优先级,因此将其转移到堆栈上,以支持使用 p_plus 规则减少表达式。我怎样才能解决这个问题?
编辑:更简单的演示。