16498Snate@binkert.org# ----------------------------------------------------------------------------- 26498Snate@binkert.org# calc.py 36498Snate@binkert.org# 46498Snate@binkert.org# This example shows how to run the parser in a debugging mode 56498Snate@binkert.org# with output routed to a logging object. 66498Snate@binkert.org# ----------------------------------------------------------------------------- 76498Snate@binkert.org 86498Snate@binkert.orgimport sys 96498Snate@binkert.orgsys.path.insert(0,"../..") 106498Snate@binkert.org 116498Snate@binkert.orgif sys.version_info[0] >= 3: 126498Snate@binkert.org raw_input = input 136498Snate@binkert.org 146498Snate@binkert.orgtokens = ( 156498Snate@binkert.org 'NAME','NUMBER', 166498Snate@binkert.org ) 176498Snate@binkert.org 186498Snate@binkert.orgliterals = ['=','+','-','*','/', '(',')'] 196498Snate@binkert.org 206498Snate@binkert.org# Tokens 216498Snate@binkert.org 226498Snate@binkert.orgt_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*' 236498Snate@binkert.org 246498Snate@binkert.orgdef t_NUMBER(t): 256498Snate@binkert.org r'\d+' 266498Snate@binkert.org t.value = int(t.value) 276498Snate@binkert.org return t 286498Snate@binkert.org 296498Snate@binkert.orgt_ignore = " \t" 306498Snate@binkert.org 316498Snate@binkert.orgdef t_newline(t): 326498Snate@binkert.org r'\n+' 336498Snate@binkert.org t.lexer.lineno += t.value.count("\n") 346498Snate@binkert.org 356498Snate@binkert.orgdef t_error(t): 366498Snate@binkert.org print("Illegal character '%s'" % t.value[0]) 376498Snate@binkert.org t.lexer.skip(1) 386498Snate@binkert.org 396498Snate@binkert.org# Build the lexer 406498Snate@binkert.orgimport ply.lex as lex 416498Snate@binkert.orglex.lex() 426498Snate@binkert.org 436498Snate@binkert.org# Parsing rules 446498Snate@binkert.org 456498Snate@binkert.orgprecedence = ( 466498Snate@binkert.org ('left','+','-'), 476498Snate@binkert.org ('left','*','/'), 486498Snate@binkert.org ('right','UMINUS'), 496498Snate@binkert.org ) 506498Snate@binkert.org 516498Snate@binkert.org# dictionary of names 526498Snate@binkert.orgnames = { } 536498Snate@binkert.org 546498Snate@binkert.orgdef p_statement_assign(p): 556498Snate@binkert.org 'statement : NAME "=" expression' 566498Snate@binkert.org names[p[1]] = p[3] 576498Snate@binkert.org 586498Snate@binkert.orgdef p_statement_expr(p): 596498Snate@binkert.org 'statement : expression' 606498Snate@binkert.org print(p[1]) 616498Snate@binkert.org 626498Snate@binkert.orgdef p_expression_binop(p): 636498Snate@binkert.org '''expression : expression '+' expression 646498Snate@binkert.org | expression '-' expression 656498Snate@binkert.org | expression '*' expression 666498Snate@binkert.org | expression '/' expression''' 676498Snate@binkert.org if p[2] == '+' : p[0] = p[1] + p[3] 686498Snate@binkert.org elif p[2] == '-': p[0] = p[1] - p[3] 696498Snate@binkert.org elif p[2] == '*': p[0] = p[1] * p[3] 706498Snate@binkert.org elif p[2] == '/': p[0] = p[1] / p[3] 716498Snate@binkert.org 726498Snate@binkert.orgdef p_expression_uminus(p): 736498Snate@binkert.org "expression : '-' expression %prec UMINUS" 746498Snate@binkert.org p[0] = -p[2] 756498Snate@binkert.org 766498Snate@binkert.orgdef p_expression_group(p): 776498Snate@binkert.org "expression : '(' expression ')'" 786498Snate@binkert.org p[0] = p[2] 796498Snate@binkert.org 806498Snate@binkert.orgdef p_expression_number(p): 816498Snate@binkert.org "expression : NUMBER" 826498Snate@binkert.org p[0] = p[1] 836498Snate@binkert.org 846498Snate@binkert.orgdef p_expression_name(p): 856498Snate@binkert.org "expression : NAME" 866498Snate@binkert.org try: 876498Snate@binkert.org p[0] = names[p[1]] 886498Snate@binkert.org except LookupError: 896498Snate@binkert.org print("Undefined name '%s'" % p[1]) 906498Snate@binkert.org p[0] = 0 916498Snate@binkert.org 926498Snate@binkert.orgdef p_error(p): 936498Snate@binkert.org if p: 946498Snate@binkert.org print("Syntax error at '%s'" % p.value) 956498Snate@binkert.org else: 966498Snate@binkert.org print("Syntax error at EOF") 976498Snate@binkert.org 986498Snate@binkert.orgimport ply.yacc as yacc 996498Snate@binkert.orgyacc.yacc() 1006498Snate@binkert.org 1016498Snate@binkert.orgimport logging 1026498Snate@binkert.orglogging.basicConfig( 1036498Snate@binkert.org level=logging.INFO, 1046498Snate@binkert.org filename="parselog.txt" 1056498Snate@binkert.org) 1066498Snate@binkert.org 1076498Snate@binkert.orgwhile 1: 1086498Snate@binkert.org try: 1096498Snate@binkert.org s = raw_input('calc > ') 1106498Snate@binkert.org except EOFError: 1116498Snate@binkert.org break 1126498Snate@binkert.org if not s: continue 1136498Snate@binkert.org yacc.parse(s,debug=logging.getLogger()) 114