Преглед изворни кода

Changed minus operator to plus and unary minus.

All unit tests are converted to the new tree representation.
Sander Mathijs van Veen пре 14 година
родитељ
комит
d9bedbd892
5 измењених фајлова са 53 додато и 36 уклоњено
  1. 5 2
      src/parser.py
  2. 22 0
      tests/parser.py
  3. 14 13
      tests/test_b1_ch08.py
  4. 5 14
      tests/test_b1_ch10.py
  5. 7 7
      tests/test_calc.py

+ 5 - 2
src/parser.py

@@ -274,15 +274,18 @@ class Parser(BisonParser):
     def on_binary(self, target, option, names, values):
         """
         binary : exp PLUS exp
-               | exp MINUS exp
                | exp TIMES exp
                | exp DIVIDE exp
                | exp POW exp
+               | exp MINUS exp
         """
 
-        if 0 <= option < 5:  # rule: exp PLUS exp
+        if 0 <= option < 4:  # rule: exp {PLUS,TIMES,DIVIDES,POW} exp
             return Node(values[1], values[0], values[2])
 
+        if option == 4:  # rule: exp MINUS exp
+            return Node('+', values[0], Node('-', values[2]))
+
         raise BisonSyntaxError('Unsupported option %d in target "%s".'
                                % (option, target))  # pragma: nocover
 

+ 22 - 0
tests/parser.py

@@ -98,6 +98,28 @@ def run_expressions(base_class, expressions, fail=True, silent=False,
                 raise
 
 
+def apply_expressions(base_class, expressions, fail=True, silent=False,
+        **kwargs):
+    parser = ParserWrapper(base_class, **kwargs)
+
+    for exp, times, out in expressions:
+        res = None
+        try:
+            res = parser.run([exp] + list('@' * times))
+            assert res == out
+        except:  # pragma: nocover
+            if not silent:
+                print >>sys.stderr, 'error: %s gives %s, but expected: %s' \
+                                    % (exp, str(res), str(out))
+
+            if not silent and hasattr(res, 'nodes'):
+                print >>sys.stderr, 'result graph:'
+                print >>sys.stderr, generate_graph(res)
+                print >>sys.stderr, 'expected graph:'
+                print >>sys.stderr, generate_graph(out)
+
+            if fail:
+                raise
 def graph(parser, *exp, **kwargs):
     return generate_graph(ParserWrapper(parser, **kwargs).run(exp))
 

+ 14 - 13
tests/test_b1_ch08.py

@@ -1,22 +1,23 @@
 import unittest
 
 from src.parser import Parser
-from src.node import ExpressionNode as N, ExpressionLeaf as L
-from tests.parser import run_expressions
+from src.node import ExpressionLeaf as L
+from tests.parser import run_expressions, apply_expressions
 
 
 class TestB1Ch08(unittest.TestCase):
 
-    def test_diagnostic_test(self):
+    def test_diagnostic_test_parser(self):
         run_expressions(Parser, [
-            ('6*5^2', N('*', L(6), N('^', L(5), L(2)))),
-            ('-5*(-3)^2', N('*', N('-', L(5)),
-                                 N('^', N('-', L(3)), L(2)))),
-            ('-5*(-3)^2', N('*', N('-', L(5)),
-                                 N('^', N('-', L(3)), L(2)))),
-            ('7p-3p', N('-', N('*', L(7), L('p')), N('*', L(3), L('p')))),
-            ('-5a*-6', N('*', N('*', N('-', L(5)), L('a')),
-                              N('-', L(6)))),
-            ('3a-8--5-2a', N('-', N('-', N('-', N('*', L(3), L('a')), L(8)),
-                                  N('-', L(5))), N('*', L(2), L('a')))),
+            ('6*5^2', L(6) * L(5) ** 2),
+            ('-5*(-3)^2', (-L(5)) * (-L(3)) ** 2),
+            ('7p-3p', L(7) * 'p' + -(L(3) * 'p')),
+            ('-5a*-6', (-L(5)) * 'a' * (-L(6))),
+            ('3a-8--5-2a', L(3) * 'a' + -L(8) + -(-L(5)) + -(L(2) * 'a')),
+            ])
+
+    def test_diagnostic_test_application(self):
+        apply_expressions(Parser, [
+            ('7p+2p', 1, (L(7) + 2) * 'p'),
+            #('7p-3p', 1, (L(7) - 3) * 'p'),
             ])

+ 5 - 14
tests/test_b1_ch10.py

@@ -9,21 +9,12 @@ class TestB1Ch10(unittest.TestCase):
 
     def test_diagnostic_test(self):
         run_expressions(Parser, [
-            ('5(a-2b)', N('*', L(5), N('-', L('a'),
-                                       N('*', L(2), L('b'))))),
-            ('-(3a+6b)', N('-', N('+', N('*', L(3), L('a')),
-                                  N('*', L(6), L('b'))))),
-            ('18-(a-12)', N('-', L(18),
-                            N('-', L('a'), L(12)))),
+            ('5(a-2b)', L(5) * (L('a') + -(L(2) * 'b'))),
+            ('-(3a+6b)', -(L(3) * L('a') + L(6) * 'b')),
+            ('18-(a-12)', L(18) + -(L('a') + -L(12))),
             ('-p-q+5(p-q)-3q-2(p-q)',
-                N('-',
-                  N('-',
-                    N('+', N('-', N('-', L('p')), L('q')),
-                      N('*', L(5), N('-', L('p'), L('q')))),
-                    N('*', L(3), L('q'))
-                  ),
-                  N('*', L(2), N('-', L('p'), L('q')))
-                )
+                -L('p') + -L('q') + L(5) * (L('p') + -L('q')) + -(L(3) * 'q') \
+                + - (L(2) * (L('p') + -L('q')))
             ),
             ('(2+3/7)^4',
                 N('^', N('+', L(2), N('/', L(3), L(7))), L(4))

+ 7 - 7
tests/test_calc.py

@@ -13,10 +13,10 @@ class TestCalc(unittest.TestCase):
 
     def test_basic_on_exp(self):
         expressions = [('4',   L(4)),
-                       ('3+4', N('+', L(3), L(4))),
-                       ('3-4', N('-', L(3), L(4))),
-                       ('3/4', N('/', L(3), L(4))),
-                       ('-4',  N('-', L(4))),
+                       ('3+4', L(3) + L(4)),
+                       ('3-4', L(3) + -L(4)),
+                       ('3/4', L(3) / L(4)),
+                       ('-4',  -L(4)),
                        ('3^4', N('^', L(3), L(4))),
                        ('(2)', L(2))]
 
@@ -83,7 +83,7 @@ class TestCalc(unittest.TestCase):
 
     def test_negation(self):
         run_expressions(Parser, [
-            ('-9', N('-', L(9))),
-            ('--9', N('-', N('-', L(9)))),
-            ('a--9', N('-', L('a'), N('-', L(9)))),
+            ('-9', -L(9)),
+            ('--9', --L(9)),
+            ('a--9', L('a') + -(-L(9))),
             ])