Replies: 7 comments
-
oh, and I have really aweful exceptipons when the parsed string has syntax issues. it is always stack exceptions and not the nice exception "hey at position 3 after the "or" something is not right..." kind of deal. |
Beta Was this translation helpful? Give feedback.
-
For these kinds of grammars where there is a lot of backtracking (expressions grammars are a good example) you should turn on memoization which can yield a massive speed improvements. Here is a test on my machine: import time
# Without memoization
ExpressionParser = ParserPython(expression, comment, debug=False, reduce_tree=True,
ignore_case=True)
exp_str = """(p in [37,47] and (c in ["A", "P"] or l==true))
or (p in [75,76,361,390,391] and c in ["A", "P"])"""
start = time.process_time()
exp_nomem = ExpressionParser.parse(exp_str)
print(exp_nomem.tree_str())
print("TIME:", time.process_time() - start, "\n")
# With memoization
ExpressionParser = ParserPython(expression, comment, debug=False, reduce_tree=True,
ignore_case=True, memoization=True)
start = time.process_time()
exp_mem = ExpressionParser.parse(exp_str)
print(exp_mem.tree_str())
print("TIME:", time.process_time() - start) Output:
As you can see, without memoization it takes over 9 secs while with memoization it takes only 4 ms. For handling exception see this part of the docs |
Beta Was this translation helpful? Give feedback.
-
TLDR; for exception the easy way to get just the error message without stacktrace is to catch |
Beta Was this translation helpful? Give feedback.
-
thanks igor! it seems i can also improve performance by rewriting a few rules. but memotization already improved significantly. |
Beta Was this translation helpful? Give feedback.
-
you are my hero of the day! |
Beta Was this translation helpful? Give feedback.
-
I rewrote the first few rules to be: def disjunction(): return conjunction, ZeroOrMore( Kwd("OR"), conjunction )
def conjunction(): return inversion, ZeroOrMore( Kwd("AND"), inversion)
def inversion(): return Optional(Kwd('NOT')), comparison
def comparison(): return [ binaryCompareOp, notin, element_in, isnot, element_is, plus ]
def binaryCompareOp(): return plus, ['==','!=','<=','<','>=','>'], plus and that alone helped considerably plus Igors tipp. Problem solved. |
Beta Was this translation helpful? Give feedback.
-
I'm glad it solved your problem. I'll leave the issue open labeled with |
Beta Was this translation helpful? Give feedback.
-
Dear all,
first of all: nice work! keep it up.
I am currently working on an expression parser (arpeggio 1.10.1) that mimics python expressions:
when I execute a parse:
expression = ExpressionParser.parse("""(p in [37,47] and (c in ["A", "P"] or l==true)) or (p in [75,76,361,390,391] and c in ["A", "P"])""")
it takes about 8 seconds. that is way to long. I would like it to be way below 1 second for parsing such a simple expression.
could anyone assist in explaing or advising how to fix the grammar? (which is directly derived from the peg parser of python itself and translated to arpeggio style)
thanks
carsten
Thanks for pushing me in the right direction
Beta Was this translation helpful? Give feedback.
All reactions