bison マニュアルの多機能電卓
練習問題2
import re globalvars = { 'PI' : 3.14159265358979, 'E' : 2.71828182845905 } def lookup(name): if not globalvars.has_key(name): print 'Undefined (defaulting to 0):', name return globalvars.get(name, 0) def power(a): if len(a) >= 2: x = a.pop(0) return x ** power(a) else: return a[0] def func(sym_name, arg): import math if sym_name == "sin": return math.sin(arg) elif sym_name == "cos": return math.cos(arg) elif sym_name == "atan": return math.atan(arg) elif sym_name == "ln": return math.log(arg) elif sym_name == "exp": return math.exp(arg) elif sym_name == "sqrt": return math.sqrt(arg) %% parser Test: ignore: "[ \r\t\n]+" token END : "$" token NUM : "\d+(\.\d+)?" token FNCT : "(sin|cos|atan|ln|exp|sqrt)" token AID : "([a-zA-Z_][a-zA-Z0-9_]*)\s*=" token VAR : "[a-zA-Z_][a-zA-Z0-9_]*" rule start : expr END {{ print "\t%f" % expr }} rule expr : AID expr {{ id = re.sub("\s*=$", "", AID); globalvars[id] = expr; return expr }} | term {{ n = term }} ( "[+]" term {{ n += term }} | "-" term {{ n -= term }} )* {{ return n }} rule term : term2 {{ n = term2 }} ( "[*]" term2 {{ n *= term2 }} | "/" term2 {{ n /= term2 }} )* {{ return n }} rule term2 : factor {{ a = [factor] }} ( "\^" factor {{ a.append(factor) }} )* {{ return power(a) }} rule factor: NUM {{ return float(NUM) }} | FNCT "\(" expr "\)" {{ return func(FNCT, expr) }} | VAR {{ return lookup(VAR) }} | "\(" expr "\)" {{ return expr }} | "-" factor {{ return -factor }} %% if __name__=='__main__': while 1: try: s = raw_input('>>> ') except EOFError: break if not s.strip(): break parse('start', s) print 'Bye.'
で、
>>> PI 3.141593 >>> E 2.718282 >>> cos(PI/2) 0.000000