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