Skip to content

Commit bf14483

Browse files
committed
Compile Python expressions only once, at grammar load/import time.
1 parent 4afacce commit bf14483

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

ometa/builder.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def __init__(self, tree, grammarText):
3232
self.tree = tree
3333
self.grammarText = grammarText
3434
self.gensymCounter = 0
35+
self.compiledExprCache = None
3536

3637

3738
def _generate(self, out, expr, retrn=False, debugname=None):
@@ -109,9 +110,19 @@ def compilePythonExpr(self, out, expr, debugname=None):
109110
ast.literal_eval(expr)
110111
return self._expr(out, 'python', '(' + expr + '), None', debugname)
111112
except ValueError:
112-
return self._expr(out, 'python',
113-
'eval(%r, self.globals, _locals), None' % (expr,),
114-
debugname)
113+
if self.compiledExprCache is None:
114+
return self._expr(out, 'python',
115+
'eval(%r, self.globals, _locals), None' % (expr,),
116+
debugname)
117+
else:
118+
if expr in self.compiledExprCache:
119+
sym = self.compiledExprCache[expr]
120+
else:
121+
sym = self.compiledExprCache[expr] = self._gensym('expr')
122+
123+
return self._expr(out, 'python',
124+
'eval(self.%s, self.globals, _locals), None' % (sym,),
125+
debugname)
115126

116127
def _convertArgs(self, out, rawArgs, debugname):
117128
return [self._generateNode(out, x, debugname) for x in rawArgs]
@@ -325,6 +336,7 @@ def generate_Rule(self, prevOut, name, expr, debugname=None):
325336

326337
def generate_Grammar(self, out, name, takesTreeInput, rules,
327338
debugname=None):
339+
self.compiledExprCache = {}
328340
self.takesTreeInput = takesTreeInput.tag.name == 'true'
329341
out.writeln("def createParserClass(GrammarBase, ruleGlobals):")
330342
funcOut = out.indent()
@@ -338,6 +350,8 @@ def generate_Grammar(self, out, name, takesTreeInput, rules,
338350
out.writeln("")
339351
if self.takesTreeInput:
340352
out.writeln("tree = %s" % self.takesTreeInput)
353+
for expr, sym in self.compiledExprCache.items():
354+
out.writeln("%s = compile(%r, '<string>', 'eval')" % (sym, expr))
341355
funcOut.writeln(
342356
"if %s.globals is not None:" % (name.data,))
343357
out.writeln("%s.globals = %s.globals.copy()" % (name.data,
@@ -347,6 +361,7 @@ def generate_Grammar(self, out, name, takesTreeInput, rules,
347361
"else:")
348362
out.writeln("%s.globals = ruleGlobals" % (name.data,))
349363
funcOut.writeln("return " + name.data)
364+
self.compiledExprCache = None
350365

351366

352367
class _Term2PythonAction(object):

0 commit comments

Comments
 (0)