Mercurial > lcfOS
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)