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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With