Mercurial > lcfOS
comparison 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 |
comparison
equal
deleted
inserted
replaced
356:52492b304adf | 357:818be710e13d |
---|---|
74 def feed(self, txt): | 74 def feed(self, txt): |
75 tok_spec = [ | 75 tok_spec = [ |
76 ('id', r'[A-Za-z][A-Za-z\d_]*', lambda typ, val: (typ, val)), | 76 ('id', r'[A-Za-z][A-Za-z\d_]*', lambda typ, val: (typ, val)), |
77 ('kw', r'%[A-Za-z][A-Za-z\d_]*', lambda typ, val: (val, val)), | 77 ('kw', r'%[A-Za-z][A-Za-z\d_]*', lambda typ, val: (val, val)), |
78 ('number', r'\d+', lambda typ, val: (typ, int(val))), | 78 ('number', r'\d+', lambda typ, val: (typ, int(val))), |
79 ('STRING', r"'[^']*'", lambda typ, val: ('id', val[1:-1])), | 79 ('STRING', r"'[^']*'", lambda typ, val: ('string', val[1:-1])), |
80 ('template', r"\(\..*\.\)", lambda typ, val: (typ, val)), | |
81 ('OTHER', r'[:;\|\(\),]', lambda typ, val: (val, val)), | 80 ('OTHER', r'[:;\|\(\),]', lambda typ, val: (val, val)), |
82 ('SKIP', r'[ ]', None) | 81 ('SKIP', r'[ ]', None) |
83 ] | 82 ] |
84 | 83 |
85 lines = txt.split('\n') | 84 lines = txt.split('\n') |
113 | 112 |
114 | 113 |
115 class Rule: | 114 class Rule: |
116 """ A rewrite rule. Specifies a tree that can be rewritten into a result | 115 """ A rewrite rule. Specifies a tree that can be rewritten into a result |
117 at a specific cost """ | 116 at a specific cost """ |
118 def __init__(self, non_term, tree, cost, template): | 117 def __init__(self, non_term, tree, cost, acceptance, template): |
119 self.non_term = non_term | 118 self.non_term = non_term |
120 self.tree = tree | 119 self.tree = tree |
121 self.cost = cost | 120 self.cost = cost |
121 self.acceptance = acceptance | |
122 self.template = template | 122 self.template = template |
123 self.nr = 0 | 123 self.nr = 0 |
124 | 124 |
125 def __repr__(self): | 125 def __repr__(self): |
126 return '{} -> {} ${}'.format(self.non_term, self.tree, self.cost) | 126 return '{} -> {} ${}'.format(self.non_term, self.tree, self.cost) |
152 | 152 |
153 terminals = property(lambda s: s.symType(Term)) | 153 terminals = property(lambda s: s.symType(Term)) |
154 | 154 |
155 non_terminals = property(lambda s: s.symType(Nonterm)) | 155 non_terminals = property(lambda s: s.symType(Nonterm)) |
156 | 156 |
157 def add_rule(self, non_term, tree, cost, template): | 157 def add_rule(self, non_term, tree, cost, acceptance, template): |
158 template = template[2:-2].strip() | 158 template = template.strip() |
159 if not template: | 159 if not template: |
160 template = 'pass' | 160 template = 'pass' |
161 rule = Rule(non_term, tree, cost, template) | 161 rule = Rule(non_term, tree, cost, acceptance, template) |
162 if len(tree.children) == 0 and tree.name not in self.terminals: | 162 if len(tree.children) == 0 and tree.name not in self.terminals: |
163 self.non_term(tree.name).chain_rules.append(rule) | 163 self.non_term(tree.name).chain_rules.append(rule) |
164 self.non_term(rule.non_term) | 164 self.non_term(rule.non_term) |
165 self.rules.append(rule) | 165 self.rules.append(rule) |
166 rule.nr = len(self.rules) | 166 rule.nr = len(self.rules) |
229 self.print(' self.nts_map[{}] = {}'.format(rule.nr, dummy)) | 229 self.print(' self.nts_map[{}] = {}'.format(rule.nr, dummy)) |
230 self.print(' self.pat_f[{}] = {}'.format(rule.nr, pf)) | 230 self.print(' self.pat_f[{}] = {}'.format(rule.nr, pf)) |
231 self.print() | 231 self.print() |
232 for rule in self.system.rules: | 232 for rule in self.system.rules: |
233 if rule.num_nts > 0: | 233 if rule.num_nts > 0: |
234 args = ', ' + ', '.join('nt{}'.format(x) for x in range(rule.num_nts)) | 234 args = ', '.join('c{}'.format(x) for x in range(rule.num_nts)) |
235 args = ', ' + args | |
235 else: | 236 else: |
236 args = '' | 237 args = '' |
238 # Create template function: | |
237 self.print(' def P{}(self, tree{}):'.format(rule.nr, args)) | 239 self.print(' def P{}(self, tree{}):'.format(rule.nr, args)) |
238 template = rule.template | 240 template = rule.template |
239 template = template.replace('$$', 'tree') | |
240 for i in range(rule.num_nts): | |
241 template = template.replace('${}'.format(i+1), 'nt{}'.format(i)) | |
242 for t in template.split(';'): | 241 for t in template.split(';'): |
243 self.print(' {}'.format(t.strip())) | 242 self.print(' {}'.format(t.strip())) |
243 # Create acceptance function: | |
244 if rule.acceptance: | |
245 self.print(' def A{}(self, tree):'.format(rule.nr)) | |
246 for t in rule.acceptance.split(';'): | |
247 self.print(' {}'.format(t.strip())) | |
244 self.emit_state() | 248 self.emit_state() |
245 self.print(' def gen(self, tree):') | 249 self.print(' def gen(self, tree):') |
246 self.print(' self.burm_label(tree)') | 250 self.print(' self.burm_label(tree)') |
247 self.print(' if not tree.state.has_goal("{}"):'.format(self.system.goal)) | 251 self.print(' if not tree.state.has_goal("{}"):'.format(self.system.goal)) |
248 self.print(' raise Exception("Tree {} not covered".format(tree))') | 252 self.print(' raise Exception("Tree {} not covered".format(tree))') |
249 self.print(' return self.apply_rules(tree, "{}")'.format(self.system.goal)) | 253 self.print(' return self.apply_rules(tree, "{}")'.format(self.system.goal)) |
250 | 254 |
251 def emit_record(self, rule, state_var): | 255 def emit_record(self, rule, state_var): |
252 # TODO: check for rules fullfilled (by not using 999999) | 256 # TODO: check for rules fullfilled (by not using 999999) |
257 acc = '' | |
258 if rule.acceptance: | |
259 acc = ' and self.A{}(tree)'.format(rule.nr) | |
253 self.print(' nts = self.nts({})'.format(rule.nr)) | 260 self.print(' nts = self.nts({})'.format(rule.nr)) |
254 self.print(' kids = self.kids(tree, {})'.format(rule.nr)) | 261 self.print(' kids = self.kids(tree, {})'.format(rule.nr)) |
255 self.print(' if all(x.state.has_goal(y) for x, y in zip(kids, nts)):') | 262 self.print(' if all(x.state.has_goal(y) for x, y in zip(kids, nts)){}:'.format(acc)) |
256 self.print(' c = sum(x.state.get_cost(y) for x, y in zip(kids, nts)) + {}'.format(rule.cost)) | 263 self.print(' c = sum(x.state.get_cost(y) for x, y in zip(kids, nts)) + {}'.format(rule.cost)) |
257 self.print(' tree.state.set_cost("{}", c, {})'.format(rule.non_term, rule.nr)) | 264 self.print(' tree.state.set_cost("{}", c, {})'.format(rule.non_term, rule.nr)) |
258 for cr in self.system.symbols[rule.non_term].chain_rules: | 265 for cr in self.system.symbols[rule.non_term].chain_rules: |
259 self.print(' # Chain rule: {}'.format(cr)) | 266 self.print(' # Chain rule: {}'.format(cr)) |
260 self.print(' tree.state.set_cost("{}", c + {}, {})'.format(cr.non_term, cr.cost, cr.nr)) | 267 self.print(' tree.state.set_cost("{}", c + {}, {})'.format(cr.non_term, cr.cost, cr.nr)) |