Просмотр исходного кода

Changed minus operator to plus and unary minus.

All unit tests are converted to the new tree representation.
Sander Mathijs van Veen 14 лет назад
Родитель
Сommit
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):
     def on_binary(self, target, option, names, values):
         """
         """
         binary : exp PLUS exp
         binary : exp PLUS exp
-               | exp MINUS exp
                | exp TIMES exp
                | exp TIMES exp
                | exp DIVIDE exp
                | exp DIVIDE exp
                | exp POW 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])
             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".'
         raise BisonSyntaxError('Unsupported option %d in target "%s".'
                                % (option, target))  # pragma: nocover
                                % (option, target))  # pragma: nocover
 
 

+ 22 - 0
tests/parser.py

@@ -98,6 +98,28 @@ def run_expressions(base_class, expressions, fail=True, silent=False,
                 raise
                 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):
 def graph(parser, *exp, **kwargs):
     return generate_graph(ParserWrapper(parser, **kwargs).run(exp))
     return generate_graph(ParserWrapper(parser, **kwargs).run(exp))
 
 

+ 14 - 13
tests/test_b1_ch08.py

@@ -1,22 +1,23 @@
 import unittest
 import unittest
 
 
 from src.parser import Parser
 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):
 class TestB1Ch08(unittest.TestCase):
 
 
-    def test_diagnostic_test(self):
+    def test_diagnostic_test_parser(self):
         run_expressions(Parser, [
         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):
     def test_diagnostic_test(self):
         run_expressions(Parser, [
         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)',
             ('-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',
             ('(2+3/7)^4',
                 N('^', N('+', L(2), N('/', L(3), L(7))), L(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):
     def test_basic_on_exp(self):
         expressions = [('4',   L(4)),
         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))),
                        ('3^4', N('^', L(3), L(4))),
                        ('(2)', L(2))]
                        ('(2)', L(2))]
 
 
@@ -83,7 +83,7 @@ class TestCalc(unittest.TestCase):
 
 
     def test_negation(self):
     def test_negation(self):
         run_expressions(Parser, [
         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))),
             ])
             ])