Răsfoiți Sursa

Merge branch 'master' of kompiler.org:trs

Taddeus Kroes 14 ani în urmă
părinte
comite
6556ca495a

+ 2 - 1
src/parser.py

@@ -17,7 +17,8 @@ from graph_drawing.graph import generate_graph
 from node import ExpressionNode as Node, ExpressionLeaf as Leaf, OP_MAP, \
         TOKEN_MAP, TYPE_OPERATOR, OP_COMMA, OP_NEG, OP_MUL, Scope, PI
 from rules import RULES
-from possibilities import filter_duplicates, pick_suggestion, apply_suggestion
+from strategy import pick_suggestion
+from possibilities import filter_duplicates, apply_suggestion
 
 import Queue
 

+ 0 - 9
src/possibilities.py

@@ -54,15 +54,6 @@ def filter_duplicates(possibilities):
     return unique
 
 
-def pick_suggestion(possibilities):
-    if not possibilities:
-        return
-
-    # TODO: pick the best suggestion.
-    suggestion = 0
-    return possibilities[suggestion]
-
-
 def find_parent_node(root, child):
     nodes = [root]
 

+ 19 - 1
src/rules/numerics.py

@@ -15,12 +15,20 @@ def match_add_numerics(node):
     2 + -3   ->  -1
     -2 + 3   ->  1
     -2 + -3  ->  -5
+    0 + 3    ->  3
+    0 + -3   ->  -3
     """
     assert node.is_op(OP_ADD)
 
     p = []
     scope = Scope(node)
-    numerics = filter(lambda n: n.is_numeric(), scope)
+    numerics = []
+
+    for n in scope:
+        if n == 0:
+            p.append(P(node, remove_zero, (scope, n)))
+        elif n.is_numeric():
+            numerics.append(n)
 
     for c0, c1 in combinations(numerics, 2):
         p.append(P(node, add_numerics, (scope, c0, c1)))
@@ -28,6 +36,16 @@ def match_add_numerics(node):
     return p
 
 
+def remove_zero(root, args):
+    """
+    0 + a  ->  a
+    """
+    scope, n = args
+    scope.remove(n)
+
+    return scope.as_nary_node()
+
+
 def add_numerics(root, args):
     """
     2 + 3    ->  5

+ 18 - 0
src/strategy.py

@@ -0,0 +1,18 @@
+from rules.sort import move_constant
+
+
+def pick_suggestion(possibilities):
+    if not possibilities:
+        return
+
+    # TODO: pick the best suggestion.
+    for suggestion, p in enumerate(possibilities + [None]):
+        if p and p.handler not in [move_constant]:
+            break
+
+    if not p:
+        return possibilities[0]
+
+    return possibilities[suggestion]
+
+

+ 43 - 49
tests/test_leiden_oefenopgave.py

@@ -25,39 +25,36 @@ class TestLeidenOefenopgave(TestCase):
             self.assertEqual(str(rewrite(exp)), solution)
 
     def test_1_2(self):
