Mercurial > lcfOS
comparison 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 |
comparison
equal
deleted
inserted
replaced
191:6b2bec5653f1 | 192:6cd6260789a1 |
---|---|
30 | 30 |
31 def add_production(self, name, symbols): | 31 def add_production(self, name, symbols): |
32 """ Add a production rule to the grammar """ | 32 """ Add a production rule to the grammar """ |
33 production = Production(name, symbols) | 33 production = Production(name, symbols) |
34 self.productions.append(production) | 34 self.productions.append(production) |
35 assert not name in self.terminals, "Cannot redefine terminal" | 35 if name in self.terminals: |
36 raise ParserGenerationException("Cannot redefine terminal {0}".format(name)) | |
36 if not name in self.nonterminals: | 37 if not name in self.nonterminals: |
37 self.nonterminals.append(name) | 38 self.nonterminals.append(name) |
38 | 39 |
39 def productionsForName(self, name): | 40 def productionsForName(self, name): |
40 """ Retrieve all productions for a non terminal """ | 41 """ Retrieve all productions for a non terminal """ |
148 if not nis: | 149 if not nis: |
149 continue | 150 continue |
150 addSt(nis) | 151 addSt(nis) |
151 transitions[(states.index(itemset), symbol)] = states.index(nis) | 152 transitions[(states.index(itemset), symbol)] = states.index(nis) |
152 return states, transitions | 153 return states, transitions |
153 | 154 |
155 def checkSymbols(self): | |
156 """ Checks no symbols are undefined """ | |
157 for production in self.productions: | |
158 for symbol in production.symbols: | |
159 if symbol not in self.Symbols: | |
160 raise ParserGenerationException('Symbol {0} undefined'.format(symbol)) | |
161 | |
162 | |
154 def genParser(self): | 163 def genParser(self): |
155 """ Generates a parser from the grammar """ | 164 """ Generates a parser from the grammar """ |
165 self.checkSymbols() | |
156 action_table = {} | 166 action_table = {} |
157 goto_table = {} | 167 goto_table = {} |
158 iis = self.initialItemSet() | 168 iis = self.initialItemSet() |
159 | 169 |
160 # First generate all item sets by using the nextItemset function: | 170 # First generate all item sets by using the nextItemset function: |
301 look_ahead = Token(EOF, EOF, 0) | 311 look_ahead = Token(EOF, EOF, 0) |
302 assert type(look_ahead) is Token | 312 assert type(look_ahead) is Token |
303 elif action == ACCEPT: | 313 elif action == ACCEPT: |
304 break | 314 break |
305 | 315 |
316 | |
306 def testSimpleGrammar(): | 317 def testSimpleGrammar(): |
307 # 1. define a simple grammar: | 318 # 1. define a simple grammar: |
308 g = Grammar(['EOF', 'identifier', '(', ')', '+', '*']) | 319 g = Grammar(['EOF', 'identifier', '(', ')', '+', '*']) |
309 g.add_production('input', ['expression']) | 320 g.add_production('input', ['expression']) |
310 g.add_production('expression', ['term']) | 321 g.add_production('expression', ['term']) |
313 g.add_production('term', ['term', '*', 'factor']) | 324 g.add_production('term', ['term', '*', 'factor']) |
314 g.add_production('factor', ['(', 'expression', ')']) | 325 g.add_production('factor', ['(', 'expression', ')']) |
315 g.add_production('factor', ['identifier']) | 326 g.add_production('factor', ['identifier']) |
316 g.start_symbol = 'input' | 327 g.start_symbol = 'input' |
317 # 2. define input: | 328 # 2. define input: |
318 tokens = ['identifier', '+', 'identifier', '+', 'identifier', 'EOF'] | 329 tokens = ['identifier', '+', 'identifier', '+', 'identifier'] |
319 # 3. build parser: | 330 # 3. build parser: |
320 p = g.genParser() | 331 p = g.genParser() |
321 # 4. feed input: | 332 # 4. feed input: |
322 p.parse(tokens) | 333 def genTokens(lst): |
334 for t in lst: | |
335 yield Token(t, t, 0) | |
336 p.parse(genTokens(tokens)) | |
323 | 337 |
324 | 338 |
325 if __name__ == '__main__': | 339 if __name__ == '__main__': |
326 testSimpleGrammar() | 340 testSimpleGrammar() |
341 |