Mercurial > lcfOS
comparison python/testpyy.py @ 185:51a6440d6398
Fixed LR(1) parser
author | Windel Bouwman |
---|---|
date | Fri, 24 May 2013 20:45:03 +0200 |
parents | fe2b72381a83 |
children | 6b2bec5653f1 |
comparison
equal
deleted
inserted
replaced
184:fe2b72381a83 | 185:51a6440d6398 |
---|---|
22 # 3. build parser: | 22 # 3. build parser: |
23 p = g.genParser() | 23 p = g.genParser() |
24 # 4. feed input: | 24 # 4. feed input: |
25 p.parse(tokens) | 25 p.parse(tokens) |
26 | 26 |
27 class testExpressionGrammar(unittest.TestCase): | |
28 def setUp(self): | |
29 g = Grammar(['EOF', 'identifier', '(', ')', '+', '*', 'num']) | |
30 g.add_production('input', ['expression']) | |
31 g.add_production('expression', ['term']) | |
32 g.add_production('expression', ['expression', '+', 'term']) | |
33 g.add_production('term', ['factor']) | |
34 g.add_production('term', ['term', '*', 'factor']) | |
35 g.add_production('factor', ['(', 'expression', ')']) | |
36 g.add_production('factor', ['identifier']) | |
37 g.add_production('factor', ['num']) | |
38 g.start_symbol = 'input' | |
39 self.g = g | |
40 | |
41 def testFirstSimpleGrammar(self): | |
42 # 1. define a simple grammar: | |
43 first = self.g.calcFirstSets() | |
44 self.assertEqual(first['input'], {'identifier', '(', 'num'}) | |
45 self.assertEqual(first['term'], {'identifier', '(', 'num'}) | |
46 | |
47 def testCanonical(self): | |
48 s0 = self.g.initialItemSet() | |
49 s, gt = self.g.genCanonicalSet(s0) | |
50 # Must result in 12 sets: | |
51 self.assertEqual(len(s), 24) | |
52 | |
27 class testPG(unittest.TestCase): | 53 class testPG(unittest.TestCase): |
28 """ Tests several parts of the parser generator """ | 54 """ Tests several parts of the parser generator """ |
29 def setUp(self): | 55 def setUp(self): |
30 g = Grammar(['(', ')']) | 56 g = Grammar(['(', ')']) |
31 g.add_production('goal', ['list']) | 57 g.add_production('goal', ['list']) |
32 g.add_production('list', ['list', 'pair']) | 58 g.add_production('list', ['list', 'pair']) |
33 g.add_production('list', ['pair']) | 59 g.add_production('list', ['pair']) |
34 g.add_production('pair', ['(', 'pair', ')']) | 60 g.add_production('pair', ['(', 'pair', ')']) |
35 g.add_production('pair', ['(', ')']) | 61 g.add_production('pair', ['(', ')']) |
36 g.start_symbol = 'goal' | 62 g.start_symbol = 'goal' |
37 g.first = g.calcFirstSets() | |
38 self.g = g | 63 self.g = g |
39 | 64 |
40 def testFirstSet(self): | 65 def testFirstSet(self): |
41 for a in ['(', ')', EOF, 'EPS']: | 66 for a in ['(', ')', EOF, 'EPS']: |
42 self.assertEqual(self.g.first[a], {a}) | 67 self.assertEqual(self.g.first[a], {a}) |
58 self.assertIn(Item(p4, 0, '('), s0) | 83 self.assertIn(Item(p4, 0, '('), s0) |
59 | 84 |
60 def testCanonical(self): | 85 def testCanonical(self): |
61 s0 = self.g.initialItemSet() | 86 s0 = self.g.initialItemSet() |
62 s, gt = self.g.genCanonicalSet(s0) | 87 s, gt = self.g.genCanonicalSet(s0) |
63 pprint.pprint(s) | |
64 # Must result in 12 sets: | 88 # Must result in 12 sets: |
65 self.assertEqual(len(s), 12) | 89 self.assertEqual(len(s), 12) |
66 | 90 |
67 def testClosure(self): | 91 def testClosure(self): |
68 p0, p1, p2, p3, p4 = self.g.productions | 92 p0, p1, p2, p3, p4 = self.g.productions |
69 s0 = set() | 93 s0 = set() |
70 for p in self.g.productionsForName(self.g.start_symbol): | 94 s0.add(Item(p0, 0, EOF)) |
71 s0.add(Item(p, 0, EOF)) | |
72 self.assertEqual(len(s0), 1) # 1 rule | 95 self.assertEqual(len(s0), 1) # 1 rule |
73 self.assertIn(Item(p0, 0, EOF), s0) | 96 self.assertIn(Item(p0, 0, EOF), s0) |
74 | 97 |
75 # Invoke closure on set: | 98 # Invoke closure on set: |
76 s0 = self.g.closure(s0) | 99 s0 = self.g.closure(s0) |
83 self.assertIn(Item(p3, 0, '('), s0) | 106 self.assertIn(Item(p3, 0, '('), s0) |
84 self.assertIn(Item(p4, 0, EOF), s0) | 107 self.assertIn(Item(p4, 0, EOF), s0) |
85 self.assertIn(Item(p4, 0, '('), s0) | 108 self.assertIn(Item(p4, 0, '('), s0) |
86 | 109 |
87 def testParser(self): | 110 def testParser(self): |
88 tokens = ['(', '(', ')', '(', ')', ')', 'EOF'] | 111 tokens = ['(', '(', ')', ')', '(', ')', EOF] |
89 # 3. build parser: | 112 # 3. build parser: |
90 p = self.g.genParser() | 113 p = self.g.genParser() |
114 self.assertEqual(len(p.goto_table), 5) | |
115 self.assertEqual(len(p.action_table), 19) | |
116 | |
91 # 4. feed input: | 117 # 4. feed input: |
92 p.parse(tokens) | 118 p.parse(tokens) |
93 | 119 |
94 if __name__ == '__main__': | 120 if __name__ == '__main__': |
95 unittest.main() | 121 unittest.main() |