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()
+