Pyparsing: named results?

I am writing a parser to parse mathematical expressions that contain variables among other things. I want a list of all captured variables. But I only get 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.

+3


source to share


1 answer


By default, named results capture only the last item. If you use an explicit method call setResultsName

, you can get all the elements by adding an optional argument listAllMatches=True

. Since you are using the shortcut form var('var')

, you can get the behavior of listAllMatches if you end the result name with "*":

expr << var('var*') + ZeroOrMore(Literal('+') + expr)

      

I prefer to use a method dump()

to list the body and names from the 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 this way, your operations will be evaluated from right to left. This will be fine if you are evaluating only addition, but doing "3 - 5 + 2" from right to left will give you -4 when you should get 0. Look at using infixNotation

(formerly called operatorPrecedence

) to define and evaluate arithmetic and boolean expressions. There are also several examples available on the pyparsing wiki page at pyparsing.wikispaces.com.

+2


source







All Articles