Reputation: 113
I am writing a parser to parse mathematical expressions, which contain variables among other things. I want a list of all the captured variables. But I am only getting the last captured variable. Below is a minimal example to show the problem.
>>> from pyparsing import *
>>> var = Word(alphas)
>>> expr = Forward()
>>> expr << var('var') + ZeroOrMore(Literal('+') + expr)
>>> foo = expr.parseString("x + y + z")
>>> foo
(['x', '+', 'y', '+', 'z'], {'var': [('x', 0), ('y', 2), ('z', 4)]})
>>> foo['var']
'z'
I was expecting ['x', 'y', 'z']. I am using pyparsing version 2.1.
Upvotes: 7
Views: 938
Reputation: 63709
By default, named results only capture the last item. If you use the explicit setResultsName
method call, you can get all the items by adding the optional listAllMatches=True
argument. Since you are using the shortcut form var('var')
, you can get the listAllMatches behavior if you end the results name with an '*':
expr << var('var*') + ZeroOrMore(Literal('+') + expr)
I prefer to use the dump()
method to list out the body and names from parsed results:
>>> foo = expr.parseString("x + y + z")
>>> foo.var
(['x', 'y', 'z'], {})
>>> print foo.dump()
['x', '+', 'y', '+', 'z']
- var: ['x', 'y', 'z']
By the way, because you have defined your grammar in this way, your operations will be evaluated right-to-left. This will be okay if you only evaluate addition, but doing "3 - 5 + 2" right-to-left will give you -4, when you should get 0. Look into using infixNotation
(formerly named operatorPrecedence
) to define and evaluate arithmetic and boolean expressions. There are also several examples available on the pyparsing wiki at pyparsing.wikispaces.com.
Upvotes: 6