Mercurial > lcfOS
diff python/pyyacc.py @ 218:494828a7adf1
added some sort of cache to assembler
author | Windel Bouwman |
---|---|
date | Fri, 05 Jul 2013 15:30:22 +0200 |
parents | 37ac6c016e0f |
children | 6259856841a0 |
line wrap: on
line diff
--- a/python/pyyacc.py Fri Jul 05 14:13:59 2013 +0200 +++ b/python/pyyacc.py Fri Jul 05 15:30:22 2013 +0200 @@ -2,6 +2,8 @@ Parser generator script """ +import shelve +import hashlib from ppci import Token EPS = 'EPS' @@ -160,9 +162,30 @@ if symbol not in self.Symbols + [EPS]: raise ParserGenerationException('Symbol {0} undefined'.format(symbol)) - + def getSignature(self): + m = hashlib.md5() + m.update((str(self.productions) + str(self.start_symbol)).encode('ascii')) + signature = m.hexdigest() + def genParser(self): - """ Generates a parser from the grammar """ + """ Generates a parser from the grammar (using a caching algorithm) """ + signature = self.getSignature() + cache = shelve.open('__grammar_cache__.shelve') + # TODO: fix caching. + if ('signature1' in cache) and cache['signature'] == signature: + goto_table = cache['goto_table'] + action_table = cache['action_table'] + else: + action_table, goto_table = self.doGenerate() + cache['goto_table'] = goto_table + cache['action_table'] = action_table + cache['signature'] = signature + cache.close() + p = LRParser(action_table, goto_table, self.start_symbol) + p.grammar = self + return p + + def doGenerate(self): self.checkSymbols() action_table = {} goto_table = {} @@ -181,6 +204,8 @@ def setAction(state, t, action): key = (state, t) + assert type(state) is int + assert type(t) is str if key in action_table: action2 = action_table[key] if action != action2: @@ -209,16 +234,15 @@ if item.IsReduce: if item.production.name == self.start_symbol and item.look_ahead == EOF: # Rule 3: accept: - setAction(states.index(state), item.look_ahead, (ACCEPT, item.production)) + setAction(states.index(state), item.look_ahead, (ACCEPT, self.productions.index(item.production))) else: # Rule 2, reduce item: - setAction(states.index(state), item.look_ahead, (REDUCE, item.production)) + setAction(states.index(state), item.look_ahead, (REDUCE, self.productions.index(item.production))) for nt in self.nonterminals: key = (states.index(state), nt) if key in transitions: goto_table[key] = transitions[key] - - return LRParser(action_table, goto_table, self.start_symbol) + return action_table, goto_table class Production: @@ -324,6 +348,7 @@ action, param = self.action_table[key] if action == REDUCE: f_args = [] + param = self.grammar.productions[param] for s in param.symbols: stack.pop() stack.pop() @@ -348,6 +373,7 @@ elif action == ACCEPT: # Pop last rule data off the stack: f_args = [] + param = self.grammar.productions[param] for s in param.symbols: stack.pop() stack.pop()