Pyparsing funktionierte gut für eine sehr kleine Grammatik, aber als die Grammatik wuchs, ging die Leistung und der Speicherverbrauch durch das Dach.pyparsing Leistung und Speichernutzung
Mein aktueller gramar ist:
newline = LineEnd()
minus = Literal ('-')
plus = Literal ('+')
star = Literal ('*')
dash = Literal ('/')
dashdash = Literal ('//')
percent = Literal ('%')
starstar = Literal ('**')
lparen = Literal ('(')
rparen = Literal (')')
dot = Literal ('.')
comma = Literal (',')
eq = Literal ('=')
eqeq = Literal ('==')
lt = Literal ('<')
gt = Literal ('>')
le = Literal ('<=')
ge = Literal ('>=')
not_ = Keyword ('not')
and_ = Keyword ('and')
or_ = Keyword ('or')
ident = Word (alphas)
integer = Word (nums)
expr = Forward()
parenthized = Group (lparen + expr + rparen)
trailer = (dot + ident)
atom = ident | integer | parenthized
factor = Forward()
power = atom + ZeroOrMore (trailer) + Optional (starstar + factor)
factor << (ZeroOrMore (minus | plus) + power)
term = ZeroOrMore (factor + (star | dashdash | dash | percent)) + factor
arith = ZeroOrMore (term + (minus | plus)) + term
comp = ZeroOrMore (arith + (eqeq | le | ge | lt | gt)) + arith
boolNot = ZeroOrMore (not_) + comp
boolAnd = ZeroOrMore (boolNot + and_) + boolNot
boolOr = ZeroOrMore (boolAnd + or_) + boolAnd
match = ZeroOrMore (ident + eq) + boolOr
expr << match
statement = expr + newline
program = OneOrMore (statement)
Wenn ich analysieren die folgenden
print (program.parseString ('3*(1+2*3*(4+5))\n'))
Es dauert ziemlich lange:
~/Desktop/m2/pyp$ time python3 slow.py
['3', '*', ['(', '1', '+', '2', '*', '3', '*', ['(', '4', '+', '5', ')'], ')']]
real 0m27.280s
user 0m25.844s
sys 0m1.364s
Und die Speichernutzung geht bis zu 1,7 GiB (sic!).
Habe ich einen schwerwiegenden Fehler bei der Implementierung dieser Grammatik gemacht oder wie sonst kann ich die Speichernutzung in erträglichen Grenzen halten?
Gleiche Sache mit lex und yacc in Sekundenbruchteilen. – Hyperboreus