-        for chain in [['(x+1)^3', '(x + 1)(x + 1) ^ 2',
-                '(x + 1)(x + 1)(x + 1)',
-                '(xx + x * 1 + 1x + 1 * 1)(x + 1)',
-                '(x ^ (1 + 1) + x * 1 + 1x + 1 * 1)(x + 1)',
-                '(x ^ 2 + x * 1 + 1x + 1 * 1)(x + 1)',
-                '(x ^ 2 + x + 1x + 1 * 1)(x + 1)',
-                '(x ^ 2 + x + x + 1 * 1)(x + 1)',
-                '(x ^ 2 + (1 + 1)x + 1 * 1)(x + 1)',
-                '(x ^ 2 + 2x + 1 * 1)(x + 1)',
-                '(x ^ 2 + 2x + 1)(x + 1)',
-                '(x ^ 2 + 2x)x + (x ^ 2 + 2x) * 1 + 1x + 1 * 1',
-                'xx ^ 2 + x * 2x + (x ^ 2 + 2x) * 1 + 1x + 1 * 1',
-                'x ^ (1 + 2) + x * 2x + (x ^ 2 + 2x) * 1 + 1x + 1 * 1',
-                'x ^ 3 + x * 2x + (x ^ 2 + 2x) * 1 + 1x + 1 * 1',
-                'x ^ 3 + 2xx + (x ^ 2 + 2x) * 1 + 1x + 1 * 1',
-                'x ^ 3 + 2x ^ (1 + 1) + (x ^ 2 + 2x) * 1 + 1x + 1 * 1',
-                'x ^ 3 + 2x ^ 2 + (x ^ 2 + 2x) * 1 + 1x + 1 * 1',
-                'x ^ 3 + 2x ^ 2 + 1x ^ 2 + 1 * 2x + 1x + 1 * 1',
-                'x ^ 3 + 2x ^ 2 + x ^ 2 + 1 * 2x + 1x + 1 * 1',
-                'x ^ 3 + (2 + 1)x ^ 2 + 1 * 2x + 1x + 1 * 1',
-                'x ^ 3 + 3x ^ 2 + 1 * 2x + 1x + 1 * 1',
-                'x ^ 3 + 3x ^ 2 + 2x + 1x + 1 * 1',
-                'x ^ 3 + 3x ^ 2 + 2x + x + 1 * 1',
-                'x ^ 3 + 3x ^ 2 + (2 + 1)x + 1 * 1',
-                'x ^ 3 + 3x ^ 2 + 3x + 1 * 1',
-                'x ^ 3 + 3x ^ 2 + 3x + 1',
-                ]
-            ]:
-            self.assertRewrite(chain)
+        self.assertRewrite(['(x+1)^3', '(x + 1)(x + 1) ^ 2',
+                            '(x + 1)(x + 1)(x + 1)',
+                            '(xx + x * 1 + 1x + 1 * 1)(x + 1)',
+                            '(x ^ (1 + 1) + x * 1 + 1x + 1 * 1)(x + 1)',
+                            '(x ^ 2 + x * 1 + 1x + 1 * 1)(x + 1)',
+                            '(x ^ 2 + x + 1x + 1 * 1)(x + 1)',
+                            '(x ^ 2 + x + x + 1 * 1)(x + 1)',
+                            '(x ^ 2 + (1 + 1)x + 1 * 1)(x + 1)',
+                            '(x ^ 2 + 2x + 1 * 1)(x + 1)',
+                            '(x ^ 2 + 2x + 1)(x + 1)',
+                            '(x ^ 2 + 2x)x + (x ^ 2 + 2x) * 1 + 1x + 1 * 1',
+                            'xx ^ 2 + x * 2x + (x ^ 2 + 2x) * 1 + 1x + 1 * 1',
+                            'x ^ (1 + 2) + x * 2x + (x ^ 2 + 2x) * 1 + 1x + 1 * 1',
+                            'x ^ 3 + x * 2x + (x ^ 2 + 2x) * 1 + 1x + 1 * 1',
+                            'x ^ 3 + x ^ (1 + 1) * 2 + (x ^ 2 + 2x) * 1 + 1x + 1 * 1',
+                            'x ^ 3 + x ^ 2 * 2 + (x ^ 2 + 2x) * 1 + 1x + 1 * 1',
+                            'x ^ 3 + x ^ 2 * 2 + 1x ^ 2 + 1 * 2x + 1x + 1 * 1',
+                            'x ^ 3 + x ^ 2 * 2 + x ^ 2 + 1 * 2x + 1x + 1 * 1',
+                            'x ^ 3 + (2 + 1)x ^ 2 + 1 * 2x + 1x + 1 * 1',
+                            'x ^ 3 + 3x ^ 2 + 1 * 2x + 1x + 1 * 1',
+                            'x ^ 3 + 3x ^ 2 + 2x + 1x + 1 * 1',
+                            'x ^ 3 + 3x ^ 2 + 2x + x + 1 * 1',
+                            'x ^ 3 + 3x ^ 2 + (2 + 1)x + 1 * 1',
+                            'x ^ 3 + 3x ^ 2 + 3x + 1 * 1',
+                            'x ^ 3 + 3x ^ 2 + 3x + 1',
+                            ])
 
     def test_1_3(self):
         # (x+1)^2 -> x^2 + 2x + 1
-        for chain in [['(x+1)^2', '(x + 1)(x + 1)',
+        self.assertRewrite(['(x+1)^2', '(x + 1)(x + 1)',
                        'xx + x * 1 + 1x + 1 * 1',
                        'x ^ (1 + 1) + x * 1 + 1x + 1 * 1',
                        'x ^ 2 + x * 1 + 1x + 1 * 1',
@@ -65,26 +62,24 @@ class TestLeidenOefenopgave(TestCase):
                        'x ^ 2 + x + x + 1 * 1',
                        'x ^ 2 + (1 + 1)x + 1 * 1',
                        'x ^ 2 + 2x + 1 * 1',
-                       'x ^ 2 + 2x + 1'],
-                     ]:
-            self.assertRewrite(chain)
+                       'x ^ 2 + 2x + 1',
+                       ])
 
     def test_1_4(self):
         # (x-1)^2 -> x^2 - 2x + 1
