Procházet zdrojové kódy

Line generaor now supports omission of negated multiplication sign.

Taddeus Kroes před 14 roky
rodič
revize
d1e486ac08
2 změnil soubory, kde provedl 46 přidání a 9 odebrání
  1. 18 8
      line.py
  2. 28 1
      tests/test_line.py

+ 18 - 8
line.py

@@ -98,7 +98,8 @@ def generate_line(root):
                     child_pred = pred(child)
 
                     if child_pred < node_pred or \
-                            (i and child_pred == node_pred and op != child.title()):
+                            (i and child_pred == node_pred \
+                             and op != child.title()):
                         exp = '(' + exp + ')'
 
                     e.append(exp)
@@ -127,26 +128,35 @@ def generate_line(root):
                     if (left_id or left_paren or left_int) \
                             and (right_id or right_paren):
                         sep = ''
-                elif op == '+':
-                    # An addition with negation can be written as a
-                    # subtraction, e.g. 1 + -2 == 1 - 2
-                    if node[1].title() == '-' and len(node[1]) == 1:
-                        sep = ' - '
-                        e[1] = e[1][1:]
 
                 result += sep.join(e)
         else:
             # Function call
             result = op + '(' + ', '.join(map(traverse, node)) + ')'
 
-        return result
+        # An addition with negation can be written as a subtraction, e.g.:
+        # 1 + -2  ->  1 - 2
+        return result.replace('+ -', '- ')
 
     return traverse(root)
 
 
+def is_negation(node):
+    if isinstance(node, Leaf):
+        return False
+
+    return node.title() == '-' and len(node) == 1
+
+
 def is_id(node):
+    if is_negation(node):
+        return is_id(node[0])
+
     return isinstance(node, Leaf) and not node.title().isdigit()
 
 
 def is_int(node):
+    if is_negation(node):
+        return is_int(node[0])
+
     return isinstance(node, Leaf) and node.title().isdigit()

+ 28 - 1
tests/test_line.py

@@ -1,7 +1,7 @@
 import unittest
 
 from node import Node as N, Leaf as L
-from line import generate_line
+from line import generate_line, is_negation, is_id, is_int
 
 
 class TestLine(unittest.TestCase):
@@ -105,6 +105,9 @@ class TestLine(unittest.TestCase):
         mul = N('*', N('*', a, l2), b)
         self.assertEquals(generate_line(mul), 'a * 2b')
 
+        plus = N('*', N('*', N('-', a), b), c)
+        self.assertEquals(generate_line(plus), '-abc')
+
         mul = N('*', a, N('-', b, c))
         self.assertEquals(generate_line(mul), 'a(b - c)')
         mul = N('*', l2, N('-', b, c))
@@ -126,3 +129,27 @@ class TestLine(unittest.TestCase):
     def test_plus_to_minus(self):
         plus = N('+', L(1), N('-', L(2)))
         self.assertEquals(generate_line(plus), '1 - 2')
+
+        l1, a, b, c = L(1), L('a'), L('b'), L('c')
+        plus = N('+', l1, N('*', N('*', N('-', a), b), c))
+        self.assertEquals(generate_line(plus), '1 - abc')
+
+    def test_helper_functions(self):
+        l1, a = L(1), L('a')
+        neg = N('-', l1)
+        neg_a = N('-', a)
+        plus = N('+', l1, a)
+
+        self.assertTrue(is_negation(neg))
+        self.assertFalse(is_negation(l1))
+        self.assertFalse(is_negation(plus))
+
+        self.assertTrue(is_id(a))
+        self.assertTrue(is_id(neg_a))
+        self.assertFalse(is_id(neg))
+        self.assertFalse(is_id(plus))
+
+        self.assertTrue(is_int(l1))
+        self.assertTrue(is_int(neg))
+        self.assertFalse(is_int(neg_a))
+        self.assertFalse(is_int(plus))