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