-        for chain in [['(x-1)^2', '(x - 1)(x - 1)',
-                       'xx + x * -1 - 1x - 1 * -1',
-                       'x ^ (1 + 1) + x * -1 - 1x - 1 * -1',
-                       'x ^ 2 + x * -1 - 1x - 1 * -1',
-                       'x ^ 2 - x * 1 - 1x - 1 * -1',
-                       'x ^ 2 - x - 1x - 1 * -1',
-                       'x ^ 2 - x - x - 1 * -1',
-                       'x ^ 2 + (1 + 1) * -x - 1 * -1',
-                       'x ^ 2 + 2 * -x - 1 * -1',
-                       'x ^ 2 - 2x - 1 * -1',
-                       'x ^ 2 - 2x - -1',
-                       'x ^ 2 - 2x + 1',
-                     ]]:
-            self.assertRewrite(chain)
+        self.assertRewrite(['(x-1)^2', '(x - 1)(x - 1)',
+                            'xx + x * -1 - 1x - 1 * -1',
+                            'x ^ (1 + 1) + x * -1 - 1x - 1 * -1',
+                            'x ^ 2 + x * -1 - 1x - 1 * -1',
+                            'x ^ 2 - x * 1 - 1x - 1 * -1',
+                            'x ^ 2 - x - 1x - 1 * -1',
+                            'x ^ 2 - x - x - 1 * -1',
+                            'x ^ 2 + (1 + 1) * -x - 1 * -1',
+                            'x ^ 2 + 2 * -x - 1 * -1',
+                            'x ^ 2 - 2x - 1 * -1',
+                            'x ^ 2 - 2x - -1',
+                            'x ^ 2 - 2x + 1',
+                            ])
 
     def test_1_4_1(self):
         self.assertRewrite(['x * -1 + 1x',
@@ -132,8 +127,7 @@ class TestLeidenOefenopgave(TestCase):
                             '(-20 + 20)x + 16x ^ 2 - 25',
                             '0x + 16x ^ 2 - 25',
                             '0 + 16x ^ 2 - 25',
-                            '-25 + 16x ^ 2'])
-                            # FIXME: '16x ^ 2 - 25'])
+                            '16x ^ 2 - 25'])
 
     def test_2(self):
         pass

+ 25 - 9
tests/test_leiden_oefenopgave_v12.py

@@ -1,7 +1,22 @@
-from tests.rulestestcase import RulesTestCase as TestCase, rewrite
+from tests.rulestestcase import RulesTestCase as TestCase
 
 
 class TestLeidenOefenopgaveV12(TestCase):
+    def test_1_a(self):
+        self.assertRewrite(['-5(x2 - 3x + 6)',
+                            '-5(x ^ 2 - 3x) - 5 * 6',
+                            '-5x ^ 2 - 5 * -3x - 5 * 6',
+                            '-5x ^ 2 - -15x - 5 * 6',
+                            '-5x ^ 2 + 15x - 5 * 6',
+                            '-5x ^ 2 + 15x - 30'])
+
+    def test_1_d(self):
+        self.assertRewrite(['(2x + x)x',
+                            '(2 + 1)xx',
+                            '3xx',
+                            '3x ^ (1 + 1)',
+                            '3x ^ 2'])
+
     def test_1_e(self):
         self.assertRewrite([
             '-2(6x - 4) ^ 2x',
@@ -24,13 +39,14 @@ class TestLeidenOefenopgaveV12(TestCase):
             'x(-72x ^ 2 + 96x) + x * -32',
             'x * -72x ^ 2 + x * 96x + x * -32',
             '-x * 72x ^ 2 + x * 96x + x * -32',
-            '72 * -xx ^ 2 + x * 96x + x * -32',
-            '-72xx ^ 2 + x * 96x + x * -32',
-            '-72x ^ (1 + 2) + x * 96x + x * -32',
-            '-72x ^ 3 + x * 96x + x * -32',
-            '-72x ^ 3 + 96xx + x * -32',
-            '-72x ^ 3 + 96x ^ (1 + 1) + x * -32',
-            '-72x ^ 3 + 96x ^ 2 + x * -32',
+            '-x ^ (1 + 2) * 72 + x * 96x + x * -32',
+            '-x ^ 3 * 72 + x * 96x + x * -32',
+            '-x ^ 3 * 72 + x ^ (1 + 1) * 96 + x * -32',
+            '-x ^ 3 * 72 + x ^ 2 * 96 + x * -32',
+            '-x ^ 3 * 72 + x ^ 2 * 96 - x * 32',
+            '72 * -x ^ 3 + x ^ 2 * 96 - x * 32',
+            '-72x ^ 3 + x ^ 2 * 96 - x * 32',
             '-72x ^ 3 + 96x ^ 2 - x * 32',
             '-72x ^ 3 + 96x ^ 2 + 32 * -x',
-            '-72x ^ 3 + 96x ^ 2 - 32x'])
+            '-72x ^ 3 + 96x ^ 2 - 32x',
+        ])