Path: blob/main/third_party/ply/example/calc/calc.py
7087 views
# -----------------------------------------------------------------------------1# calc.py2#3# A simple calculator with variables. This is from O'Reilly's4# "Lex and Yacc", p. 63.5# -----------------------------------------------------------------------------67import sys8sys.path.insert(0,"../..")910if sys.version_info[0] >= 3:11raw_input = input1213tokens = (14'NAME','NUMBER',15)1617literals = ['=','+','-','*','/', '(',')']1819# Tokens2021t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'2223def t_NUMBER(t):24r'\d+'25t.value = int(t.value)26return t2728t_ignore = " \t"2930def t_newline(t):31r'\n+'32t.lexer.lineno += t.value.count("\n")3334def t_error(t):35print("Illegal character '%s'" % t.value[0])36t.lexer.skip(1)3738# Build the lexer39import ply.lex as lex40lex.lex()4142# Parsing rules4344precedence = (45('left','+','-'),46('left','*','/'),47('right','UMINUS'),48)4950# dictionary of names51names = { }5253def p_statement_assign(p):54'statement : NAME "=" expression'55names[p[1]] = p[3]5657def p_statement_expr(p):58'statement : expression'59print(p[1])6061def p_expression_binop(p):62'''expression : expression '+' expression63| expression '-' expression64| expression '*' expression65| expression '/' expression'''66if p[2] == '+' : p[0] = p[1] + p[3]67elif p[2] == '-': p[0] = p[1] - p[3]68elif p[2] == '*': p[0] = p[1] * p[3]69elif p[2] == '/': p[0] = p[1] / p[3]7071def p_expression_uminus(p):72"expression : '-' expression %prec UMINUS"73p[0] = -p[2]7475def p_expression_group(p):76"expression : '(' expression ')'"77p[0] = p[2]7879def p_expression_number(p):80"expression : NUMBER"81p[0] = p[1]8283def p_expression_name(p):84"expression : NAME"85try:86p[0] = names[p[1]]87except LookupError:88print("Undefined name '%s'" % p[1])89p[0] = 09091def p_error(p):92if p:93print("Syntax error at '%s'" % p.value)94else:95print("Syntax error at EOF")9697import ply.yacc as yacc98yacc.yacc()99100while 1:101try:102s = raw_input('calc > ')103except EOFError:104break105if not s: continue106yacc.parse(s)107108109