From 1c79332afcd17f830afcf58766e79caf1ad5f257 Mon Sep 17 00:00:00 2001
From: Andreas Kloeckner <inform@tiker.net>
Date: Thu, 9 Jun 2005 23:39:01 +0000
Subject: [PATCH] [pymbolic @
 Arch-1:inform@tiker.net--iam-2005%pymbolic--mainline--1.0--patch-3] Simple
 fixes for mapper and parser.

---
 src/__init__.py |  4 ++-
 src/mapper.py   | 16 ++++++------
 src/parser.py   | 69 +++++++++++++++++++++++++++----------------------
 3 files changed, 49 insertions(+), 40 deletions(-)

diff --git a/src/__init__.py b/src/__init__.py
index 7b488a0..6fb21ae 100644
--- a/src/__init__.py
+++ b/src/__init__.py
@@ -22,5 +22,7 @@ if __name__ == "__main__":
     #print evaluate(ex, {"alpha":5, "cos":math.cos, "x":-math.pi, "pi":math.pi})
     #print is_constant(ex)
     #print substitute(ex, {"alpha": ex})
-    print differentiate(ex, "x")
+    ex2 = parse("cos(x**2/x)")
+    print ex2
+    print differentiate(ex2, "x")
 
diff --git a/src/mapper.py b/src/mapper.py
index 004cb6f..d126fa0 100644
--- a/src/mapper.py
+++ b/src/mapper.py
@@ -28,22 +28,22 @@ class CombineMapper(ByArityMapper):
         return expr.Child.invoke_mapper(self)
 
     def map_binary(self, expr):
-        return self.combine(expr.Child1.invoke_mapper(self),
-                            expr.Child2.invoke_mapper(self))
+        return self.combine((expr.Child1.invoke_mapper(self),
+                             expr.Child2.invoke_mapper(self)))
 
     def map_n_ary(self, expr):
         return self.combine(child.invoke_mapper(self)
                             for child in expr.Children)
 
     def map_polynomial(self, expr):
-        return self.combine([expr.Base.invoke_mapper(self)] 
-                            + [child.invoke_mapper(self)
-                               for child in expr.Children])
+        return self.combine((expr.Base.invoke_mapper(self)) 
+                            + (child.invoke_mapper(self)
+                               for child in expr.Children))
 
     def map_call(self, expr):
-        return self.combine([expr.Function.invoke_mapper(self)] 
-                            + [child.invoke_mapper(self)
-                               for child in expr.Parameters])
+        return self.combine((expr.Function.invoke_mapper(self))
+                            + (child.invoke_mapper(self)
+                               for child in expr.Parameters))
 
 
 
diff --git a/src/parser.py b/src/parser.py
index aa0bb63..60f8dfd 100644
--- a/src/parser.py
+++ b/src/parser.py
@@ -78,40 +78,47 @@ def parse(expr_str):
 
         left_exp = parse_terminal(pstate)
 
-        if pstate.is_at_end():
-            return left_exp
+        did_something = True
+        while did_something:
+            did_something = False
+            if pstate.is_at_end():
+                return left_exp
+            
+            next_tag = pstate.next_tag()
 
-        next_tag = pstate.next_tag()
-
-        if next_tag is _openpar and _PREC_CALL >= min_precedence:
-            pstate.advance()
-            pstate.expect_not_end()
-            if pstate.next_tag is _closepar:
+            if next_tag is _openpar and _PREC_CALL >= min_precedence:
+                pstate.advance()
+                pstate.expect_not_end()
+                if pstate.next_tag is _closepar:
+                    pstate.advance()
+                    left_exp = primitives.Call(left_exp, ())
+                else:
+                    left_exp = primitives.Call(left_exp, 
+                                             tuple(parse_expr_list(pstate)))
+                    pstate.expect(_closepar)
+                did_something = True
+            elif next_tag is _plus and _PREC_PLUS >= min_precedence:
+                pstate.advance()
+                left_exp = parse_expression(pstate, _PREC_PLUS)
+                did_something = True
+            elif next_tag is _minus and _PREC_PLUS >= min_precedence:
+                pstate.advance()
+                left_exp -= primitives.Negation(parse_expression(pstate, _PREC_PLUS))
+                did_something = True
+            elif next_tag is _times and _PREC_TIMES >= min_precedence:
+                pstate.advance()
+                left_exp *= parse_expression(pstate, _PREC_TIMES)
+                did_something = True
+            elif next_tag is _over and _PREC_TIMES >= min_precedence:
                 pstate.advance()
-                return primitives.Call(left_exp, ())
-            else:
-                result = primitives.Call(left_exp, 
-                                         tuple(parse_expr_list(pstate)))
-                pstate.expect(_closepar)
-                return result
+                left_exp /= parse_expression(pstate, _PREC_TIMES)
+                did_something = True
+            elif next_tag is _power and _PREC_POWER >= min_precedence:
+                pstate.advance()
+                left_exp **= parse_expression(pstate, _PREC_POWER)
+                did_something = True
 
-        if next_tag is _plus and _PREC_PLUS >= min_precedence:
-            pstate.advance()
-            return left_exp+parse_expression(pstate, _PREC_PLUS)
-        elif next_tag is _minus and _PREC_PLUS >= min_precedence:
-            pstate.advance()
-            return left_exp-primitives.Negation(parse_expression(pstate, _PREC_PLUS))
-        elif next_tag is _times and _PREC_TIMES >= min_precedence:
-            pstate.advance()
-            return left_exp*parse_expression(pstate, _PREC_TIMES)
-        elif next_tag is _over and _PREC_TIMES >= min_precedence:
-            pstate.advance()
-            return left_exp/parse_expression(pstate, _PREC_TIMES)
-        elif next_tag is _power and _PREC_POWER >= min_precedence:
-            pstate.advance()
-            return left_exp**parse_expression(pstate, _PREC_TIMES)
-        else:
-            return left_exp
+        return left_exp
 
         
     pstate = lex.LexIterator([(tag, s, idx) 
-- 
GitLab