I am currently writing a parser for simple arithmetic strings with (), {} and [] as balanced brackets and * and + as operations. Somehow my grammar seems to be off though. Does somebody have an idea how to fix that? I tried to be a bit more recursive but always run into recursion depth errors.
from pyparsing import *
enclosed = Forward()
nestedParens = nestedExpr('(', ')', content=enclosed)
nestedBrackets = nestedExpr('[', ']', content=enclosed)
nestedCurlies = nestedExpr('{', '}', content=enclosed)
braexpr = Forward()
parexpr = Forward()
curexpr = Forward()
parexpr << OneOrMore(infixNotation(
nestedParens | nestedBrackets | nestedCurlies | Word(nums),
[
('*', 2, opAssoc.LEFT),
('+', 2, opAssoc.LEFT),
]
))
curexpr << OneOrMore(infixNotation(
nestedParens | nestedBrackets | nestedCurlies | Word(nums),
[
('*', 2, opAssoc.LEFT),
('+', 2, opAssoc.LEFT),
],
Suppress('{'),
Suppress('}')
))
braexpr << OneOrMore(infixNotation(
nestedParens | nestedBrackets | nestedCurlies | Word(nums),
[
('*', 2, opAssoc.LEFT),
('+', 2, opAssoc.LEFT),
],
Suppress('['),
Suppress(']')
))
enclosed << ( (nestedParens | nestedBrackets | nestedCurlies | Word(nums)) + oneOf("+ *") + (enclosed | nestedParens | nestedBrackets | nestedCurlies | Word(nums)) | parexpr | curexpr | braexpr | nestedParens | nestedBrackets | nestedCurlies | Word(nums) )
print(evaluate("[{1}+5]*({2}+[{1*3}+2] + 2])"))
If you just have the basic arithmetic operators, then I suggest you not use infixNotation, but instead define your own recursive parser, something like:
import pyparsing as pp
ppc = pp.pyparsing_common
operand = ppc.integer()
multop = pp.oneOf("* /")
addop = pp.oneOf("+ -")
expr = pp.Forward()
# here is where to extend the grouping symbols to include (), [], and {}
LPAR, RPAR, LBRACK, RBRACK, LBRACE, RBRACE = map(pp.Suppress, "()[]{}")
atom = operand | LPAR + expr + RPAR | LBRACK + expr + RBRACK | LBRACE + expr + RBRACE
factor = pp.Group('-' + atom) | atom
term = pp.Group(factor + (multop + factor)[1, ...]) | factor
sum = pp.Group(term + (addop + term)[1, ...]) | term
expr <<= sum
Some simple tests:
expr.runTests("""
1+7
1+2+4
-(1+2)*4
3*[11+14]
""", fullDump=False)
Gives:
1+7
[[1, '+', 7]]
1+2+4
[[1, '+', 2, '+', 4]]
-(1+2)*4
[[['-', [1, '+', 2]], '*', 4]]
3*[11+14]
[[3, '*', [11, '+', 14]]]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.