Я писал синтаксический анализатор LALR с использованием ply и столкнулся с несоответствием при попытке проанализировать умножение.
Поскольку полный анализатор link состоит из нескольких тысяч строк, я не буду включать его сюда, но я создал простую демонстрацию:
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. Как я могу это исправить?
Изменить: более простая демонстрация.
open
к своей приоритетной ассоциации? Я давно не занимался грамматикой - person Joran Beasley   schedule 10.04.2013