diff --git a/pymbolic/parser.py b/pymbolic/parser.py index 3ca63ef203f81a17a9d26ef02d3c90c49b98df7e..9c117b0608035eaf256a4066911831085ea29d69 100644 --- a/pymbolic/parser.py +++ b/pymbolic/parser.py @@ -50,6 +50,14 @@ def _join_to_slice(left, right): else: return Slice((left, right)) + + + +class FinalizedTuple(tuple): + """A tuple that may not have elements appended to it, because it was + terminated by a close-paren. + """ + class Parser: lex_table = [ (_equal, pytools.lex.RE(r"==")), @@ -155,6 +163,8 @@ class Parser: left_exp = self.parse_expression(pstate) pstate.expect(_closepar) pstate.advance() + if isinstance(left_exp, tuple): + left_exp = FinalizedTuple(left_exp) else: left_exp = self.parse_terminal(pstate) @@ -173,6 +183,9 @@ class Parser: pstate, min_precedence, left_exp) left_exp, did_something = result + if isinstance(left_exp, FinalizedTuple): + return tuple(left_exp) + return left_exp def parse_postfix(self, pstate, min_precedence, left_exp): @@ -275,7 +288,7 @@ class Parser: left_exp = (left_exp,) else: new_el = self.parse_expression(pstate, _PREC_COMMA) - if isinstance(left_exp, tuple): + if isinstance(left_exp, tuple) and not isinstance(left_exp, FinalizedTuple): left_exp = left_exp + (new_el,) else: left_exp = (left_exp, new_el) diff --git a/test/test_pymbolic.py b/test/test_pymbolic.py index 8fc5a08b17d3dba9f39cf63c59ad5eafa03324cd..cf4e3530b283566e21c20ea2bfc92764fe04575d 100644 --- a/test/test_pymbolic.py +++ b/test/test_pymbolic.py @@ -160,6 +160,12 @@ def test_parser(): assert parse("e1") == prim.Variable("e1") assert parse("d1") == prim.Variable("d1") + from pymbolic import variables + f, x, y, z = variables("f x y z") + assert parse("f((x,y),z)") == f((x,y),z) + assert parse("f((x,),z)") == f((x,),z) + assert parse("f(x,(y,z),z)") == f(x,(y,z),z) +