Mercurial > lcfOS
comparison python/testpyy.py @ 194:b01429a5d695
Fixed test
author | Windel Bouwman |
---|---|
date | Wed, 29 May 2013 22:36:37 +0200 |
parents | 6cd6260789a1 |
children | 37ac6c016e0f |
comparison
equal
deleted
inserted
replaced
193:f091e7d70996 | 194:b01429a5d695 |
---|---|
1 import unittest, pprint | 1 import unittest, pprint |
2 from pyyacc import Grammar, Item, EOF, ParserGenerationException | 2 from pyyacc import Grammar, Item, ParserGenerationException, ParserException, EPS, EOF |
3 from ppci import Token | 3 from ppci import Token |
4 | 4 |
5 def genTokens(lst): | 5 def genTokens(lst): |
6 for t in lst: | 6 for t in lst: |
7 yield Token(t, t, 0) | 7 yield Token(t, t) |
8 | 8 |
9 class testLR(unittest.TestCase): | 9 class testLR(unittest.TestCase): |
10 def setUp(self): | 10 """ Test basic LR(1) parser generator constructs """ |
11 pass | |
12 | |
13 def testSimpleGrammar(self): | 11 def testSimpleGrammar(self): |
14 # 1. define a simple grammar: | 12 # 1. define a simple grammar: |
15 g = Grammar(['EOF', 'identifier', '(', ')', '+', '*']) | 13 g = Grammar(['identifier', '(', ')', '+', '*']) |
16 g.add_production('input', ['expression']) | 14 g.add_production('input', ['expression']) |
17 g.add_production('expression', ['term']) | 15 g.add_production('expression', ['term']) |
18 g.add_production('expression', ['expression', '+', 'term']) | 16 g.add_production('expression', ['expression', '+', 'term']) |
19 g.add_production('term', ['factor']) | 17 g.add_production('term', ['factor']) |
20 g.add_production('term', ['term', '*', 'factor']) | 18 g.add_production('term', ['term', '*', 'factor']) |
28 # 4. feed input: | 26 # 4. feed input: |
29 p.parse(tokens) | 27 p.parse(tokens) |
30 def testReduceReduceConflict(self): | 28 def testReduceReduceConflict(self): |
31 """ Check if a reduce-reduce conflict is detected """ | 29 """ Check if a reduce-reduce conflict is detected """ |
32 # Define a grammar with an obvious reduce-reduce conflict: | 30 # Define a grammar with an obvious reduce-reduce conflict: |
33 g = Grammar([EOF, 'id']) | 31 g = Grammar(['id']) |
34 g.add_production('goal', ['a']) | 32 g.add_production('goal', ['a']) |
35 g.add_production('a', ['b']) | 33 g.add_production('a', ['b']) |
36 g.add_production('a', ['c']) | 34 g.add_production('a', ['c']) |
37 g.add_production('b', ['id']) | 35 g.add_production('b', ['id']) |
38 g.add_production('c', ['id']) | 36 g.add_production('c', ['id']) |
39 g.start_symbol = 'goal' | 37 g.start_symbol = 'goal' |
40 with self.assertRaises(ParserGenerationException): | 38 with self.assertRaises(ParserGenerationException): |
41 p = g.genParser() | 39 p = g.genParser() |
42 def testShiftReduceConflict(self): | 40 def testShiftReduceConflict(self): |
43 g = Grammar([EOF, 'if', 'then', 'else']) | 41 """ Must be handled automatically by doing shift """ |
44 g.add_production('if_stmt', ['if', 'then']) | 42 g = Grammar([EOF, 'if', 'then', 'else', 'ass']) |
45 g.add_production('if_stmt', ['if', 'then', 'else']) | 43 # Ambiguous grammar: |
46 g.add_production('stmt', ['if_stmt', 'else']) | 44 g.add_production('if_stmt', ['if', 'then', 'stmt']) |
45 g.add_production('if_stmt', ['if', 'then', 'stmt', 'else', 'stmt']) | |
46 g.add_production('stmt', ['if_stmt']) | |
47 g.add_production('stmt', ['ass']) | |
47 g.start_symbol = 'stmt' | 48 g.start_symbol = 'stmt' |
48 with self.assertRaises(ParserGenerationException): | 49 p = g.genParser() |
49 g.genParser() | 50 # Ambiguous program: |
51 tokens = genTokens(['if', 'then','if', 'then', 'ass', 'else', 'ass' ]) | |
52 p.parse(tokens) | |
53 | |
50 def testUndefinedTerminal(self): | 54 def testUndefinedTerminal(self): |
51 """ Test correct behavior when a terminal is undefined """ | 55 """ Test correct behavior when a terminal is undefined """ |
52 g = Grammar([EOF, 'b']) | 56 g = Grammar(['b']) |
53 g.add_production('goal', ['a']) | 57 g.add_production('goal', ['a']) |
54 g.add_production('a', ['b']) | 58 g.add_production('a', ['b']) |
55 g.add_production('a', ['c']) | 59 g.add_production('a', ['c']) |
56 g.start_symbol = 'goal' | 60 g.start_symbol = 'goal' |
57 with self.assertRaises(ParserGenerationException): | 61 with self.assertRaises(ParserGenerationException): |
63 with self.assertRaises(ParserGenerationException): | 67 with self.assertRaises(ParserGenerationException): |
64 g.add_production('b', ['c']) # Not allowed | 68 g.add_production('b', ['c']) # Not allowed |
65 g.add_production('a', ['c']) | 69 g.add_production('a', ['c']) |
66 g.start_symbol = 'goal' | 70 g.start_symbol = 'goal' |
67 g.genParser() | 71 g.genParser() |
72 def testEmpty(self): | |
73 """ Test empty token stream """ | |
74 g = Grammar([',']) | |
75 g.add_production('input', [',']) | |
76 g.start_symbol = 'input' | |
77 p = g.genParser() | |
78 tokens = genTokens([]) | |
79 with self.assertRaises(ParserException): | |
80 p.parse(tokens) | |
81 | |
82 def testEps(self): | |
83 """ Test epsilon terminal """ | |
84 g = Grammar(['a', 'b']) | |
85 g.add_production('input', ['optional_a', 'b']) | |
86 g.add_production('optional_a', ['a']) | |
87 g.add_production('optional_a', []) | |
88 g.start_symbol = 'input' | |
89 p = g.genParser() | |
90 tokens = genTokens(['b']) | |
91 p.parse(tokens) | |
92 | |
93 def testEps2(self): | |
94 g = Grammar(['id', ':']) | |
95 g.add_production('input', ['opt_lab', 'ins', 'op1']) | |
96 g.add_production('input', ['ins', 'op1']) | |
97 g.add_production('opt_lab', ['id', ':']) | |
98 g.add_production('ins', ['id']) | |
99 g.add_production('op1', ['id']) | |
100 g.start_symbol = 'input' | |
101 p = g.genParser() | |
102 tokens = genTokens(['id', ':', 'id', 'id']) # i.e. "lab_0: inc rax" | |
103 p.parse(tokens) | |
104 tokens = genTokens(['id', 'id']) # i.e. "inc rax" | |
105 p.parse(tokens) | |
106 | |
68 | 107 |
69 class testExpressionGrammar(unittest.TestCase): | 108 class testExpressionGrammar(unittest.TestCase): |
70 def setUp(self): | 109 def setUp(self): |
71 g = Grammar(['EOF', 'identifier', '(', ')', '+', '*', 'num']) | 110 g = Grammar(['EOF', 'identifier', '(', ')', '+', '*', 'num']) |
72 g.add_production('input', ['expression']) | 111 g.add_production('input', ['expression']) |