16498Snate@binkert.org# -----------------------------------------------------------------------------
26498Snate@binkert.org# yacc_uprec2.py
36498Snate@binkert.org#
46498Snate@binkert.org# A grammar with a bad %prec specifier
56498Snate@binkert.org# -----------------------------------------------------------------------------
66498Snate@binkert.orgimport sys
76498Snate@binkert.org
86498Snate@binkert.orgif ".." not in sys.path: sys.path.insert(0,"..")
96498Snate@binkert.orgimport ply.yacc as yacc
106498Snate@binkert.org
116498Snate@binkert.orgfrom calclex import tokens
126498Snate@binkert.org
136498Snate@binkert.org# Parsing rules
146498Snate@binkert.org
156498Snate@binkert.org# dictionary of names
166498Snate@binkert.orgnames = { }
176498Snate@binkert.org
186498Snate@binkert.orgdef p_statement_assign(t):
196498Snate@binkert.org    'statement : NAME EQUALS expression'
206498Snate@binkert.org    names[t[1]] = t[3]
216498Snate@binkert.org
226498Snate@binkert.orgdef p_statement_expr(t):
236498Snate@binkert.org    'statement : expression'
246498Snate@binkert.org    print(t[1])
256498Snate@binkert.org
266498Snate@binkert.orgdef p_expression_binop(t):
276498Snate@binkert.org    '''expression : expression PLUS expression
286498Snate@binkert.org                  | expression MINUS expression
296498Snate@binkert.org                  | expression TIMES expression
306498Snate@binkert.org                  | expression DIVIDE expression'''
316498Snate@binkert.org    if t[2] == '+'  : t[0] = t[1] + t[3]
326498Snate@binkert.org    elif t[2] == '-': t[0] = t[1] - t[3]
336498Snate@binkert.org    elif t[2] == '*': t[0] = t[1] * t[3]
346498Snate@binkert.org    elif t[2] == '/': t[0] = t[1] / t[3]
356498Snate@binkert.org
366498Snate@binkert.orgdef p_expression_uminus(t):
376498Snate@binkert.org    'expression : MINUS expression %prec'
386498Snate@binkert.org    t[0] = -t[2]
396498Snate@binkert.org
406498Snate@binkert.orgdef p_expression_group(t):
416498Snate@binkert.org    'expression : LPAREN expression RPAREN'
426498Snate@binkert.org    t[0] = t[2]
436498Snate@binkert.org
446498Snate@binkert.orgdef p_expression_number(t):
456498Snate@binkert.org    'expression : NUMBER'
466498Snate@binkert.org    t[0] = t[1]
476498Snate@binkert.org
486498Snate@binkert.orgdef p_expression_name(t):
496498Snate@binkert.org    'expression : NAME'
506498Snate@binkert.org    try:
516498Snate@binkert.org        t[0] = names[t[1]]
526498Snate@binkert.org    except LookupError:
536498Snate@binkert.org        print("Undefined name '%s'" % t[1])
546498Snate@binkert.org        t[0] = 0
556498Snate@binkert.org
566498Snate@binkert.orgdef p_error(t):
576498Snate@binkert.org    print("Syntax error at '%s'" % t.value)
586498Snate@binkert.org
596498Snate@binkert.orgyacc.yacc()
606498Snate@binkert.org
616498Snate@binkert.org
626498Snate@binkert.org
636498Snate@binkert.org
64