Analyze math expressions with pyparsing

I am trying to parse a math expression using pyparsing. I know that I can just copy the calculator example from the pyparsing website, but I want to understand it, so I can add to it later. And I'm here because I tried to understand this example, and I could not, so I tried my best, and I got to this:

symbol = (
    pp.Literal("^") |
    pp.Literal("*") |
    pp.Literal("/") |
    pp.Literal("+") |
    pp.Literal("-")
)
operation = pp.Forward()
atom = pp.Group(
    pp.Literal("(").suppress() + operation + pp.Literal(")").suppress()
) | number
operation << (pp.Group(number + symbol + number + pp.ZeroOrMore(symbol + atom)) | atom)
expression = pp.OneOrMore(operation)


print(expression.parseString("9-1+27+(3-5)+9"))

What prints:

[[9, '-', 1, '+', 27, '+', [[3, '-', 5]], '+', 9]]

It works, curious. I want to take priority and everyone is sorted by Groups, but after a lot, I could not find a way to do this. Moreover:

[[[[9, '-', 1], '+', 27], '+', [3, '-', 5]], '+', 9]

I want to save it in AST search, I would like to generate code from it.

Have I seen the class operatorPrecedence? similar to Forward, but I don’t think I understand how it works.

EDIT:

I tried in more detail operatorPrecedence, and I got the following:

expression = pp.operatorPrecedence(number, [
    (pp.Literal("^"), 1, pp.opAssoc.RIGHT),
    (pp.Literal("*"), 2, pp.opAssoc.LEFT),
    (pp.Literal("/"), 2, pp.opAssoc.LEFT),
    (pp.Literal("+"), 2, pp.opAssoc.LEFT),
    (pp.Literal("-"), 2, pp.opAssoc.LEFT)
])

( , ), .

+4
1

- "infix notation" ( pyparsing operatorPrecedence infixNotation). infix, fourFn.py - pyparsing. BNF 4- :

operand :: integer or real number
factor :: operand | '(' expr ')'
term :: factor ( ('*' | '/') factor )*
expr :: term ( ('+' | '-') term )*

, , .

, .

( ), expr ().

, , expr, expr .

pyparsing (, integer real ):

LPAR,RPAR = map(Suppress, '()')
expr = Forward()
operand = real | integer
factor = operand | Group(LPAR + expr + RPAR)
term = factor + ZeroOrMore( oneOf('* /') + factor )
expr <<= term + ZeroOrMore( oneOf('+ -') + term )

, expr, :

3
3+2
3+2*4
(3+2)*4

infixNotation pyparsing :

expr = infixNotation(operand,
        [
        (oneOf('* /'), 2, opAssoc.LEFT),
        (oneOf('+ -'), 2, opAssoc.LEFT),
        ])

, , , , fourFn.py.

+8

Source: https://habr.com/ru/post/1542105/


All Articles