[pypy-svn] r44556 - pypy/dist/pypy/rlib/parsing

cfbolz at codespeak.net cfbolz at codespeak.net
Wed Jun 27 13:21:12 CEST 2007


Author: cfbolz
Date: Wed Jun 27 13:21:10 2007
New Revision: 44556

Added:
   pypy/dist/pypy/rlib/parsing/codebuilder.py
Modified:
   pypy/dist/pypy/rlib/parsing/ebnfparse.py
   pypy/dist/pypy/rlib/parsing/makepackrat.py
Log:
factor out common code


Added: pypy/dist/pypy/rlib/parsing/codebuilder.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rlib/parsing/codebuilder.py	Wed Jun 27 13:21:10 2007
@@ -0,0 +1,54 @@
+class Codebuilder(object):
+    def __init__(self):
+        self.blocks = []
+        self.code = []
+
+    def get_code(self):
+        assert not self.blocks
+        return "\n".join(["    " * depth + line for depth, line in self.code])
+
+    def make_parser(self):
+        m = {'Status': Status,
+             'Nonterminal': Nonterminal,
+             'Symbol': Symbol,}
+        exec py.code.Source(self.get_code()).compile() in m
+        return m['Parser']
+
+    def emit(self, line):
+        for line in line.split("\n"):
+            self.code.append((len(self.blocks),  line))
+
+    def emit_initcode(self, line):
+        for line in line.split("\n"):
+            self.initcode.append(line)
+
+    def start_block(self, blockstarter):
+        assert blockstarter.endswith(":")
+        self.emit(blockstarter)
+        self.blocks.append(blockstarter)
+        def BlockEnder():
+            yield None
+            self.end_block(blockstarter)
+        return BlockEnder()
+
+    def end_block(self, starterpart=""):
+        block = self.blocks.pop()
+        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
+ 

Modified: pypy/dist/pypy/rlib/parsing/ebnfparse.py
==============================================================================
--- pypy/dist/pypy/rlib/parsing/ebnfparse.py	(original)
+++ pypy/dist/pypy/rlib/parsing/ebnfparse.py	Wed Jun 27 13:21:10 2007
@@ -1,6 +1,7 @@
 import py
 from pypy.rlib.parsing.parsing import PackratParser, Rule
 from pypy.rlib.parsing.tree import Nonterminal, Symbol, RPythonVisitor
+from pypy.rlib.parsing.codebuilder import Codebuilder
 from pypy.rlib.parsing.regexparse import parse_regex
 import string
 from pypy.rlib.parsing.regex import *
@@ -277,14 +278,12 @@
             all_changes.append(real_changes)
         return all_rules + other_rules, all_changes + other_changes
 
-class TransformerMaker(object):
+class TransformerMaker(Codebuilder):
     def __init__(self, rules, changes):
+        Codebuilder.__init__(self)
         self.rules = rules
         self.changes = changes
         self.nonterminals = dict.fromkeys([rule.nonterminal for rule in rules])
-        self.code = []
-        self.depth = 0
-        self.blocks = []
 
     def make_transformer(self, print_code=False):
         self.start_block("class ToAST(object):")
@@ -309,8 +308,7 @@
         self.emit("return r[0]")
         self.end_block("transform")
         self.end_block("ToAST")
-        assert not self.blocks
-        code = "\n".join(self.code)
+        code = self.get_code()
         if print_code:
             print code
         ns = {"RPythonVisitor": RPythonVisitor, "Nonterminal": Nonterminal,
@@ -324,20 +322,6 @@
         ToAST.changes = self.changes
         return ToAST
 
-    def emit(self, line):
-        for line in line.split("\n"):
-            self.code.append(" " * (4 * len(self.blocks)) + line)
-
-    def start_block(self, blockstarter):
-        assert blockstarter.endswith(":")
-        self.emit(blockstarter)
-        self.blocks.append(blockstarter)
-
-    def end_block(self, starterpart=""):
-        block = self.blocks.pop()
-        assert starterpart in block, "ended wrong block %s with %s" % (
-            block, starterpart)
-
     def dispatch(self, symbol, expr):
         if symbol in self.nonterminals:
             return "self.visit_%s(%s)" % (symbol, expr)

Modified: pypy/dist/pypy/rlib/parsing/makepackrat.py
==============================================================================
--- pypy/dist/pypy/rlib/parsing/makepackrat.py	(original)
+++ pypy/dist/pypy/rlib/parsing/makepackrat.py	Wed Jun 27 13:21:10 2007
@@ -1,6 +1,7 @@
 import py
 import sys
 from pypy.rlib.parsing.tree import Nonterminal, Symbol, RPythonVisitor
+from pypy.rlib.parsing.codebuilder import Codebuilder
 from pypy.rlib.objectmodel import we_are_translated
 
 class BacktrackException(Exception):
@@ -296,18 +297,13 @@
         self.status = self.INPROGRESS
         self.result = None
 
-class ParserBuilder(RPythonVisitor):
+class ParserBuilder(RPythonVisitor, Codebuilder):
     def __init__(self):
-        self.code = []
-        self.blocks = []
+        Codebuilder.__init__(self)
         self.initcode = []
         self.names = {}
         self.matchers = {}
 
-    def get_code(self):
-        assert not self.blocks
-        return "\n".join(["    " * depth + line for depth, line in self.code])
-
     def make_parser(self):
         m = {'Status': Status,
              'Nonterminal': Nonterminal,
@@ -315,44 +311,6 @@
         exec py.code.Source(self.get_code()).compile() in m
         return m['Parser']
 
-    def emit(self, line):
-        for line in line.split("\n"):
-            self.code.append((len(self.blocks),  line))
-
-    def emit_initcode(self, line):
-        for line in line.split("\n"):
-            self.initcode.append(line)
-
-    def start_block(self, blockstarter):
-        assert blockstarter.endswith(":")
-        self.emit(blockstarter)
-        self.blocks.append(blockstarter)
-        def BlockEnder():
-            yield None
-            self.end_block(blockstarter)
-        return BlockEnder()
-
-    def end_block(self, starterpart=""):
-        block = self.blocks.pop()
-        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, ))



More information about the Pypy-commit mailing list