diff --git a/examples/calc.py b/examples/calc.py index 396971d..f29dc59 100644 --- a/examples/calc.py +++ b/examples/calc.py @@ -1,64 +1,39 @@ -import sys, os -sys.path.append('..') +# calc.py - # A simple calculator without using eval +# A shorter and simpler re-implementation of http://www.dabeaz.com/ply/example.html -from pprint import pprint -from operator import itemgetter, add, sub, mul, div, neg - -from plyplus import Grammar -from sexp import Transformer +import operator as op +from plyplus import Grammar, STransformer calc_grammar = Grammar(""" - start: expression; - @expression: bin_op | un_op | parenthesis | number ; - parenthesis: '\(' expression '\)'; - bin_op: expression ('\+'|'-'|'\*'|'/') expression; - un_op: '-' expression; + start: add; + + ?add: (add add_symbol)? mul; + ?mul: (mul mul_symbol)? atom; + @atom: neg | number | '\(' add '\)'; + neg: '-' atom; number: '[\d.]+'; - PLUS: '\+'; - MINUS: '-'; - MUL: '\*'; - DIV: '/'; + mul_symbol: '\*' | '/'; + add_symbol: '\+' | '-'; WS: '[ \t]+' (%ignore); - -### -self.precedence = ( - ('left','PLUS','MINUS'), - ('left','MUL','DIV'), -) """) -class Calc(Transformer): - unary_operator_mapping = { - '-': neg, - } - - bin_operator_mapping = { - '+': add, - '-': sub, - '*': mul, - '/': div, - } +class Calc(STransformer): - start = itemgetter(1) # start only has one member: expression - parenthesis = itemgetter(2) # get the expression between the parenthesis + def _bin_operator(self, exp): + arg1, operator_symbol, arg2 = exp.tail - def number(self, exp): - return float(exp[1]) + operator_func = { '+': op.add, '-': op.sub, '*': op.mul, '/': op.div }[operator_symbol] - def un_op(self, exp): - _, operator_symbol, arg = exp + return operator_func(arg1, arg2) - operator = self.unary_operator_mapping[operator_symbol] - return operator(arg) - - def bin_op(self, exp): - _, arg1, operator_symbol, arg2 = exp - - operator = self.bin_operator_mapping[operator_symbol] - return operator(arg1, arg2) + number = lambda self, exp: float(exp.tail[0]) + neg = lambda self, exp: -exp.tail[0] + __default__ = lambda self, exp: exp.tail[0] + add = _bin_operator + mul = _bin_operator def main(): calc = Calc() @@ -72,14 +47,4 @@ def main(): tree = calc_grammar.parse(s) print calc.transform(tree) -def _test(): - s="4.5-2+3*(-1/-2)" - tree = calc_grammar.parse(s) - pprint(tree) - res = Calc().transform(tree) - print s,"=",res - assert res == 4 - - -#_test() main() diff --git a/examples/calc2.py b/examples/calc2.py deleted file mode 100644 index 396971d..0000000 --- a/examples/calc2.py +++ /dev/null @@ -1,85 +0,0 @@ -import sys, os -sys.path.append('..') - -from pprint import pprint -from operator import itemgetter, add, sub, mul, div, neg - -from plyplus import Grammar -from sexp import Transformer - -calc_grammar = Grammar(""" - start: expression; - @expression: bin_op | un_op | parenthesis | number ; - parenthesis: '\(' expression '\)'; - bin_op: expression ('\+'|'-'|'\*'|'/') expression; - un_op: '-' expression; - - number: '[\d.]+'; - PLUS: '\+'; - MINUS: '-'; - MUL: '\*'; - DIV: '/'; - - WS: '[ \t]+' (%ignore); - -### -self.precedence = ( - ('left','PLUS','MINUS'), - ('left','MUL','DIV'), -) -""") - -class Calc(Transformer): - unary_operator_mapping = { - '-': neg, - } - - bin_operator_mapping = { - '+': add, - '-': sub, - '*': mul, - '/': div, - } - - start = itemgetter(1) # start only has one member: expression - parenthesis = itemgetter(2) # get the expression between the parenthesis - - def number(self, exp): - return float(exp[1]) - - def un_op(self, exp): - _, operator_symbol, arg = exp - - operator = self.unary_operator_mapping[operator_symbol] - return operator(arg) - - def bin_op(self, exp): - _, arg1, operator_symbol, arg2 = exp - - operator = self.bin_operator_mapping[operator_symbol] - return operator(arg1, arg2) - - -def main(): - calc = Calc() - while True: - try: - s = raw_input('> ') - except EOFError: - break - if s == '': - break - tree = calc_grammar.parse(s) - print calc.transform(tree) - -def _test(): - s="4.5-2+3*(-1/-2)" - tree = calc_grammar.parse(s) - pprint(tree) - res = Calc().transform(tree) - print s,"=",res - assert res == 4 - - -#_test() -main() diff --git a/examples/calc3.py b/examples/calc3.py deleted file mode 100644 index 4089b57..0000000 --- a/examples/calc3.py +++ /dev/null @@ -1,63 +0,0 @@ -# calc.py - # A simple calculator without using eval -# A shorter and simpler re-implementation of http://www.dabeaz.com/ply/example.html - -import operator as op - -from plyplus import Grammar, STransformer - -calc_grammar = Grammar(""" - start: add; - - ?add: (add add_symbol)? mul; - ?mul: (mul mul_symbol)? atom; - @atom: neg | number | '\(' add '\)'; - neg: '-' add; - - number: '[\d.]+'; - mul_symbol: '\*' | '/'; - add_symbol: '\+' | '-'; - - WS: '[ \t]+' (%ignore); -""") - -class Calc(STransformer): - - _bin_operator_mapping = { '+': op.add, '-': op.sub, '*': op.mul, '/': op.div } - - def _bin_operator(self, exp): - arg1, operator_symbol, arg2 = exp.tail - - operator = self._bin_operator_mapping[operator_symbol] - return operator(arg1, arg2) - - number = lambda self, exp: float(exp.tail[0]) - neg = lambda self, exp: -exp.tail[0] - __default__ = lambda self, exp: exp.tail[0] - - add = _bin_operator - mul = _bin_operator - -def main(): - calc = Calc() - while True: - try: - s = raw_input('> ') - except EOFError: - break - if s == '': - break - tree = calc_grammar.parse(s) - print calc.transform(tree) - -def _test(): - from pprint import pprint - s = "2*4.5/2-2+3*(-1/-2)" - tree = calc_grammar.parse(s) - pprint(tree) - res = Calc().transform(tree) - print s, "=" , res - assert res == 4, res - - -#_test() -main()