1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport unittest
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport textwrap
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport antlr3
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport antlr3.tree
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport testbase
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport sys
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass TestRewriteAST(testbase.ANTLRTest):
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def parserClass(self, base):
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        class TParser(base):
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            def __init__(self, *args, **kwargs):
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                base.__init__(self, *args, **kwargs)
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                self._errors = []
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                self._output = ""
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            def capture(self, t):
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                self._output += t
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            def traceIn(self, ruleName, ruleIndex):
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                self.traces.append('>'+ruleName)
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            def traceOut(self, ruleName, ruleIndex):
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                self.traces.append('<'+ruleName)
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            def emitErrorMessage(self, msg):
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                self._errors.append(msg)
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return TParser
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def lexerClass(self, base):
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        class TLexer(base):
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            def __init__(self, *args, **kwargs):
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                base.__init__(self, *args, **kwargs)
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                self._output = ""
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            def capture(self, t):
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                self._output += t
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            def traceIn(self, ruleName, ruleIndex):
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                self.traces.append('>'+ruleName)
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            def traceOut(self, ruleName, ruleIndex):
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                self.traces.append('<'+ruleName)
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            def recover(self, input, re):
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                # no error recovery yet, just crash!
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                raise
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return TLexer
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def execParser(self, grammar, grammarEntry, input, expectErrors=False):
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        lexerCls, parserCls = self.compileInlineGrammar(grammar)
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        cStream = antlr3.StringStream(input)
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        lexer = lexerCls(cStream)
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        tStream = antlr3.CommonTokenStream(lexer)
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        parser = parserCls(tStream)
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        r = getattr(parser, grammarEntry)()
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if not expectErrors:
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.assertEquals(len(parser._errors), 0, parser._errors)
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        result = ""
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if r is not None:
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if hasattr(r, 'result'):
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                result += r.result
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if r.tree is not None:
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                result += r.tree.toStringTree()
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if not expectErrors:
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return result
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else:
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return result, parser._errors
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def execTreeParser(self, grammar, grammarEntry, treeGrammar, treeEntry, input):
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        lexerCls, parserCls = self.compileInlineGrammar(grammar)
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        walkerCls = self.compileInlineGrammar(treeGrammar)
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        cStream = antlr3.StringStream(input)
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        lexer = lexerCls(cStream)
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        tStream = antlr3.CommonTokenStream(lexer)
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        parser = parserCls(tStream)
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        r = getattr(parser, grammarEntry)()
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        nodes = antlr3.tree.CommonTreeNodeStream(r.tree)
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        nodes.setTokenStream(tStream)
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        walker = walkerCls(nodes)
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        r = getattr(walker, treeEntry)()
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if r is not None:
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return r.tree.toStringTree()
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return ""
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testDelete(self):
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID INT -> ;
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "abc 34")
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("", found)
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testSingleToken(self):
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID -> ID;
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "abc")
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("abc", found)
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testSingleTokenToNewNode(self):
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID -> ID["x"];
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "abc")
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("x", found)
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testSingleTokenToNewNodeRoot(self):
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID -> ^(ID["x"] INT);
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "abc")
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(x INT)", found)
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testSingleTokenToNewNode2(self):
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # Allow creation of new nodes w/o args.
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar TT;
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID -> ID[ ];
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "abc")
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("ID", found)
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testSingleCharLiteral(self):
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : 'c' -> 'c';
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "c")
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("c", found)
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testSingleStringLiteral(self):
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : 'ick' -> 'ick';
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "ick")
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("ick", found)
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testSingleRule(self):
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : b -> b;
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "abc")
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("abc", found)
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testReorderTokens(self):
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID INT -> INT ID;
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "abc 34")
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("34 abc", found)
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testReorderTokenAndRule(self):
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : b INT -> INT b;
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "abc 34")
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("34 abc", found)
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testTokenTree(self):
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID INT -> ^(INT ID);
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "abc 34")
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(34 abc)", found)
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testTokenTreeAfterOtherStuff(self):
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : 'void' ID INT -> 'void' ^(INT ID);
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "void abc 34")
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("void (34 abc)", found)
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testNestedTokenTreeWithOuterLoop(self):
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # verify that ID and INT both iterate over outer index variable
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {DUH;}
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID INT ID INT -> ^( DUH ID ^( DUH INT) )+ ;
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a 1 b 2")
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(DUH a (DUH 1)) (DUH b (DUH 2))", found)
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testOptionalSingleToken(self):
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID -> ID? ;
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "abc")
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("abc", found)
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testClosureSingleToken(self):
328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID ID -> ID* ;
333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a b")
339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a b", found)
340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testPositiveClosureSingleToken(self):
343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID ID -> ID+ ;
348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a b")
354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a b", found)
355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testOptionalSingleRule(self):
358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : b -> b?;
363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "abc")
370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("abc", found)
371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testClosureSingleRule(self):
374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : b b -> b*;
379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a b")
386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a b", found)
387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testClosureOfLabel(self):
390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : x+=b x+=b -> $x*;
395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a b")
402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a b", found)
403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testOptionalLabelNoListLabel(self):
406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : (x=ID)? -> $x?;
411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a")
417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a", found)
418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testPositiveClosureSingleRule(self):
421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : b b -> b+;
426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a b")
433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a b", found)
434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testSinglePredicateT(self):
437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID -> {True}? ID -> ;
442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "abc")
448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("abc", found)
449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testSinglePredicateF(self):
452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID -> {False}? ID -> ;
457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "abc")
463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("", found)
464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testMultiplePredicate(self):
467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID INT -> {False}? ID
472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                       -> {True}? INT
473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                       ->
474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              ;
475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a 2")
481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("2", found)
482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testMultiplePredicateTrees(self):
485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID INT -> {False}? ^(ID INT)
490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                       -> {True}? ^(INT ID)
491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                       -> ID
492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              ;
493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a 2")
499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(2 a)", found)
500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testSimpleTree(self):
503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : op INT -> ^(op INT);
508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            op : '+'|'-' ;
509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "-34")
515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(- 34)", found)
516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testSimpleTree2(self):
519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : op INT -> ^(INT op);
524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            op : '+'|'-' ;
525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "+ 34")
531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(34 +)", found)
532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testNestedTrees(self):
536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : 'var' (ID ':' type ';')+ -> ^('var' ^(':' ID type)+) ;
541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            type : 'int' | 'float' ;
542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "var a:int; b:float;")
548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(var (: a int) (: b float))", found)
549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testImaginaryTokenCopy(self):
552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {VAR;}
557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID (',' ID)*-> ^(VAR ID)+ ;
558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            type : 'int' | 'float' ;
559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a,b,c")
565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(VAR a) (VAR b) (VAR c)", found)
566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testTokenUnreferencedOnLeftButDefined(self):
569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {VAR;}
574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : b -> ID ;
575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a")
582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("ID", found)
583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testImaginaryTokenCopySetText(self):
586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {VAR;}
591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID (',' ID)*-> ^(VAR["var"] ID)+ ;
592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            type : 'int' | 'float' ;
593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a,b,c")
599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(var a) (var b) (var c)", found)
600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testImaginaryTokenNoCopyFromToken(self):
603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ;
609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            type : 'int' | 'float' ;
610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "{a b c}")
616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("({ a b c)", found)
617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testImaginaryTokenNoCopyFromTokenSetText(self):
620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : lc='{' ID+ '}' -> ^(BLOCK[$lc,"block"] ID+) ;
626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            type : 'int' | 'float' ;
627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "{a b c}")
633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(block a b c)", found)
634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testMixedRewriteAndAutoAST(self):
637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : b b^ ; // 2nd b matches only an INT; can make it root
643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID INT -> INT ID
644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              | INT
645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              ;
646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a 1 2")
652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(2 1 a)", found)
653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testSubruleWithRewrite(self):
656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : b b ;
662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : (ID INT -> INT ID | INT INT -> INT+ )
663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              ;
664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a 1 2 3")
670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("1 a 2 3", found)
671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testSubruleWithRewrite2(self):
674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {TYPE;}
679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : b b ;
680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : 'int'
681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                ( ID -> ^(TYPE 'int' ID)
682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                | ID '=' INT -> ^(TYPE 'int' ID INT)
683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                )
684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                ';'
685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              ;
686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "int a; int b=3;")
692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(TYPE int a) (TYPE int b 3)", found)
693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testNestedRewriteShutsOffAutoAST(self):
696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : b b ;
702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ( ID (last=ID -> $last)+ ) ';' // get last ID
703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              | INT // should still get auto AST construction
704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              ;
705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a b c d; 42")
711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("d 42", found)
712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testRewriteActions(self):
715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : atom -> ^({self.adaptor.create(INT,"9")} atom) ;
720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            atom : INT ;
721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "3")
727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(9 3)", found)
728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testRewriteActions2(self):
731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : atom -> {self.adaptor.create(INT,"9")} atom ;
736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            atom : INT ;
737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "3")
743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("9 3", found)
744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testRefToOldValue(self):
747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
751324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : (atom -> atom) (op='+' r=atom -> ^($op $a $r) )* ;
753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            atom : INT ;
754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "3+4+5")
760324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(+ (+ 3 4) 5)", found)
761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testCopySemanticsForRules(self):
764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
766324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
767324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
768324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : atom -> ^(atom atom) ; // NOT CYCLE! (dup atom)
770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            atom : INT ;
771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "3")
777324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(3 3)", found)
778324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
779324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
780324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testCopySemanticsForRules2(self):
781324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # copy type as a root for each invocation of (...)+ in rewrite
782324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
783324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
784324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
785324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
786324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : type ID (',' ID)* ';' -> ^(type ID)+ ;
787324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            type : 'int' ;
788324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
789324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
790324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
791324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
792324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "int a,b,c;")
793324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(int a) (int b) (int c)", found)
794324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
795324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
796324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testCopySemanticsForRules3(self):
797324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # copy type *and* modifier even though it's optional
798324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # for each invocation of (...)+ in rewrite
799324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
800324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
801324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
802324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
803324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : modifier? type ID (',' ID)* ';' -> ^(type modifier? ID)+ ;
804324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            type : 'int' ;
805324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            modifier : 'public' ;
806324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
807324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
808324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
809324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
810324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "public int a,b,c;")
811324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(int public a) (int public b) (int public c)", found)
812324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
813324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
814324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testCopySemanticsForRules3Double(self):
815324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # copy type *and* modifier even though it's optional
816324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # for each invocation of (...)+ in rewrite
817324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
818324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
819324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
820324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
821324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : modifier? type ID (',' ID)* ';' -> ^(type modifier? ID)+ ^(type modifier? ID)+ ;
822324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            type : 'int' ;
823324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            modifier : 'public' ;
824324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
825324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
826324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
827324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
828324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "public int a,b,c;")
829324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(int public a) (int public b) (int public c) (int public a) (int public b) (int public c)", found)
830324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
831324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
832324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testCopySemanticsForRules4(self):
833324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # copy type *and* modifier even though it's optional
834324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # for each invocation of (...)+ in rewrite
835324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
836324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
837324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
838324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
839324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {MOD;}
840324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : modifier? type ID (',' ID)* ';' -> ^(type ^(MOD modifier)? ID)+ ;
841324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            type : 'int' ;
842324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            modifier : 'public' ;
843324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
844324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
845324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
846324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
847324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "public int a,b,c;")
848324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(int (MOD public) a) (int (MOD public) b) (int (MOD public) c)", found)
849324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
850324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
851324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testCopySemanticsLists(self):
852324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
853324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
854324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
855324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
856324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {MOD;}
857324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID (',' ID)* ';' -> ID+ ID+ ;
858324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
859324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
860324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
861324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
862324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a,b,c;")
863324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a b c a b c", found)
864324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
865324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
866324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testCopyRuleLabel(self):
867324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
868324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
869324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
870324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
871324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
872324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : x=b -> $x $x;
873324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
874324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
875324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
876324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
877324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
878324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a")
879324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a a", found)
880324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
881324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
882324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testCopyRuleLabel2(self):
883324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
884324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
885324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
886324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
887324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
888324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : x=b -> ^($x $x);
889324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
890324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
891324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
892324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
893324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
894324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a")
895324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(a a)", found)
896324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
897324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
898324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testQueueingOfTokens(self):
899324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
900324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
901324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
902324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
903324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : 'int' ID (',' ID)* ';' -> ^('int' ID+) ;
904324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            op : '+'|'-' ;
905324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
906324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
907324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
908324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
909324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
910324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "int a,b,c;")
911324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(int a b c)", found)
912324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
913324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
914324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testCopyOfTokens(self):
915324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
916324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
917324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
918324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
919324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : 'int' ID ';' -> 'int' ID 'int' ID ;
920324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            op : '+'|'-' ;
921324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
922324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
923324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
924324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
925324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
926324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "int a;")
927324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("int a int a", found)
928324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
929324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
930324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testTokenCopyInLoop(self):
931324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
932324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
933324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
934324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
935324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : 'int' ID (',' ID)* ';' -> ^('int' ID)+ ;
936324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            op : '+'|'-' ;
937324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
938324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
939324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
940324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
941324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
942324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "int a,b,c;")
943324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(int a) (int b) (int c)", found)
944324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
945324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
946324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testTokenCopyInLoopAgainstTwoOthers(self):
947324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # must smear 'int' copies across as root of multiple trees
948324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
949324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
950324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
951324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
952324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : 'int' ID ':' INT (',' ID ':' INT)* ';' -> ^('int' ID INT)+ ;
953324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            op : '+'|'-' ;
954324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
955324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
956324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
957324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
958324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
959324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "int a:1,b:2,c:3;")
960324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(int a 1) (int b 2) (int c 3)", found)
961324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
962324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
963324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testListRefdOneAtATime(self):
964324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
965324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
966324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
967324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
968324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID+ -> ID ID ID ; // works if 3 input IDs
969324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            op : '+'|'-' ;
970324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
971324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
972324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
973324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
974324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
975324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a b c")
976324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a b c", found)
977324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
978324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
979324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testSplitListWithLabels(self):
980324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
981324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
982324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
983324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
984324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {VAR;}
985324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : first=ID others+=ID* -> $first VAR $others+ ;
986324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            op : '+'|'-' ;
987324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
988324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
989324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
990324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
991324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
992324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a b c")
993324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a VAR b c", found)
994324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
995324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
996324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testComplicatedMelange(self):
997324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
998324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
999324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1000324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1001324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
1002324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : A A b=B B b=B c+=C C c+=C D {s=$D.text} -> A+ B+ C+ D ;
1003324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            type : 'int' | 'float' ;
1004324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            A : 'a' ;
1005324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            B : 'b' ;
1006324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            C : 'c' ;
1007324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            D : 'd' ;
1008324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1009324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1010324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1011324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a a b b b c c c d")
1012324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a a b b b c c c d", found)
1013324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1014324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1015324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testRuleLabel(self):
1016324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1017324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1018324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1019324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1020324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
1021324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : x=b -> $x;
1022324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
1023324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1024324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1025324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1026324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1027324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a")
1028324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a", found)
1029324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1030324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1031324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testAmbiguousRule(self):
1032324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1033324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1034324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1035324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1036324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID a -> a | INT ;
1037324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1038324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT: '0'..'9'+ ;
1039324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1040324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1041324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1042324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar,
1043324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    "a", "abc 34")
1044324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("34", found)
1045324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1046324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1047324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testRuleListLabel(self):
1048324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1049324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1050324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1051324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1052324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
1053324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : x+=b x+=b -> $x+;
1054324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
1055324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1056324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1057324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1058324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1059324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a b")
1060324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a b", found)
1061324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1062324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1063324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testRuleListLabel2(self):
1064324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1065324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1066324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1067324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1068324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
1069324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : x+=b x+=b -> $x $x*;
1070324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
1071324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1072324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1073324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1074324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1075324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a b")
1076324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a b", found)
1077324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1078324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1079324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testOptional(self):
1080324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1081324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1082324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1083324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1084324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
1085324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : x=b (y=b)? -> $x $y?;
1086324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
1087324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1088324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1089324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1090324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1091324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a")
1092324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a", found)
1093324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1094324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1095324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testOptional2(self):
1096324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1097324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1098324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1099324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
1101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : x=ID (y=b)? -> $x $y?;
1102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
1103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a b")
1108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a b", found)
1109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testOptional3(self):
1112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
1117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : x=ID (y=b)? -> ($x $y)?;
1118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
1119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a b")
1124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a b", found)
1125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testOptional4(self):
1128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
1133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : x+=ID (y=b)? -> ($x $y)?;
1134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
1135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a b")
1140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a b", found)
1141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testOptional5(self):
1144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
1149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID -> ID? ; // match an ID to optional ID
1150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
1151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a")
1156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("a", found)
1157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testArbitraryExprType(self):
1160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
1165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : x+=b x+=b -> {CommonTree(None)};
1166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID ;
1167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "a b")
1172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("", found)
1173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testSet(self):
1176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a: (INT|ID)+ -> INT+ ID+ ;
1181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT: '0'..'9'+;
1182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+;
1183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "2 a 34 de")
1187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("2 34 a de", found)
1188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testSet2(self):
1191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a: (INT|ID) -> INT? ID? ;
1196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT: '0'..'9'+;
1197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+;
1198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "2")
1202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("2", found)
1203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @testbase.broken("http://www.antlr.org:8888/browse/ANTLR-162",
1206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                     antlr3.tree.RewriteEmptyStreamException)
1207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testSetWithLabel(self):
1208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : x=(INT|ID) -> $x ;
1213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT: '0'..'9'+;
1214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+;
1215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "2")
1219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("2", found)
1220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testRewriteAction(self):
1223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens { FLOAT; }
1228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r
1229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                : INT -> {CommonTree(CommonToken(type=FLOAT, text=$INT.text+".0"))}
1230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                ;
1231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
1232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS: (' ' | '\n' | '\t')+ {$channel = HIDDEN;};
1233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "r", "25")
1236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("25.0", found)
1237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testOptionalSubruleWithoutRealElements(self):
1240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # copy type *and* modifier even though it's optional
1241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # for each invocation of (...)+ in rewrite
1242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r"""
1244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {PARMS;}
1247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            modulo
1249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver             : 'modulo' ID ('(' parms+ ')')? -> ^('modulo' ID ^(PARMS parms+)?)
1250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver             ;
1251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            parms : '#'|ID;
1252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : ('a'..'z' | 'A'..'Z')+;
1253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            """)
1255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "modulo", "modulo abc (x y #)")
1257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(modulo abc (PARMS x y #))", found)
1258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ## C A R D I N A L I T Y  I S S U E S
1261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testCardinality(self):
1263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {BLOCK;}
1268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID ID INT INT INT -> (ID INT)+;
1269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
1271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        try:
1275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.execParser(grammar, "a", "a b 3 4 5")
1276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.fail()
1277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        except antlr3.tree.RewriteCardinalityException:
1278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            pass
1279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testCardinality2(self):
1282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID+ -> ID ID ID ; // only 2 input IDs
1287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            op : '+'|'-' ;
1288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
1290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        try:
1294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.execParser(grammar, "a", "a b")
1295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.fail()
1296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        except antlr3.tree.RewriteCardinalityException:
1297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            pass
1298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testCardinality3(self):
1301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID? INT -> ID INT ;
1306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            op : '+'|'-' ;
1307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
1309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        try:
1313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.execParser(grammar, "a", "3")
1314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.fail()
1315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        except antlr3.tree.RewriteEmptyStreamException:
1316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            pass
1317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testLoopCardinality(self):
1320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID? INT -> ID+ INT ;
1325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            op : '+'|'-' ;
1326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
1328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        try:
1332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.execParser(grammar, "a", "3")
1333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.fail()
1334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        except antlr3.tree.RewriteEarlyExitException:
1335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            pass
1336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testWildcard(self):
1339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar T;
1342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID c=. -> $c;
1344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
1346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found = self.execParser(grammar, "a", "abc 34")
1350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("34", found)
1351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # E R R O R S
1354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testExtraTokenInSimpleDecl(self):
1356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar foo;
1359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {EXPR;}
1361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ;
1362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            type : 'int' | 'float' ;
1363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
1365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found, errors = self.execParser(grammar, "decl", "int 34 x=1;",
1369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                        expectErrors=True)
1370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals(["line 1:4 extraneous input u'34' expecting ID"],
1371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                          errors)
1372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(EXPR int x 1)", found) # tree gets correct x and 1 tokens
1373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    #@testbase.broken("FIXME", AssertionError)
1376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testMissingIDInSimpleDecl(self):
1377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar foo;
1380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {EXPR;}
1382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ;
1383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            type : 'int' | 'float' ;
1384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
1386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found, errors = self.execParser(grammar, "decl", "int =1;",
1390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                        expectErrors=True)
1391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals(["line 1:4 missing ID at u'='"], errors)
1392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(EXPR int <missing ID> 1)", found) # tree gets invented ID token
1393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testMissingSetInSimpleDecl(self):
1396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar foo;
1399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokens {EXPR;}
1401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ;
1402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            type : 'int' | 'float' ;
1403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
1405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found, errors = self.execParser(grammar, "decl", "x=1;",
1409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                        expectErrors=True)
1410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals(["line 1:0 mismatched input u'x' expecting set None"],
1411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                          errors);
1412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("(EXPR <error: x> x 1)", found) # tree gets invented ID token
1413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testMissingTokenGivesErrorNode(self):
1416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar foo;
1419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID INT -> ID INT ;
1421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
1423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found, errors = self.execParser(grammar, "a", "abc",
1427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                        expectErrors=True)
1428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals(["line 1:3 missing INT at '<EOF>'"], errors)
1429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # doesn't do in-line recovery for sets (yet?)
1430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("abc <missing INT>", found)
1431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testExtraTokenGivesErrorNode(self):
1434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar foo;
1437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : b c -> b c;
1439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID -> ID ;
1440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            c : INT -> INT ;
1441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
1443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found, errors = self.execParser(grammar, "a", "abc ick 34",
1447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                        expectErrors=True)
1448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals(["line 1:4 extraneous input u'ick' expecting INT"],
1449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                          errors)
1450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("abc 34", found)
1451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    #@testbase.broken("FIXME", AssertionError)
1454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testMissingFirstTokenGivesErrorNode(self):
1455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar foo;
1458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : ID INT -> ID INT ;
1460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
1462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found, errors = self.execParser(grammar, "a", "34", expectErrors=True)
1466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals(["line 1:0 missing ID at u'34'"], errors)
1467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("<missing ID> 34", found)
1468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    #@testbase.broken("FIXME", AssertionError)
1471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testMissingFirstTokenGivesErrorNode2(self):
1472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar foo;
1475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : b c -> b c;
1477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID -> ID ;
1478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            c : INT -> INT ;
1479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
1481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found, errors = self.execParser(grammar, "a", "34", expectErrors=True)
1485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # finds an error at the first token, 34, and re-syncs.
1486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # re-synchronizing does not consume a token because 34 follows
1487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # ref to rule b (start of c). It then matches 34 in c.
1488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals(["line 1:0 missing ID at u'34'"], errors)
1489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("<missing ID> 34", found)
1490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def testNoViableAltGivesErrorNode(self):
1493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        grammar = textwrap.dedent(
1494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            r'''
1495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            grammar foo;
1496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            options {language=Python;output=AST;}
1497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            a : b -> b | c -> c;
1498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            b : ID -> ID ;
1499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            c : INT -> INT ;
1500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ID : 'a'..'z'+ ;
1501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            S : '*' ;
1502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            INT : '0'..'9'+;
1503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            WS : (' '|'\n') {$channel=HIDDEN;} ;
1504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ''')
1505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        found, errors = self.execParser(grammar, "a", "*", expectErrors=True)
1507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # finds an error at the first token, 34, and re-syncs.
1508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # re-synchronizing does not consume a token because 34 follows
1509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # ref to rule b (start of c). It then matches 34 in c.
1510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals(["line 1:0 no viable alternative at input u'*'"],
1511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                          errors);
1512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.assertEquals("<unexpected: [@0,0:0=u'*',<6>,1:0], resync=*>",
1513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                          found)
1514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverif __name__ == '__main__':
1517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    unittest.main()
1518