bison マニュアルの逆ポーランド記法電卓
#!/usr/bin/env python import ply.lex as lex tokens = ( 'NUM', ) literals = ['+', '-', '*', '/', '^', 'n'] 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 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 exp '^' | exp 'n' ''' if len(p) == 3 : p[0] = -p[1] elif p[3] == '+' : p[0] = p[1] + p[2] elif p[3] == '-' : p[0] = p[1] - p[2] elif p[3] == '*' : p[0] = p[1] * p[2] elif p[3] == '/' : p[0] = p[1] / p[2] elif p[3] == '^' : p[0] = p[1] ** p[2] 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 9 + 13.000000 input > 3 7 + 3 4 5 *+- -13.000000 input > 3 7 + 3 4 5 * + - n 13.000000 input > 5 6 / 4 n + -3.166667 input > 3 4 ^ 81.000000 input > 1.2 3.4 + 4.600000 input > 0.2 3.4 + 3.600000 input > 1 3.4 + 4.400000