I've been writing a LALR parser using ply and have come across an inconsistency when trying to parse multiplication.
As the full parser link is several thousand lines long I won't include it here, but I've created a simple demonstration:
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)
There are no shift/reduce conflicts or reduce/reduce conflicts reported by PLY yet I get the following inconsistency:
>> 1 + 2 3
= 9
>> 1 + 2 * 3
= 7
This seems odd to me since the explicit and implicit times rules have the same precedence. But I think it could be due to the fact that PLY assigns a precedence to the 'times' token and thus shifts it onto the stack in favour of reducing the expression with the p_plus rule. How can I fix this?
Edit: Simpler demonstration.
opento your precedence association? I havent done grammars in a while - Joran Beasley