Пипарсинг простой арифметики c грамматика не захватывает выражение - PullRequest
1 голос
/ 16 января 2020

В настоящее время я пишу парсер для простых арифметических c строк с (), {} и [] в виде сбалансированных скобок и * и + в качестве операций. Почему-то моя грамматика, кажется, выключена У кого-нибудь есть идея, как это исправить? Я пытался быть немного более рекурсивным, но всегда сталкивался с ошибками глубины рекурсии.

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])"))

1 Ответ

0 голосов
/ 16 января 2020

Если у вас просто есть базовые c арифметические c операторы, тогда я предлагаю вам , а не использовать infixNotation, но вместо этого определить свой собственный рекурсивный парсер, что-то вроде:

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

Несколько простых тестов:

expr.runTests("""
1+7
1+2+4
-(1+2)*4
3*[11+14]
""", fullDump=False)

Дает:

1+7
[[1, '+', 7]]

1+2+4
[[1, '+', 2, '+', 4]]

-(1+2)*4
[[['-', [1, '+', 2]], '*', 4]]

3*[11+14]
[[3, '*', [11, '+', 14]]]
...