16498Snate@binkert.org# -----------------------------------------------------------------------------
26498Snate@binkert.org# yacc_prec1.py
36498Snate@binkert.org#
46498Snate@binkert.org# Tests case where precedence specifier doesn't match up to terminals
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.orgprecedence = (
156498Snate@binkert.org    ('left','+','-'),
166498Snate@binkert.org    ('left','*','/'),
176498Snate@binkert.org    ('right','UMINUS'),
186498Snate@binkert.org    )
196498Snate@binkert.org
206498Snate@binkert.org# dictionary of names
216498Snate@binkert.orgnames = { }
226498Snate@binkert.org
236498Snate@binkert.orgdef p_statement_assign(t):
246498Snate@binkert.org    'statement : NAME EQUALS expression'
256498Snate@binkert.org    names[t[1]] = t[3]
266498Snate@binkert.org
276498Snate@binkert.orgdef p_statement_expr(t):
286498Snate@binkert.org    'statement : expression'
296498Snate@binkert.org    print(t[1])
306498Snate@binkert.org
316498Snate@binkert.orgdef p_expression_binop(t):
326498Snate@binkert.org    '''expression : expression PLUS expression
336498Snate@binkert.org                  | expression MINUS expression
346498Snate@binkert.org                  | expression TIMES expression
356498Snate@binkert.org                  | expression DIVIDE expression'''
366498Snate@binkert.org    if t[2] == '+'  : t[0] = t[1] + t[3]
376498Snate@binkert.org    elif t[2] == '-': t[0] = t[1] - t[3]
386498Snate@binkert.org    elif t[2] == '*': t[0] = t[1] * t[3]
396498Snate@binkert.org    elif t[2] == '/': t[0] = t[1] / t[3]
406498Snate@binkert.org
416498Snate@binkert.orgdef p_expression_uminus(t):
426498Snate@binkert.org    'expression : MINUS expression %prec UMINUS'
436498Snate@binkert.org    t[0] = -t[2]
446498Snate@binkert.org
456498Snate@binkert.orgdef p_expression_group(t):
466498Snate@binkert.org    'expression : LPAREN expression RPAREN'
476498Snate@binkert.org    t[0] = t[2]
486498Snate@binkert.org
496498Snate@binkert.orgdef p_expression_number(t):
506498Snate@binkert.org    'expression : NUMBER'
516498Snate@binkert.org    t[0] = t[1]
526498Snate@binkert.org
536498Snate@binkert.orgdef p_expression_name(t):
546498Snate@binkert.org    'expression : NAME'
556498Snate@binkert.org    try:
566498Snate@binkert.org        t[0] = names[t[1]]
576498Snate@binkert.org    except LookupError:
586498Snate@binkert.org        print("Undefined name '%s'" % t[1])
596498Snate@binkert.org        t[0] = 0
606498Snate@binkert.org
616498Snate@binkert.orgdef p_error(t):
626498Snate@binkert.org    print("Syntax error at '%s'" % t.value)
636498Snate@binkert.org
646498Snate@binkert.orgyacc.yacc()
656498Snate@binkert.org
666498Snate@binkert.org
676498Snate@binkert.org
686498Snate@binkert.org
69