Python 解析隐式与显式时间运算符
我一直在使用ply编写LALR解析器,在尝试解析乘法时遇到了不一致的情况 由于完整的解析器有几千行长,我将不在这里介绍它,但我创建了一个简单的演示:Python 解析隐式与显式时间运算符,python,parsing,ply,lalr,Python,Parsing,Ply,Lalr,我一直在使用ply编写LALR解析器,在尝试解析乘法时遇到了不一致的情况 由于完整的解析器有几千行长,我将不在这里介绍它,但我创建了一个简单的演示: import ply.lex as lex import ply.yacc as yacc tokens = ( 'int', 'times', 'plus', ) precedence = ( ('left', 'plus'), ('left', 'times'), ) t_ignore = ' \t
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规则减少表达式。我怎样才能解决这个问题
编辑:更简单的演示。快速破解:将
int
标记添加到优先级规范中(具有时间优先级)。int
标记随后将被适当地转移到符号堆栈上。即(根据原问题),
这是可行的,但在处理可能大量的代币时会很混乱(开放括号,
符号、浮点数等)
我还是想知道是否有更优雅的解决方案 快速破解:将
int
标记添加到优先级规范(具有时间优先级)。int
标记随后将被适当地转移到符号堆栈上。即(根据原问题),
这是可行的,但在处理可能大量的代币时会很混乱(开放括号,
符号、浮点数等)
我还是想知道是否有更优雅的解决方案 有一个更合适的解决方案:取消运算符优先级,并以通常的方式定义非终端符号
expr
、术语
、和因子。原因是什么?隐含乘法没有作为优先决策基础的特征标记,并且您不希望手动恢复第一组非终结符。此外,随着语法的发展,第一套语法也会随之发展
在BNF中,考虑类似于:
expr -> term | expr + term | expr - term
term -> factor | term * factor | term factor | term / factor
factor -> number | variable | ( expr )
顺便说一句,你可能想做一个额外的非终结层来表示这样一个事实,即通过邻接进行的隐式乘法通常被认为比除法具有更高的优先级,而显式乘法通常被解释为具有相同的优先级
这并不特定于任何特定的解析器生成器框架。有一个更合适的解决方案:放弃运算符优先级,并以通常的方式定义非终端符号expr
、术语和因子。原因是什么?隐含乘法没有作为优先决策基础的特征标记,并且您不希望手动恢复第一组非终结符。此外,随着语法的发展,第一套语法也会随之发展
在BNF中,考虑类似于:
expr -> term | expr + term | expr - term
term -> factor | term * factor | term factor | term / factor
factor -> number | variable | ( expr )
顺便说一句,你可能想做一个额外的非终结层来表示这样一个事实,即通过邻接进行的隐式乘法通常被认为比除法具有更高的优先级,而显式乘法通常被解释为具有相同的优先级
这并不特定于任何特定的解析器生成器框架。您可以将open
添加到优先级关联中吗?我还没有在这种情况下完成语法,但是还有其他的情况需要考虑。例如“1+2 3”=>9对“1+2*3”=>7。@JoranBeasley我已经编辑了这个问题,以使示例更简单。您能将expr添加到您的先例中吗。。。不确定那会不会破坏其他东西是的,那也不行。我认为,因为expr是一个非终端,PLY只允许您为终端指定优先级。编辑:类似的方法也能起作用-将int添加到优先级中,因为这是移位的标记。您能将open
添加到优先级关联中吗?我还没有在这种情况下完成语法,但是还有其他的情况需要考虑。例如“1+2 3”=>9对“1+2*3”=>7。@JoranBeasley我已经编辑了这个问题,以使示例更简单。您能将expr添加到您的先例中吗。。。不确定那会不会破坏其他东西是的,那也不行。我认为,因为expr是一个非终端,PLY只允许您为终端指定优先级。编辑:类似的东西也可以工作-将int添加到优先级,因为这是移位的标记。
expr -> term | expr + term | expr - term
term -> factor | term * factor | term factor | term / factor
factor -> number | variable | ( expr )