3

I am trying to create a parser for condition statements. Something like [X=2 OR Y contains A]

Here is what I came up with so far:

parameter = pp.Word(pp.alphanums).setResultsName('parameter')
operator = pp.oneOf(['=', '!=', 'contains', 'CONTAINS']).setResultsName('operator')
value = pp.Word(pp.alphanums).setResultsName('value')
condition = pp.Group(parameter + operator + value).setResultsName('condition')
expr = pp.operatorPrecedence(condition,[
                            ("AND", 2, pp.opAssoc.LEFT, ),
                            ("OR", 2, pp.opAssoc.LEFT, ),
                            ]).setResultsName('expr')

parse_result = expr.parseString('X=2 OR Y contains A')
print(parse_result.dump()

which prints the following

[[['X', '=', '2'], 'OR', ['Y', 'contains', 'A']]]
- expr: [['X', '=', '2'], 'OR', ['Y', 'contains', 'A']]
  - condition: ['Y', 'contains', 'A']
    - operator: 'contains'
    - parameter: 'Y'
    - value: 'A'

And dump result has only the last condition and the first condition is missing in the result. How can I access to all of the conditions in parse result?

user1390638
  • 180
  • 2
  • 8
  • 1
    Remove the results name on `condition`. This will let `dump()` dump out all the elements as a list instead of showing the named values. The next step will be to add classes for OR and AND terms. See the answer to [this question](https://stackoverflow.com/questions/64709299/pyparsing-evaluating-expression) for more detailed advice. – PaulMcG Dec 31 '20 at 00:48
  • 2
    You can also get all the conditions by calling `setResultsName("condition", listAllMatches=True)` - tells pyparsing to keep all matching named results, not just the last. In general, though I find results names to be less helpful in `operatorPrecedence` expressions, and instead recommend using a parse action to capture the parsed tokens into an AST-ish class. (Also, `operatorPrecedence` is being renamed to `infixNotation` - use the new names, since the old name will be dropped in pyparsing 3.0.) Look for the examples that use `infixNotation` to see how this is done. – PaulMcG Jan 03 '21 at 00:20

0 Answers0