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