[pypy-svn] r44533 - pypy/dist/pypy/rlib/parsing
cfbolz at codespeak.net
cfbolz at codespeak.net
Tue Jun 26 00:07:46 CEST 2007
Author: cfbolz
Date: Tue Jun 26 00:07:46 2007
New Revision: 44533
Modified:
pypy/dist/pypy/rlib/parsing/makepackrat.py
Log:
slightly hackish: save the left-recursion detection code in the header when it is not necessary (because no call that could have led to recursion was done)
Modified: pypy/dist/pypy/rlib/parsing/makepackrat.py
==============================================================================
--- pypy/dist/pypy/rlib/parsing/makepackrat.py (original)
+++ pypy/dist/pypy/rlib/parsing/makepackrat.py Tue Jun 26 00:07:46 2007
@@ -273,13 +273,12 @@
self.code = []
self.blocks = []
self.initcode = []
- self.namecount = 0
self.names = {}
self.matchers = {}
def get_code(self):
assert not self.blocks
- return "\n".join(self.code)
+ return "\n".join([" " * depth + line for depth, line in self.code])
def make_parser(self):
m = {'Status': Status,
@@ -290,7 +289,7 @@
def emit(self, line):
for line in line.split("\n"):
- self.code.append(" " * (4 * len(self.blocks)) + line)
+ self.code.append((len(self.blocks), line))
def emit_initcode(self, line):
for line in line.split("\n"):
@@ -310,6 +309,22 @@
assert starterpart in block, "ended wrong block %s with %s" % (
block, starterpart)
+ def store_code_away(self):
+ result = self.blocks, self.code
+ self.code = []
+ self.blocks = []
+ return result
+
+ def restore_code(self, (blocks, code)):
+ result = self.blocks, self.code
+ self.code = code
+ self.blocks = blocks
+ return result
+
+ def add_code(self, (blocks, code)):
+ self.code += [(depth + len(self.blocks), line) for depth, line in code]
+ self.blocks += blocks
+
def memoize_header(self, name, args):
dictname = "_dict_%s" % (name, )
self.emit_initcode("self.%s = {}" % (dictname, ))
@@ -328,18 +343,19 @@
self.emit("return _status")
for _ in self.start_block("elif _statusstatus == _status.ERROR:"):
self.emit("raise BacktrackException(_status.error)")
- for _ in self.start_block(
- "elif (_statusstatus == _status.INPROGRESS or\n"
- " _statusstatus == _status.LEFTRECURSION):"):
- self.emit("_status.status = _status.LEFTRECURSION")
- for _ in self.start_block("if _status.result is not None:"):
- self.emit("self._pos = _status.pos")
- self.emit("return _status")
- for _ in self.start_block("else:"):
- self.emit("raise BacktrackException(None)")
- for _ in self.start_block(
- "elif _statusstatus == _status.SOMESOLUTIONS:"):
- self.emit("_status.status = _status.INPROGRESS")
+ if self.have_call:
+ for _ in self.start_block(
+ "elif (_statusstatus == _status.INPROGRESS or\n"
+ " _statusstatus == _status.LEFTRECURSION):"):
+ self.emit("_status.status = _status.LEFTRECURSION")
+ for _ in self.start_block("if _status.result is not None:"):
+ self.emit("self._pos = _status.pos")
+ self.emit("return _status")
+ for _ in self.start_block("else:"):
+ self.emit("raise BacktrackException(None)")
+ for _ in self.start_block(
+ "elif _statusstatus == _status.SOMESOLUTIONS:"):
+ self.emit("_status.status = _status.INPROGRESS")
self.emit("_startingpos = self._pos")
self.start_block("try:")
self.emit("_result = None")
@@ -440,13 +456,15 @@
for _ in self.start_block("def %s(%s):" % (name, argswithself)):
self.emit("return self._%s(%s).result" % (name, argswithoutself))
self.start_block("def _%s(%s):" % (name, argswithself, ))
-
- self.memoize_header(name, otherargs)
- #self.emit("print '%s', self._pos" % (name, ))
+ self.namecount = 0
self.resultname = "_result"
self.have_call = False
self.created_error = False
+ allother = self.store_code_away()
self.dispatch(t.children[-1])
+ subsequent = self.restore_code(allother)
+ self.memoize_header(name, otherargs)
+ self.add_code(subsequent)
self.memoize_footer(name)
self.end_block("def")
More information about the Pypy-commit
mailing list