Mercurial > lcfOS
diff python/pyyacc.py @ 192:6cd6260789a1
Added more tests for parser generator
author | Windel Bouwman |
---|---|
date | Sun, 26 May 2013 23:19:27 +0200 |
parents | 6b2bec5653f1 |
children | b01429a5d695 |
line wrap: on
line diff
--- a/python/pyyacc.py Sun May 26 15:28:07 2013 +0200 +++ b/python/pyyacc.py Sun May 26 23:19:27 2013 +0200 @@ -32,7 +32,8 @@ """ Add a production rule to the grammar """ production = Production(name, symbols) self.productions.append(production) - assert not name in self.terminals, "Cannot redefine terminal" + if name in self.terminals: + raise ParserGenerationException("Cannot redefine terminal {0}".format(name)) if not name in self.nonterminals: self.nonterminals.append(name) @@ -150,9 +151,18 @@ addSt(nis) transitions[(states.index(itemset), symbol)] = states.index(nis) return states, transitions - + + def checkSymbols(self): + """ Checks no symbols are undefined """ + for production in self.productions: + for symbol in production.symbols: + if symbol not in self.Symbols: + raise ParserGenerationException('Symbol {0} undefined'.format(symbol)) + + def genParser(self): """ Generates a parser from the grammar """ + self.checkSymbols() action_table = {} goto_table = {} iis = self.initialItemSet() @@ -303,6 +313,7 @@ elif action == ACCEPT: break + def testSimpleGrammar(): # 1. define a simple grammar: g = Grammar(['EOF', 'identifier', '(', ')', '+', '*']) @@ -315,12 +326,16 @@ g.add_production('factor', ['identifier']) g.start_symbol = 'input' # 2. define input: - tokens = ['identifier', '+', 'identifier', '+', 'identifier', 'EOF'] + tokens = ['identifier', '+', 'identifier', '+', 'identifier'] # 3. build parser: p = g.genParser() # 4. feed input: - p.parse(tokens) + def genTokens(lst): + for t in lst: + yield Token(t, t, 0) + p.parse(genTokens(tokens)) if __name__ == '__main__': testSimpleGrammar() +