bison マニュアルの中間記法電卓
#!/usr/bin/env python import ply.lex as lex tokens = ( 'NUM', ) literals = ['+', '-', '*', '/', '^', '(', ')'] def t_NUM(t): r'\d+(\.\d+)*' try: t.value = float(t.value) except ValueError: print "Integer value too large", t.value t.value = 0 return t t_ignore = " \t" def t_error(t): print "Illegal character '%s'" % t.value[0] t.lexer.skip(1) lex.lex() import ply.yacc as yacc precedence = ( ('left', '+', '-'), ('left', '*', '/'), ('left', 'NEG'), ('right', '^'), ) def p_input(p): "input : exp" print "\t%f" % p[1] def p_input_error(p): "input : exp error" def p_exp_num(p): "exp : NUM" p[0] = p[1] def p_exp(p): '''exp : exp '+' exp | exp '-' exp | exp '*' exp | exp '/' exp | '-' exp %prec NEG | exp '^' exp | '(' exp ')' ''' if p[1] == '(' : p[0] = p[2] elif p[1] == '-' : p[0] = -p[2] elif p[2] == '+' : p[0] = p[1] + p[3] elif p[2] == '-' : p[0] = p[1] - p[3] elif p[2] == '*' : p[0] = p[1] * p[3] elif p[2] == '/' : p[0] = p[1] / p[3] elif p[2] == '^' : p[0] = p[1] ** p[3] def p_error(p): print "Syntax error at '%s'" % p.value yacc.yacc() while 1: try: s = raw_input('input > ') except EOFError: break if not s: continue yacc.parse(s)
で、
input > 4+4.5-(34.0/(8*3+-3)) 6.880952 input > -56+2 -54.000000 input > 3^2 9.000000 input > -3^2 -9.000000