diff python/pyburg.py @ 321:8c569fbe60e4

Load yacc and burg dynamic
author Windel Bouwman
date Sun, 19 Jan 2014 18:48:45 +0100
parents 84d67cce67b7
children 44f336460c2a
line wrap: on
line diff
--- a/python/pyburg.py	Sun Jan 19 16:09:44 2014 +0100
+++ b/python/pyburg.py	Sun Jan 19 18:48:45 2014 +0100
@@ -1,51 +1,59 @@
 #!/usr/bin/python
 
 """
-    Bottom up rewrite generator.
+Bottom up rewrite generator.
 
-    This script takes as input a description of patterns and outputs a
-    matcher class that can match trees given the patterns.
+This script takes as input a description of patterns and outputs a
+matcher class that can match trees given the patterns.
 
     Patterns are specified as follows:
-     reg -> ADDI32(reg, reg) 2 (. add $1 $2 .)
+     reg -> ADDI32(reg, reg) 2 (. add NT0 NT1 .)
      reg -> MULI32(reg, reg) 3 (. .)
     or a multiply add:
      reg -> ADDI32(MULI32(reg, reg), reg) 4 (. muladd $1, $2, $3 .)
     The general specification pattern is:
      [result] -> [tree] [cost] [template code]
 
-    A tree is described using parenthesis notation. For example a node X with
-    three
-    child nodes is described as:
+Trees
+-----
+
+A tree is described using parenthesis notation. For example a node X with
+three child nodes is described as:
      X(a, b, b)
-    Trees can be nested:
+Trees can be nested:
      X(Y(a, a), a)
-    The 'a' in the example above indicates an open connection to a next tree
-    pattern.
+The 'a' in the example above indicates an open connection to a next tree
+pattern.
+
 
-    In the example above 'reg' is a non-terminal. ADDI32 is a terminal. non-terminals
-    cannot have child nodes. A special case occurs in this case:
-    reg -> rc
-    where 'rc' is a non-terminal. This is an example of a chain rule. Chain rules
-    can be used to allow several variants of non-terminals.
+In the example above 'reg' is a non-terminal. ADDI32 is a terminal. non-terminals
+cannot have child nodes. A special case occurs in this case:
+reg -> rc
+where 'rc' is a non-terminal. This is an example of a chain rule. Chain rules
+can be used to allow several variants of non-terminals.
 
-    The generated matcher uses dynamic programming to find the best match of the
-    tree. This strategy consists of two steps:
-    - label: During this phase the given tree is traversed in a bottom up way.
-      each node is labelled with a possible matching rule and the corresponding cost.
-    - select: In this step, the tree is traversed again, selecting at each point
-      the cheapest way to get to the goal.
+The generated matcher uses dynamic programming to find the best match of the
+tree. This strategy consists of two steps:
+  - label: During this phase the given tree is traversed in a bottom up way.
+    each node is labelled with a possible matching rule and the corresponding cost.
+  - select: In this step, the tree is traversed again, selecting at each point
+    the cheapest way to get to the goal.
 
 """
 
 import sys
+import os
 import argparse
 from ppci import Token
-import burg_parser   # Automatically generated
 from pyyacc import ParserException, EOF
+import yacc
 import baselex
 from tree import Tree
 
+# Generate parser on the fly:
+spec_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'burg.x')
+burg_parser = yacc.load_as_module(spec_file)
+
 
 class BurgLexer:
     def feed(self, txt):
@@ -129,7 +137,6 @@
             template = 'pass'
         rule = Rule(non_term, tree, cost, template)
         if len(tree.children) == 0 and tree.name not in self.terminals:
-            print('chain:', rule)
             self.non_term(tree.name).chain_rules.append(rule)
         self.non_term(rule.non_term)
         self.rules.append(rule)
@@ -262,14 +269,17 @@
         return tst + child_tests
 
 
-def main():
-    # Parse arguments:
+def make_argument_parser():
+    """ Constructs an argument parser """
     parser = argparse.ArgumentParser(description='pyburg bottom up rewrite system generator compiler compiler')
     parser.add_argument('source', type=argparse.FileType('r'), \
       help='the parser specification')
     parser.add_argument('-o', '--output', type=argparse.FileType('w'), \
         default=sys.stdout)
-    args = parser.parse_args()
+    return parser
+
+
+def main(args):
     src = args.source.read()
     args.source.close()
 
@@ -283,5 +293,8 @@
     generator = BurgGenerator()
     generator.generate(burg_system, args.output)
 
+
 if __name__ == '__main__':
-    main()
+    # Parse arguments:
+    args = make_argument_parser().parse_args()
+    main(args)