2014-01-26 3 views
8

매우 작은 문법에 대해 Pyparsing이 잘 수행되었지만 문법이 늘어남에 따라 성능이 저하되고 지붕을 통해 메모리가 사용됩니다.성능 및 메모리 사용량 구분을

나의 현재 gramar은 다음과 같습니다

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) 

나는 구문 분석 할 때 다음과 같은

print (program.parseString ('3*(1+2*3*(4+5))\n')) 

그것은 아주 오래 걸립니다 :

~/Desktop/m2/pyp$ time python3 slow.py 
['3', '*', ['(', '1', '+', '2', '*', '3', '*', ['(', '4', '+', '5', ')'], ')']] 

real 0m27.280s 
user 0m25.844s 
sys 0m1.364s 

그리고 메모리 사용량이 1.7 지브까지 간다 (영문)!

이 문법을 구현하는 데 심각한 실수를했거나 메모리 사용을 어떻게 견딜 수 있습니까?

+0

lex와 yacc는 초 단위로 구분됩니다. – Hyperboreus

답변

11

대한 파싱 구문 분석 동작을 memoize하는 분석 자료가 많 수 있도록 가져온 후 :

ParserElement.enablePackrat() 

이 성능에 큰 개선을해야한다.

+0

고맙습니다. 시험해 보겠습니다. – Hyperboreus

+1

기록의 경우 컴퓨터에서 3.5 초에서 0.036 초로 거의 100 배 향상됩니다. 메모 작성이 자동으로 켜지지 않는 이유가 있습니까? 일부 경우에는 실패합니다. – Hooked

+1

@Hooked : pyparsing을 사용한 packrat 구문 분석에 대한 자세한 내용은 [pyparsing FAQ의이 항목] (http://pyparsing-public.wikispaces.com/FAQs#toc3)을 참조하십시오. 일반적으로 packrat 파싱에 대해서는 [this SO thread] (https://stackoverflow.com/q/1410477/857390)를 참조하십시오. –