Reputation: 185
I want to parse the following (simplified) recursive expressions using PyParsing:
foo
(foo + bar)
foo'attribute
foo + bar'attribute
foo.field
(foo'attribute + foo.field)'attribute
I came up with the following parser which works for all of the above expressions:
identifier = Word(alphas)
expr = (
infixNotation(
identifier,
[
(Literal(".") + identifier, 1, opAssoc.LEFT),
(Literal("'") + identifier, 1, opAssoc.LEFT),
(Literal("+"), 2, opAssoc.LEFT),
],
)
+ StringEnd()
)
What fails, however, are expressions that involve .field
and the 'attribute
suffix together. While foo.field'attribute
is accepted, foo'attribute.field
yields
pyparsing.ParseException: Expected end of text (at char 13), (line:1, col:14)
When exchanging the tuples for attribute and field of the infixNotation
, the second expression parses and the first doesn't. Seems like the order/precedence is relevant.
Any ideas how to parse arbitrary recursive appearances of different suffixes?
Upvotes: 3
Views: 103
Reputation: 370092
Each tuple in the list defines its own level of precedence. When one operator has a higher precedence than another, the lower precedence operator can only be used as an operand of the higher precedence one by using parentheses (note that (foo'attribute).field
parses fine).
For unary operators, you usually want a single level of precedence for all postfix operators (and another for all prefix operators if you had any). The way you do that in pyparsing is by using a tuple containing a single rule that can match both operators:
(oneOf(". '") + identifier, 1, opAssoc.LEFT),
Upvotes: 2