Mercurial > lcfOS
diff python/pyburg.py @ 357:818be710e13d
Added acceptance function to burg
author | Windel Bouwman |
---|---|
date | Fri, 14 Mar 2014 15:14:29 +0100 |
parents | 5477e499b039 |
children | d2ddfe134c48 |
line wrap: on
line diff
--- a/python/pyburg.py Fri Mar 14 13:02:16 2014 +0100 +++ b/python/pyburg.py Fri Mar 14 15:14:29 2014 +0100 @@ -76,8 +76,7 @@ ('id', r'[A-Za-z][A-Za-z\d_]*', lambda typ, val: (typ, val)), ('kw', r'%[A-Za-z][A-Za-z\d_]*', lambda typ, val: (val, val)), ('number', r'\d+', lambda typ, val: (typ, int(val))), - ('STRING', r"'[^']*'", lambda typ, val: ('id', val[1:-1])), - ('template', r"\(\..*\.\)", lambda typ, val: (typ, val)), + ('STRING', r"'[^']*'", lambda typ, val: ('string', val[1:-1])), ('OTHER', r'[:;\|\(\),]', lambda typ, val: (val, val)), ('SKIP', r'[ ]', None) ] @@ -115,10 +114,11 @@ class Rule: """ A rewrite rule. Specifies a tree that can be rewritten into a result at a specific cost """ - def __init__(self, non_term, tree, cost, template): + def __init__(self, non_term, tree, cost, acceptance, template): self.non_term = non_term self.tree = tree self.cost = cost + self.acceptance = acceptance self.template = template self.nr = 0 @@ -154,11 +154,11 @@ non_terminals = property(lambda s: s.symType(Nonterm)) - def add_rule(self, non_term, tree, cost, template): - template = template[2:-2].strip() + def add_rule(self, non_term, tree, cost, acceptance, template): + template = template.strip() if not template: template = 'pass' - rule = Rule(non_term, tree, cost, template) + rule = Rule(non_term, tree, cost, acceptance, template) if len(tree.children) == 0 and tree.name not in self.terminals: self.non_term(tree.name).chain_rules.append(rule) self.non_term(rule.non_term) @@ -231,28 +231,35 @@ self.print() for rule in self.system.rules: if rule.num_nts > 0: - args = ', ' + ', '.join('nt{}'.format(x) for x in range(rule.num_nts)) + args = ', '.join('c{}'.format(x) for x in range(rule.num_nts)) + args = ', ' + args else: args = '' + # Create template function: self.print(' def P{}(self, tree{}):'.format(rule.nr, args)) template = rule.template - template = template.replace('$$', 'tree') - for i in range(rule.num_nts): - template = template.replace('${}'.format(i+1), 'nt{}'.format(i)) for t in template.split(';'): self.print(' {}'.format(t.strip())) + # Create acceptance function: + if rule.acceptance: + self.print(' def A{}(self, tree):'.format(rule.nr)) + for t in rule.acceptance.split(';'): + self.print(' {}'.format(t.strip())) self.emit_state() self.print(' def gen(self, tree):') self.print(' self.burm_label(tree)') self.print(' if not tree.state.has_goal("{}"):'.format(self.system.goal)) - self.print(' raise Exception("Tree {} not covered".format(tree))') + self.print(' raise Exception("Tree {} not covered".format(tree))') self.print(' return self.apply_rules(tree, "{}")'.format(self.system.goal)) def emit_record(self, rule, state_var): # TODO: check for rules fullfilled (by not using 999999) + acc = '' + if rule.acceptance: + acc = ' and self.A{}(tree)'.format(rule.nr) self.print(' nts = self.nts({})'.format(rule.nr)) self.print(' kids = self.kids(tree, {})'.format(rule.nr)) - self.print(' if all(x.state.has_goal(y) for x, y in zip(kids, nts)):') + self.print(' if all(x.state.has_goal(y) for x, y in zip(kids, nts)){}:'.format(acc)) self.print(' c = sum(x.state.get_cost(y) for x, y in zip(kids, nts)) + {}'.format(rule.cost)) self.print(' tree.state.set_cost("{}", c, {})'.format(rule.non_term, rule.nr)) for cr in self.system.symbols[rule.non_term].chain_rules: