1 /*
2  * [The "BSD license"]
3  *  Copyright (c) 2010 Terence Parr
4  *  All rights reserved.
5  *
6  *  Redistribution and use in source and binary forms, with or without
7  *  modification, are permitted provided that the following conditions
8  *  are met:
9  *  1. Redistributions of source code must retain the above copyright
10  *      notice, this list of conditions and the following disclaimer.
11  *  2. Redistributions in binary form must reproduce the above copyright
12  *      notice, this list of conditions and the following disclaimer in the
13  *      documentation and/or other materials provided with the distribution.
14  *  3. The name of the author may not be used to endorse or promote products
15  *      derived from this software without specific prior written permission.
16  *
17  *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 package org.antlr.test;
29 
30 import org.antlr.Tool;
31 import org.antlr.codegen.CodeGenerator;
32 import org.antlr.grammar.v3.ANTLRParser;
33 import org.antlr.grammar.v3.ActionTranslator;
34 import org.antlr.runtime.CommonToken;
35 import org.stringtemplate.v4.ST;
36 import org.stringtemplate.v4.STGroup;
37 import org.antlr.tool.*;
38 import org.junit.Test;
39 
40 import java.io.StringReader;
41 import java.util.ArrayList;
42 import java.util.List;
43 
44 import static org.junit.Assert.*;
45 
46 /** Check the $x, $x.y attributes.  For checking the actual
47  *  translation, assume the Java target.  This is still a great test
48  *  for the semantics of the $x.y stuff regardless of the target.
49  */
50 public class TestAttributes extends BaseTest {
51 
52 	/** Public default constructor used by TestRig */
TestAttributes()53 	public TestAttributes() {
54 	}
55 
testEscapedLessThanInAction()56 	@Test public void testEscapedLessThanInAction() throws Exception {
57 		Grammar g = new Grammar();
58 		Tool antlr = newTool();
59 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
60 		String action = "i<3; '<xmltag>'";
61 		ActionTranslator translator = new ActionTranslator(generator,"a",
62 			new CommonToken(ANTLRParser.ACTION,action),0);
63 		String expecting = action;
64 		String rawTranslation =
65 			translator.translate();
66 		STGroup templates =
67 			new STGroup();
68 		ST actionST = new ST(templates, "<action>");
69 		actionST.add("action", rawTranslation);
70 		String found = actionST.render();
71 		assertEquals(expecting, found);
72 	}
73 
testEscaped$InAction()74 	@Test public void testEscaped$InAction() throws Exception {
75 		String action = "int \\$n; \"\\$in string\\$\"";
76 		String expecting = "int $n; \"$in string$\"";
77 		Grammar g = new Grammar(
78 			"parser grammar t;\n"+
79 				"@members {"+action+"}\n"+
80 				"a[User u, int i]\n" +
81 				"        : {"+action+"}\n" +
82 				"        ;");
83 		Tool antlr = newTool();
84 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
85 		g.setCodeGenerator(generator);
86 		generator.genRecognizer(); // forces load of templates
87 		ActionTranslator translator =
88 			new ActionTranslator(generator,
89 				"a",
90 				new CommonToken(ANTLRParser.ACTION,action),0);
91 		String found = translator.translate();		assertEquals(expecting, found);
92 	}
93 
testArguments()94 	@Test public void testArguments() throws Exception {
95 		String action = "$i; $i.x; $u; $u.x";
96 		String expecting = "i; i.x; u; u.x";
97 
98 		ErrorQueue equeue = new ErrorQueue();
99 		ErrorManager.setErrorListener(equeue);
100 		Grammar g = new Grammar(
101 			"parser grammar t;\n"+
102 				"a[User u, int i]\n" +
103 				"        : {"+action+"}\n" +
104 				"        ;");
105 		Tool antlr = newTool();
106 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
107 		g.setCodeGenerator(generator);
108 		generator.genRecognizer(); // forces load of templates
109 		ActionTranslator translator = new ActionTranslator(generator,"a",
110 			new CommonToken(ANTLRParser.ACTION,action),1);
111 		String found = translator.translate();		assertEquals(expecting, found);
112 
113 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
114 	}
115 
testComplicatedArgParsing()116 	@Test public void testComplicatedArgParsing() throws Exception {
117 		String action = "x, (*a).foo(21,33), 3.2+1, '\\n', "+
118 			"\"a,oo\\nick\", {bl, \"fdkj\"eck}";
119 		String expecting = "x, (*a).foo(21,33), 3.2+1, '\\n', \"a,oo\\nick\", {bl, \"fdkj\"eck}";
120 
121 		ErrorQueue equeue = new ErrorQueue();
122 		ErrorManager.setErrorListener(equeue);
123 
124 		// now check in actual grammar.
125 		Grammar g = new Grammar(
126 			"parser grammar t;\n"+
127 				"a[User u, int i]\n" +
128 				"        : A a["+action+"] B\n" +
129 				"        ;");
130 		Tool antlr = newTool();
131 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
132 		g.setCodeGenerator(generator);
133 		generator.genRecognizer(); // forces load of templates
134 		ActionTranslator translator = new ActionTranslator(generator,"a",
135 			new CommonToken(ANTLRParser.ACTION,action),1);
136 		String rawTranslation =	translator.translate();
137 		assertEquals(expecting, rawTranslation);
138 
139 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
140 	}
141 
testBracketArgParsing()142 	@Test public void testBracketArgParsing() throws Exception {
143 		ErrorQueue equeue = new ErrorQueue();
144 		ErrorManager.setErrorListener(equeue);
145 
146 		// now check in actual grammar.
147 		Grammar g = new Grammar(
148 			"parser grammar t;\n"+
149 				"a[String[\\] ick, int i]\n" +
150 				"        : A \n"+
151 				"        ;");
152 		Tool antlr = newTool();
153 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
154 		g.setCodeGenerator(generator);
155 		generator.genRecognizer(); // forces load of templates
156 		Rule r = g.getRule("a");
157 		AttributeScope parameters = r.parameterScope;
158 		List<Attribute> attrs = parameters.getAttributes();
159 		assertEquals("attribute mismatch","String[] ick",attrs.get(0).decl.toString());
160 		assertEquals("parameter name mismatch","ick",attrs.get(0).name);
161 		assertEquals("declarator mismatch", "String[]", attrs.get(0).type);
162 
163 		assertEquals("attribute mismatch","int i",attrs.get(1).decl.toString());
164 		assertEquals("parameter name mismatch","i",attrs.get(1).name);
165 		assertEquals("declarator mismatch", "int", attrs.get(1).type);
166 
167 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
168 	}
169 
testStringArgParsing()170 	@Test public void testStringArgParsing() throws Exception {
171 		String action = "34, '{', \"it's<\", '\"', \"\\\"\", 19";
172 		String expecting = "34, '{', \"it's<\", '\"', \"\\\"\", 19";
173 
174 		ErrorQueue equeue = new ErrorQueue();
175 		ErrorManager.setErrorListener(equeue);
176 
177 		// now check in actual grammar.
178 		Grammar g = new Grammar(
179 			"parser grammar t;\n"+
180 				"a[User u, int i]\n" +
181 				"        : A a["+action+"] B\n" +
182 				"        ;");
183 		Tool antlr = newTool();
184 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
185 		g.setCodeGenerator(generator);
186 		generator.genRecognizer(); // forces load of templates
187 		ActionTranslator translator = new ActionTranslator(generator,"a",
188 			new CommonToken(ANTLRParser.ACTION,action),1);
189 		String rawTranslation =	translator.translate();
190 		assertEquals(expecting, rawTranslation);
191 
192 		List<String> expectArgs = new ArrayList<String>() {
193 			{add("34");}
194 			{add("'{'");}
195 			{add("\"it's<\"");}
196 			{add("'\"'");}
197 			{add("\"\\\"\"");} // that's "\""
198 			{add("19");}
199 		};
200 		List<String> actualArgs = CodeGenerator.getListOfArgumentsFromAction(action, ',');
201 		assertEquals("args mismatch", expectArgs, actualArgs);
202 
203 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
204 	}
205 
testComplicatedSingleArgParsing()206 	@Test public void testComplicatedSingleArgParsing() throws Exception {
207 		String action = "(*a).foo(21,33,\",\")";
208 		String expecting = "(*a).foo(21,33,\",\")";
209 
210 		ErrorQueue equeue = new ErrorQueue();
211 		ErrorManager.setErrorListener(equeue);
212 
213 		// now check in actual grammar.
214 		Grammar g = new Grammar(
215 			"parser grammar t;\n"+
216 				"a[User u, int i]\n" +
217 				"        : A a["+action+"] B\n" +
218 				"        ;");
219 		Tool antlr = newTool();
220 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
221 		g.setCodeGenerator(generator);
222 		generator.genRecognizer(); // forces load of templates
223 		ActionTranslator translator = new ActionTranslator(generator,"a",
224 			new CommonToken(ANTLRParser.ACTION,action),1);
225 		String rawTranslation =	translator.translate();
226 		assertEquals(expecting, rawTranslation);
227 
228 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
229 	}
230 
testArgWithLT()231 	@Test public void testArgWithLT() throws Exception {
232 		String action = "34<50";
233 		String expecting = "34<50";
234 
235 		ErrorQueue equeue = new ErrorQueue();
236 		ErrorManager.setErrorListener(equeue);
237 
238 		// now check in actual grammar.
239 		Grammar g = new Grammar(
240 			"parser grammar t;\n"+
241 				"a[boolean b]\n" +
242 				"        : A a["+action+"] B\n" +
243 				"        ;");
244 		Tool antlr = newTool();
245 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
246 		g.setCodeGenerator(generator);
247 		generator.genRecognizer(); // forces load of templates
248 		ActionTranslator translator = new ActionTranslator(generator,"a",
249 			new CommonToken(ANTLRParser.ACTION,action),1);
250 		String rawTranslation =
251 			translator.translate();
252 		assertEquals(expecting, rawTranslation);
253 
254 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
255 	}
256 
testGenericsAsArgumentDefinition()257 	@Test public void testGenericsAsArgumentDefinition() throws Exception {
258 		String action = "$foo.get(\"ick\");";
259 		String expecting = "foo.get(\"ick\");";
260 
261 		ErrorQueue equeue = new ErrorQueue();
262 		ErrorManager.setErrorListener(equeue);
263 		String grammar =
264 			"parser grammar T;\n"+
265 				"a[HashMap<String,String> foo]\n" +
266 				"        : {"+action+"}\n" +
267 				"        ;";
268 		Grammar g = new Grammar(grammar);
269 		Rule ra = g.getRule("a");
270 		List<Attribute> attrs = ra.parameterScope.getAttributes();
271 		assertEquals("attribute mismatch","HashMap<String,String> foo",attrs.get(0).decl.toString());
272 		assertEquals("parameter name mismatch","foo",attrs.get(0).name);
273 		assertEquals("declarator mismatch", "HashMap<String,String>", attrs.get(0).type);
274 
275 		Tool antlr = newTool();
276 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
277 		g.setCodeGenerator(generator);
278 		generator.genRecognizer(); // forces load of templates
279 		ActionTranslator translator = new ActionTranslator(generator,"a",
280 			new CommonToken(ANTLRParser.ACTION,action),1);
281 		String found = translator.translate();		assertEquals(expecting, found);
282 
283 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
284 	}
285 
testGenericsAsArgumentDefinition2()286 	@Test public void testGenericsAsArgumentDefinition2() throws Exception {
287 		String action = "$foo.get(\"ick\"); x=3;";
288 		String expecting = "foo.get(\"ick\"); x=3;";
289 
290 		ErrorQueue equeue = new ErrorQueue();
291 		ErrorManager.setErrorListener(equeue);
292 		String grammar =
293 			"parser grammar T;\n"+
294 				"a[HashMap<String,String> foo, int x, List<String> duh]\n" +
295 				"        : {"+action+"}\n" +
296 				"        ;";
297 		Grammar g = new Grammar(grammar);
298 		Rule ra = g.getRule("a");
299 		List<Attribute> attrs = ra.parameterScope.getAttributes();
300 
301 		assertEquals("attribute mismatch","HashMap<String,String> foo",attrs.get(0).decl.toString().trim());
302 		assertEquals("parameter name mismatch","foo",attrs.get(0).name);
303 		assertEquals("declarator mismatch", "HashMap<String,String>", attrs.get(0).type);
304 
305 		assertEquals("attribute mismatch","int x",attrs.get(1).decl.toString().trim());
306 		assertEquals("parameter name mismatch","x",attrs.get(1).name);
307 		assertEquals("declarator mismatch", "int", attrs.get(1).type);
308 
309 		assertEquals("attribute mismatch","List<String> duh",attrs.get(2).decl.toString().trim());
310 		assertEquals("parameter name mismatch","duh",attrs.get(2).name);
311 		assertEquals("declarator mismatch", "List<String>", attrs.get(2).type);
312 
313 		Tool antlr = newTool();
314 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
315 		g.setCodeGenerator(generator);
316 		generator.genRecognizer(); // forces load of templates
317 		ActionTranslator translator = new ActionTranslator(generator,"a",
318 			new CommonToken(ANTLRParser.ACTION,action),1);
319 		String found = translator.translate();		assertEquals(expecting, found);
320 
321 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
322 	}
323 
testGenericsAsReturnValue()324 	@Test public void testGenericsAsReturnValue() throws Exception {
325 		ErrorQueue equeue = new ErrorQueue();
326 		ErrorManager.setErrorListener(equeue);
327 		String grammar =
328 			"parser grammar T;\n"+
329 				"a returns [HashMap<String,String> foo] : ;\n";
330 		Grammar g = new Grammar(grammar);
331 		Rule ra = g.getRule("a");
332 		List<Attribute> attrs = ra.returnScope.getAttributes();
333 		assertEquals("attribute mismatch","HashMap<String,String> foo",attrs.get(0).decl.toString());
334 		assertEquals("parameter name mismatch","foo",attrs.get(0).name);
335 		assertEquals("declarator mismatch", "HashMap<String,String>", attrs.get(0).type);
336 
337 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
338 	}
339 
testComplicatedArgParsingWithTranslation()340 	@Test public void testComplicatedArgParsingWithTranslation() throws Exception {
341 		String action = "x, $A.text+\"3242\", (*$A).foo(21,33), 3.2+1, '\\n', "+
342 			"\"a,oo\\nick\", {bl, \"fdkj\"eck}";
343 		String expecting = "x, (A1!=null?A1.getText():null)+\"3242\", (*A1).foo(21,33), 3.2+1, '\\n', \"a,oo\\nick\", {bl, \"fdkj\"eck}";
344 
345 		ErrorQueue equeue = new ErrorQueue();
346 		ErrorManager.setErrorListener(equeue);
347 
348 		// now check in actual grammar.
349 		Grammar g = new Grammar(
350 			"parser grammar t;\n"+
351 				"a[User u, int i]\n" +
352 				"        : A a["+action+"] B\n" +
353 				"        ;");
354 		Tool antlr = newTool();
355 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
356 		g.setCodeGenerator(generator);
357 		generator.genRecognizer(); // forces load of templates
358 		ActionTranslator translator = new ActionTranslator(generator,"a",
359 			new CommonToken(ANTLRParser.ACTION,action),1);
360 		String found = translator.translate();		assertEquals(expecting, found);
361 
362 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
363 	}
364 
365 	/** $x.start refs are checked during translation not before so ANTLR misses
366 	 the fact that rule r has refs to predefined attributes if the ref is after
367 	 the def of the method or self-referential.  Actually would be ok if I didn't
368 	 convert actions to strings; keep as templates.
369 	 June 9, 2006: made action translation leave templates not strings
370 	 */
testRefToReturnValueBeforeRefToPredefinedAttr()371 	@Test public void testRefToReturnValueBeforeRefToPredefinedAttr() throws Exception {
372 		String action = "$x.foo";
373 		String expecting = "(x!=null?((t.b_return)x).foo:0)";
374 
375 		ErrorQueue equeue = new ErrorQueue();
376 		ErrorManager.setErrorListener(equeue);
377 		Grammar g = new Grammar(
378 			"parser grammar t;\n"+
379 				"a : x=b {"+action+"} ;\n" +
380 				"b returns [int foo] : B {$b.start} ;\n");
381 		Tool antlr = newTool();
382 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
383 		g.setCodeGenerator(generator);
384 		generator.genRecognizer(); // forces load of templates
385 		ActionTranslator translator = new ActionTranslator(generator,"a",
386 			new CommonToken(ANTLRParser.ACTION,action),1);
387 		String found = translator.translate();
388 		assertEquals(expecting, found);
389 
390 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
391 	}
392 
testRuleLabelBeforeRefToPredefinedAttr()393 	@Test public void testRuleLabelBeforeRefToPredefinedAttr() throws Exception {
394 		// As of Mar 2007, I'm removing unused labels.  Unfortunately,
395 		// the action is not seen until code gen.  Can't see $x.text
396 		// before stripping unused labels.  We really need to translate
397 		// actions first so code gen logic can use info.
398 		String action = "$x.text";
399 		String expecting = "(x!=null?input.toString(x.start,x.stop):null)";
400 
401 		ErrorQueue equeue = new ErrorQueue();
402 		ErrorManager.setErrorListener(equeue);
403 		Grammar g = new Grammar(
404 			"parser grammar t;\n"+
405 				"a : x=b {###"+action+"!!!} ;\n" +
406 				"b : B ;\n");
407 		Tool antlr = newTool();
408 
409 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
410 		g.setCodeGenerator(generator);
411 		generator.genRecognizer(); // codegen phase sets some vars we need
412 		ST codeST = generator.getRecognizerST();
413 		String code = codeST.render();
414 		String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!"));
415 		assertEquals(expecting, found);
416 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
417 	}
418 
testInvalidArguments()419 	@Test public void testInvalidArguments() throws Exception {
420 		String action = "$x";
421 		String expecting = action;
422 
423 		ErrorQueue equeue = new ErrorQueue();
424 		ErrorManager.setErrorListener(equeue);
425 		Grammar g = new Grammar(
426 			"parser grammar t;\n"+
427 				"a[User u, int i]\n" +
428 				"        : {"+action+"}\n" +
429 				"        ;");
430 		Tool antlr = newTool();
431 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
432 		ActionTranslator translator = new ActionTranslator(generator,
433 			"a",
434 			new CommonToken(ANTLRParser.ACTION,action),1);
435 		String found = translator.translate();
436 		assertEquals(expecting, found);
437 
438 		int expectedMsgID = ErrorManager.MSG_UNKNOWN_SIMPLE_ATTRIBUTE;
439 		Object expectedArg = "x";
440 		GrammarSemanticsMessage expectedMessage =
441 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
442 		checkError(equeue, expectedMessage);
443 	}
444 
testReturnValue()445 	@Test public void testReturnValue() throws Exception {
446 		String action = "$x.i";
447 		String expecting = "x";
448 
449 		ErrorQueue equeue = new ErrorQueue();
450 		ErrorManager.setErrorListener(equeue);
451 		Grammar g = new Grammar(
452 			"grammar t;\n"+
453 				"a returns [int i]\n" +
454 				"        : 'a'\n" +
455 				"        ;\n" +
456 				"b : x=a {"+action+"} ;\n");
457 		Tool antlr = newTool();
458 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
459 		g.setCodeGenerator(generator);
460 		generator.genRecognizer(); // forces load of templates
461 		ActionTranslator translator =
462 			new ActionTranslator(generator,
463 				"b",
464 				new CommonToken(ANTLRParser.ACTION,action),1);
465 		String found =	translator.translate();
466 		assertEquals(expecting, found);
467 
468 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
469 	}
470 
testActionNotMovedToSynPred()471 	@Test public void testActionNotMovedToSynPred() throws Exception {
472 		String action = "$b = true;";
473 		String expecting = "retval.b = true;";
474 
475 		ErrorQueue equeue = new ErrorQueue();
476 		ErrorManager.setErrorListener(equeue);
477 		Grammar g = new Grammar(
478 			"grammar t;\n"+
479 			"options {output=AST;}\n" + // push b into retval struct
480 			"a returns [boolean b]\n" +
481 			"options {backtrack=true;}\n" +
482 			"   : 'a' {"+action+"}\n" +
483 			"   | 'a'\n" +
484 			"   ;\n");
485 		Tool antlr = newTool();
486 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
487 		g.setCodeGenerator(generator);
488 		generator.genRecognizer(); // forces load of templates
489 		ActionTranslator translator =
490 			new ActionTranslator(generator,
491 				"a",
492 				new CommonToken(ANTLRParser.ACTION,action),1);
493 		String found =	translator.translate();
494 		assertEquals(expecting, found);
495 
496 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
497 	}
498 
testReturnValueWithNumber()499 	@Test public void testReturnValueWithNumber() throws Exception {
500 		String action = "$x.i1";
501 		String expecting = "x";
502 
503 		ErrorQueue equeue = new ErrorQueue();
504 		ErrorManager.setErrorListener(equeue);
505 		Grammar g = new Grammar(
506 			"grammar t;\n"+
507 				"a returns [int i1]\n" +
508 				"        : 'a'\n" +
509 				"        ;\n" +
510 				"b : x=a {"+action+"} ;\n");
511 		Tool antlr = newTool();
512 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
513 		g.setCodeGenerator(generator);
514 		generator.genRecognizer(); // forces load of templates
515 		ActionTranslator translator =
516 			new ActionTranslator(generator,
517 				"b",
518 				new CommonToken(ANTLRParser.ACTION,action),1);
519 		String found = translator.translate();
520 		assertEquals(expecting, found);
521 
522 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
523 	}
524 
testReturnValues()525 	@Test public void testReturnValues() throws Exception {
526 		String action = "$i; $i.x; $u; $u.x";
527 		String expecting = "retval.i; retval.i.x; retval.u; retval.u.x";
528 
529 		ErrorQueue equeue = new ErrorQueue();
530 		ErrorManager.setErrorListener(equeue);
531 		Grammar g = new Grammar(
532 			"parser grammar t;\n"+
533 				"a returns [User u, int i]\n" +
534 				"        : {"+action+"}\n" +
535 				"        ;");
536 		Tool antlr = newTool();
537 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
538 		g.setCodeGenerator(generator);
539 		generator.genRecognizer(); // forces load of templates
540 		ActionTranslator translator = new ActionTranslator(generator,"a",
541 			new CommonToken(ANTLRParser.ACTION,action),1);
542 		String found = translator.translate();
543 		assertEquals(expecting, found);
544 
545 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
546 	}
547 
548 	/* regression test for ANTLR-46 */
testReturnWithMultipleRuleRefs()549 	@Test public void testReturnWithMultipleRuleRefs() throws Exception {
550 		String action1 = "$obj = $rule2.obj;";
551 		String action2 = "$obj = $rule3.obj;";
552 		String expecting1 = "obj = rule21;";
553 		String expecting2 = "obj = rule32;";
554 
555 		ErrorQueue equeue = new ErrorQueue();
556 		ErrorManager.setErrorListener(equeue);
557 		Grammar g = new Grammar(
558 			"grammar t;\n" +
559 				"rule1 returns [ Object obj ]\n" +
560 				":	rule2 { "+action1+" }\n" +
561 				"|	rule3 { "+action2+" }\n" +
562 				";\n"+
563 				"rule2 returns [ Object obj ]\n"+
564 				":	foo='foo' { $obj = $foo.text; }\n"+
565 				";\n"+
566 				"rule3 returns [ Object obj ]\n"+
567 				":	bar='bar' { $obj = $bar.text; }\n"+
568 				";");
569 		Tool antlr = newTool();
570 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
571 		g.setCodeGenerator(generator);
572 		generator.genRecognizer(); // forces load of templates
573 		int i = 0;
574 		String action = action1;
575 		String expecting = expecting1;
576 		do {
577 			ActionTranslator translator = new ActionTranslator(generator,"rule1",
578 				new CommonToken(ANTLRParser.ACTION,action),i+1);
579 			String found = translator.translate();
580 			assertEquals(expecting, found);
581 			action = action2;
582 			expecting = expecting2;
583 		} while (i++ < 1);
584 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
585 	}
586 
testInvalidReturnValues()587 	@Test public void testInvalidReturnValues() throws Exception {
588 		String action = "$x";
589 		String expecting = action;
590 
591 		ErrorQueue equeue = new ErrorQueue();
592 		ErrorManager.setErrorListener(equeue);
593 		Grammar g = new Grammar(
594 			"parser grammar t;\n"+
595 				"a returns [User u, int i]\n" +
596 				"        : {"+action+"}\n" +
597 				"        ;");
598 		Tool antlr = newTool();
599 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
600 		ActionTranslator translator = new ActionTranslator(generator,"a",
601 			new CommonToken(ANTLRParser.ACTION,action),1);
602 		String found = translator.translate();
603 		assertEquals(expecting, found);
604 
605 		int expectedMsgID = ErrorManager.MSG_UNKNOWN_SIMPLE_ATTRIBUTE;
606 		Object expectedArg = "x";
607 		GrammarSemanticsMessage expectedMessage =
608 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
609 		checkError(equeue, expectedMessage);
610 	}
611 
testTokenLabels()612 	@Test public void testTokenLabels() throws Exception {
613 		String action = "$id; $f; $id.text; $id.getText(); $id.dork " +
614 			"$id.type; $id.line; $id.pos; " +
615 			"$id.channel; $id.index;";
616 		String expecting = "id; f; (id!=null?id.getText():null); id.getText(); id.dork (id!=null?id.getType():0); (id!=null?id.getLine():0); (id!=null?id.getCharPositionInLine():0); (id!=null?id.getChannel():0); (id!=null?id.getTokenIndex():0);";
617 
618 		ErrorQueue equeue = new ErrorQueue();
619 		ErrorManager.setErrorListener(equeue);
620 		Grammar g = new Grammar(
621 			"parser grammar t;\n"+
622 				"a : id=ID f=FLOAT {"+action+"}\n" +
623 				"  ;");
624 		Tool antlr = newTool();
625 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
626 		g.setCodeGenerator(generator);
627 		generator.genRecognizer(); // forces load of templates
628 		ActionTranslator translator = new ActionTranslator(generator,"a",
629 			new CommonToken(ANTLRParser.ACTION,action),1);
630 		String found = translator.translate();
631 		assertEquals(expecting, found);
632 
633 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
634 	}
635 
testRuleLabels()636 	@Test public void testRuleLabels() throws Exception {
637 		String action = "$r.x; $r.start;\n $r.stop;\n $r.tree; $a.x; $a.stop;";
638 		String expecting = "(r!=null?((t.a_return)r).x:0); (r!=null?(r.start):null);" + newline +
639 			"\t\t\t (r!=null?(r.stop):null);" + newline +
640 			"\t\t\t (r!=null?((Object)r.getTree()):null); (r!=null?((t.a_return)r).x:0); (r!=null?(r.stop):null);";
641 
642 		ErrorQueue equeue = new ErrorQueue();
643 		ErrorManager.setErrorListener(equeue);
644 		Grammar g = new Grammar(
645 			"parser grammar t;\n"+
646 				"a returns [int x]\n" +
647 				"  :\n" +
648 				"  ;\n"+
649 				"b : r=a {###"+action+"!!!}\n" +
650 				"  ;");
651 		Tool antlr = newTool();
652 		antlr.setOutputDirectory(null); // write to /dev/null
653 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
654 		g.setCodeGenerator(generator);
655 		generator.genRecognizer(); // codegen phase sets some vars we need
656 		ST codeST = generator.getRecognizerST();
657 		String code = codeST.render();
658 		String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!"));
659 		assertEquals(expecting, found);
660 
661 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
662 	}
663 
testAmbiguRuleRef()664 	@Test public void testAmbiguRuleRef() throws Exception {
665 		ErrorQueue equeue = new ErrorQueue();
666 		ErrorManager.setErrorListener(equeue);
667 		Grammar g = new Grammar(
668 			"parser grammar t;\n"+
669 				"a : A a {$a.text} | B ;");
670 		Tool antlr = newTool();
671 		antlr.setOutputDirectory(null); // write to /dev/null
672 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
673 		g.setCodeGenerator(generator);
674 		generator.genRecognizer();
675 
676 		// error(132): <string>:2:9: reference $a is ambiguous; rule a is enclosing rule and referenced in the production
677 		assertEquals("unexpected errors: "+equeue, 1, equeue.errors.size());
678 	}
679 
testRuleLabelsWithSpecialToken()680 	@Test public void testRuleLabelsWithSpecialToken() throws Exception {
681 		String action = "$r.x; $r.start; $r.stop; $r.tree; $a.x; $a.stop;";
682 		String expecting = "(r!=null?((t.a_return)r).x:0); (r!=null?((MYTOKEN)r.start):null); (r!=null?((MYTOKEN)r.stop):null); (r!=null?((Object)r.getTree()):null); (r!=null?((t.a_return)r).x:0); (r!=null?((MYTOKEN)r.stop):null);";
683 
684 		ErrorQueue equeue = new ErrorQueue();
685 		ErrorManager.setErrorListener(equeue);
686 		Grammar g = new Grammar(
687 			"parser grammar t;\n"+
688 				"options {TokenLabelType=MYTOKEN;}\n"+
689 				"a returns [int x]\n" +
690 				"  :\n" +
691 				"  ;\n"+
692 				"b : r=a {###"+action+"!!!}\n" +
693 				"  ;");
694 		Tool antlr = newTool();
695 		antlr.setOutputDirectory(null); // write to /dev/null
696 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
697 		g.setCodeGenerator(generator);
698 		generator.genRecognizer(); // codegen phase sets some vars we need
699 
700 		ST codeST = generator.getRecognizerST();
701 		String code = codeST.render();
702 		String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!"));
703 		assertEquals(expecting, found);
704 
705 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
706 	}
707 
testForwardRefRuleLabels()708 	@Test public void testForwardRefRuleLabels() throws Exception {
709 		String action = "$r.x; $r.start; $r.stop; $r.tree; $a.x; $a.tree;";
710 		String expecting = "(r!=null?((t.a_return)r).x:0); (r!=null?(r.start):null); (r!=null?(r.stop):null); (r!=null?((Object)r.getTree()):null); (r!=null?((t.a_return)r).x:0); (r!=null?((Object)r.getTree()):null);";
711 
712 		ErrorQueue equeue = new ErrorQueue();
713 		ErrorManager.setErrorListener(equeue);
714 		Grammar g = new Grammar(
715 			"parser grammar t;\n"+
716 				"b : r=a {###"+action+"!!!}\n" +
717 				"  ;\n" +
718 				"a returns [int x]\n" +
719 				"  : ;\n");
720 		Tool antlr = newTool();
721 		antlr.setOutputDirectory(null); // write to /dev/null
722 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
723 		g.setCodeGenerator(generator);
724 		generator.genRecognizer(); // codegen phase sets some vars we need
725 
726 		ST codeST = generator.getRecognizerST();
727 		String code = codeST.render();
728 		String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!"));
729 		assertEquals(expecting, found);
730 
731 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
732 	}
733 
testInvalidRuleLabelAccessesParameter()734 	@Test public void testInvalidRuleLabelAccessesParameter() throws Exception {
735 		String action = "$r.z";
736 		String expecting = action;
737 
738 		ErrorQueue equeue = new ErrorQueue();
739 		ErrorManager.setErrorListener(equeue);
740 		Grammar g = new Grammar(
741 			"parser grammar t;\n"+
742 				"a[int z] returns [int x]\n" +
743 				"  :\n" +
744 				"  ;\n"+
745 				"b : r=a[3] {"+action+"}\n" +
746 				"  ;");
747 		Tool antlr = newTool();
748 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
749 		ActionTranslator translator = new ActionTranslator(generator, "b",
750 			new CommonToken(ANTLRParser.ACTION,action),1);
751 		String found = translator.translate();		assertEquals(expecting, found);
752 
753 		int expectedMsgID = ErrorManager.MSG_INVALID_RULE_PARAMETER_REF;
754 		Object expectedArg = "a";
755 		Object expectedArg2 = "z";
756 		GrammarSemanticsMessage expectedMessage =
757 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
758 		checkError(equeue, expectedMessage);
759 	}
760 
testInvalidRuleLabelAccessesScopeAttribute()761 	@Test public void testInvalidRuleLabelAccessesScopeAttribute() throws Exception {
762 		String action = "$r.n";
763 		String expecting = action;
764 
765 		ErrorQueue equeue = new ErrorQueue();
766 		ErrorManager.setErrorListener(equeue);
767 		Grammar g = new Grammar(
768 			"parser grammar t;\n"+
769 				"a\n" +
770 				"scope { int n; }\n" +
771 				"  :\n" +
772 				"  ;\n"+
773 				"b : r=a[3] {"+action+"}\n" +
774 				"  ;");
775 		Tool antlr = newTool();
776 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
777 		ActionTranslator translator = new ActionTranslator(generator, "b",
778 			new CommonToken(ANTLRParser.ACTION,action),1);
779 		String found = translator.translate();
780 		assertEquals(expecting, found);
781 
782 		int expectedMsgID = ErrorManager.MSG_INVALID_RULE_SCOPE_ATTRIBUTE_REF;
783 		Object expectedArg = "a";
784 		Object expectedArg2 = "n";
785 		GrammarSemanticsMessage expectedMessage =
786 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
787 		checkError(equeue, expectedMessage);
788 	}
789 
testInvalidRuleAttribute()790 	@Test public void testInvalidRuleAttribute() throws Exception {
791 		String action = "$r.blort";
792 		String expecting = action;
793 
794 		ErrorQueue equeue = new ErrorQueue();
795 		ErrorManager.setErrorListener(equeue);
796 		Grammar g = new Grammar(
797 			"parser grammar t;\n"+
798 				"a[int z] returns [int x]\n" +
799 				"  :\n" +
800 				"  ;\n"+
801 				"b : r=a[3] {"+action+"}\n" +
802 				"  ;");
803 		Tool antlr = newTool();
804 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
805 		ActionTranslator translator = new ActionTranslator(generator, "b",
806 			new CommonToken(ANTLRParser.ACTION,action),1);
807 		String found = translator.translate();
808 		assertEquals(expecting, found);
809 
810 		int expectedMsgID = ErrorManager.MSG_UNKNOWN_RULE_ATTRIBUTE;
811 		Object expectedArg = "a";
812 		Object expectedArg2 = "blort";
813 		GrammarSemanticsMessage expectedMessage =
814 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
815 		checkError(equeue, expectedMessage);
816 	}
817 
testMissingRuleAttribute()818 	@Test public void testMissingRuleAttribute() throws Exception {
819 		String action = "$r";
820 		String expecting = action;
821 
822 		ErrorQueue equeue = new ErrorQueue();
823 		ErrorManager.setErrorListener(equeue);
824 		Grammar g = new Grammar(
825 			"parser grammar t;\n"+
826 				"a[int z] returns [int x]\n" +
827 				"  :\n" +
828 				"  ;\n"+
829 				"b : r=a[3] {"+action+"}\n" +
830 				"  ;");
831 		Tool antlr = newTool();
832 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
833 		ActionTranslator translator = new ActionTranslator(generator, "b",
834 			new CommonToken(ANTLRParser.ACTION,action),1);
835 		String rawTranslation =
836 			translator.translate();
837 
838 		int expectedMsgID = ErrorManager.MSG_ISOLATED_RULE_SCOPE;
839 		Object expectedArg = "r";
840 		Object expectedArg2 = null;
841 		GrammarSemanticsMessage expectedMessage =
842 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
843 		checkError(equeue, expectedMessage);
844 	}
845 
testMissingUnlabeledRuleAttribute()846 	@Test public void testMissingUnlabeledRuleAttribute() throws Exception {
847 		String action = "$a";
848 		String expecting = action;
849 
850 		ErrorQueue equeue = new ErrorQueue();
851 		ErrorManager.setErrorListener(equeue);
852 		Grammar g = new Grammar(
853 			"parser grammar t;\n"+
854 				"a returns [int x]:\n" +
855 				"  ;\n"+
856 				"b : a {"+action+"}\n" +
857 				"  ;");
858 		Tool antlr = newTool();
859 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
860 		ActionTranslator translator = new ActionTranslator(generator, "b",
861 			new CommonToken(ANTLRParser.ACTION,action),1);
862 		String rawTranslation =
863 			translator.translate();
864 
865 		int expectedMsgID = ErrorManager.MSG_ISOLATED_RULE_SCOPE;
866 		Object expectedArg = "a";
867 		GrammarSemanticsMessage expectedMessage =
868 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
869 		checkError(equeue, expectedMessage);
870 	}
871 
testNonDynamicAttributeOutsideRule()872 	@Test public void testNonDynamicAttributeOutsideRule() throws Exception {
873 		String action = "public void foo() { $x; }";
874 		String expecting = action;
875 
876 		ErrorQueue equeue = new ErrorQueue();
877 		ErrorManager.setErrorListener(equeue);
878 		Grammar g = new Grammar(
879 			"parser grammar t;\n"+
880 				"@members {'+action+'}\n" +
881 				"a : ;\n");
882 		Tool antlr = newTool();
883 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
884 		ActionTranslator translator = new ActionTranslator(generator,
885 			null,
886 			new CommonToken(ANTLRParser.ACTION,action),0);
887 		String found = translator.translate();		assertEquals(expecting, found);
888 
889 		int expectedMsgID = ErrorManager.MSG_ATTRIBUTE_REF_NOT_IN_RULE;
890 		Object expectedArg = "x";
891 		GrammarSemanticsMessage expectedMessage =
892 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
893 		checkError(equeue, expectedMessage);
894 	}
895 
testNonDynamicAttributeOutsideRule2()896 	@Test public void testNonDynamicAttributeOutsideRule2() throws Exception {
897 		String action = "public void foo() { $x.y; }";
898 		String expecting = action;
899 
900 		ErrorQueue equeue = new ErrorQueue();
901 		ErrorManager.setErrorListener(equeue);
902 		Grammar g = new Grammar(
903 			"parser grammar t;\n"+
904 				"@members {'+action+'}\n" +
905 				"a : ;\n");
906 		Tool antlr = newTool();
907 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
908 		ActionTranslator translator = new ActionTranslator(generator,
909 			null,
910 			new CommonToken(ANTLRParser.ACTION,action),0);
911 		String found = translator.translate();
912 		assertEquals(expecting, found);
913 
914 		int expectedMsgID = ErrorManager.MSG_ATTRIBUTE_REF_NOT_IN_RULE;
915 		Object expectedArg = "x";
916 		Object expectedArg2 = "y";
917 		GrammarSemanticsMessage expectedMessage =
918 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
919 		checkError(equeue, expectedMessage);
920 	}
921 
922 	// D Y N A M I C A L L Y  S C O P E D  A T T R I B U T E S
923 
testBasicGlobalScope()924 	@Test public void testBasicGlobalScope() throws Exception {
925 		String action = "$Symbols::names.add($id.text);";
926 		String expecting = "Symbols_stack.peek().names.add((id!=null?id.getText():null));";
927 
928 		ErrorQueue equeue = new ErrorQueue();
929 		ErrorManager.setErrorListener(equeue);
930 		Grammar g = new Grammar(
931 			"grammar t;\n"+
932 				"scope Symbols {\n" +
933 				"  int n;\n" +
934 				"  List names;\n" +
935 				"}\n" +
936 				"a scope Symbols; : (id=ID ';' {"+action+"} )+\n" +
937 				"  ;\n" +
938 				"ID : 'a';\n");
939 		Tool antlr = newTool();
940 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
941 		g.setCodeGenerator(generator);
942 		generator.genRecognizer(); // forces load of templates
943 		ActionTranslator translator = new ActionTranslator(generator,"a",
944 			new CommonToken(ANTLRParser.ACTION,action),1);
945 		String found = translator.translate();
946 		assertEquals(expecting, found);
947 
948 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
949 	}
950 
testUnknownGlobalScope()951 	@Test public void testUnknownGlobalScope() throws Exception {
952 		String action = "$Symbols::names.add($id.text);";
953 
954 		ErrorQueue equeue = new ErrorQueue();
955 		ErrorManager.setErrorListener(equeue);
956 		Grammar g = new Grammar(
957 			"grammar t;\n"+
958 				"a scope Symbols; : (id=ID ';' {"+action+"} )+\n" +
959 				"  ;\n" +
960 				"ID : 'a';\n");
961 		Tool antlr = newTool();
962 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
963 		g.setCodeGenerator(generator);
964 		generator.genRecognizer(); // forces load of templates
965 		ActionTranslator translator = new ActionTranslator(generator,"a",
966 			new CommonToken(ANTLRParser.ACTION,action),1);
967 
968 		assertEquals("unexpected errors: "+equeue, 2, equeue.errors.size());
969 
970 		int expectedMsgID = ErrorManager.MSG_UNKNOWN_DYNAMIC_SCOPE;
971 		Object expectedArg = "Symbols";
972 		GrammarSemanticsMessage expectedMessage =
973 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
974 		checkError(equeue, expectedMessage);
975 	}
976 
testIndexedGlobalScope()977 	@Test public void testIndexedGlobalScope() throws Exception {
978 		String action = "$Symbols[-1]::names.add($id.text);";
979 		String expecting =
980 			"Symbols_stack.elementAt(Symbols_stack.size()-1-1).names.add((id!=null?id.getText():null));";
981 
982 		ErrorQueue equeue = new ErrorQueue();
983 		ErrorManager.setErrorListener(equeue);
984 		Grammar g = new Grammar(
985 			"grammar t;\n"+
986 				"scope Symbols {\n" +
987 				"  int n;\n" +
988 				"  List names;\n" +
989 				"}\n" +
990 				"a scope Symbols; : (id=ID ';' {"+action+"} )+\n" +
991 				"  ;\n" +
992 				"ID : 'a';\n");
993 		Tool antlr = newTool();
994 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
995 		g.setCodeGenerator(generator);
996 		generator.genRecognizer(); // forces load of templates
997 		ActionTranslator translator = new ActionTranslator(generator,"a",
998 			new CommonToken(ANTLRParser.ACTION,action),1);
999 		String found = translator.translate();
1000 		assertEquals(expecting, found);
1001 
1002 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1003 	}
1004 
test0IndexedGlobalScope()1005 	@Test public void test0IndexedGlobalScope() throws Exception {
1006 		String action = "$Symbols[0]::names.add($id.text);";
1007 		String expecting =
1008 			"Symbols_stack.elementAt(0).names.add((id!=null?id.getText():null));";
1009 
1010 		ErrorQueue equeue = new ErrorQueue();
1011 		ErrorManager.setErrorListener(equeue);
1012 		Grammar g = new Grammar(
1013 			"grammar t;\n"+
1014 				"scope Symbols {\n" +
1015 				"  int n;\n" +
1016 				"  List names;\n" +
1017 				"}\n" +
1018 				"a scope Symbols; : (id=ID ';' {"+action+"} )+\n" +
1019 				"  ;\n" +
1020 				"ID : 'a';\n");
1021 		Tool antlr = newTool();
1022 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1023 		g.setCodeGenerator(generator);
1024 		generator.genRecognizer(); // forces load of templates
1025 		ActionTranslator translator = new ActionTranslator(generator,"a",
1026 			new CommonToken(ANTLRParser.ACTION,action),1);
1027 		String found = translator.translate();
1028 		assertEquals(expecting, found);
1029 
1030 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1031 	}
1032 
testAbsoluteIndexedGlobalScope()1033 	@Test public void testAbsoluteIndexedGlobalScope() throws Exception {
1034 		String action = "$Symbols[3]::names.add($id.text);";
1035 		String expecting =
1036 			"Symbols_stack.elementAt(3).names.add((id!=null?id.getText():null));";
1037 
1038 		ErrorQueue equeue = new ErrorQueue();
1039 		ErrorManager.setErrorListener(equeue);
1040 		Grammar g = new Grammar(
1041 			"grammar t;\n"+
1042 				"scope Symbols {\n" +
1043 				"  int n;\n" +
1044 				"  List names;\n" +
1045 				"}\n" +
1046 				"a scope Symbols; : (id=ID ';' {"+action+"} )+\n" +
1047 				"  ;\n" +
1048 				"ID : 'a';\n");
1049 		Tool antlr = newTool();
1050 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1051 		g.setCodeGenerator(generator);
1052 		generator.genRecognizer(); // forces load of templates
1053 		ActionTranslator translator = new ActionTranslator(generator,"a",
1054 			new CommonToken(ANTLRParser.ACTION,action),1);
1055 		String found = translator.translate();
1056 		assertEquals(expecting, found);
1057 
1058 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1059 	}
1060 
testScopeAndAttributeWithUnderscore()1061 	@Test public void testScopeAndAttributeWithUnderscore() throws Exception {
1062 		String action = "$foo_bar::a_b;";
1063 		String expecting = "foo_bar_stack.peek().a_b;";
1064 
1065 		ErrorQueue equeue = new ErrorQueue();
1066 		ErrorManager.setErrorListener(equeue);
1067 		Grammar g = new Grammar(
1068 			"grammar t;\n"+
1069 				"scope foo_bar {\n" +
1070 				"  int a_b;\n" +
1071 				"}\n" +
1072 				"a scope foo_bar; : (ID {"+action+"} )+\n" +
1073 				"  ;\n" +
1074 				"ID : 'a';\n");
1075 		Tool antlr = newTool();
1076 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1077 		g.setCodeGenerator(generator);
1078 		generator.genRecognizer(); // forces load of templates
1079 		ActionTranslator translator = new ActionTranslator(generator,"a",
1080 			new CommonToken(ANTLRParser.ACTION,action),1);
1081 		String found = translator.translate();
1082 		assertEquals(expecting, found);
1083 
1084 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1085 	}
1086 
testSharedGlobalScope()1087 	@Test public void testSharedGlobalScope() throws Exception {
1088 		String action = "$Symbols::x;";
1089 		String expecting = "Symbols_stack.peek().x;";
1090 
1091 		ErrorQueue equeue = new ErrorQueue();
1092 		ErrorManager.setErrorListener(equeue);
1093 		Grammar g = new Grammar(
1094 			"grammar t;\n"+
1095 				"scope Symbols {\n" +
1096 				"  String x;\n" +
1097 				"}\n" +
1098 				"a\n"+
1099 				"scope { int y; }\n"+
1100 				"scope Symbols;\n" +
1101 				" : b {"+action+"}\n" +
1102 				" ;\n" +
1103 				"b : ID {$Symbols::x=$ID.text} ;\n" +
1104 				"ID : 'a';\n");
1105 		Tool antlr = newTool();
1106 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1107 		g.setCodeGenerator(generator);
1108 		generator.genRecognizer(); // forces load of templates
1109 		ActionTranslator translator = new ActionTranslator(generator,"a",
1110 			new CommonToken(ANTLRParser.ACTION,action),1);
1111 		String found = translator.translate();
1112 		assertEquals(expecting, found);
1113 
1114 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1115 	}
1116 
testGlobalScopeOutsideRule()1117 	@Test public void testGlobalScopeOutsideRule() throws Exception {
1118 		String action = "public void foo() {$Symbols::names.add('foo');}";
1119 		String expecting = "public void foo() {Symbols_stack.peek().names.add('foo');}";
1120 
1121 		ErrorQueue equeue = new ErrorQueue();
1122 		ErrorManager.setErrorListener(equeue);
1123 		Grammar g = new Grammar(
1124 			"grammar t;\n"+
1125 				"scope Symbols {\n" +
1126 				"  int n;\n" +
1127 				"  List names;\n" +
1128 				"}\n" +
1129 				"@members {'+action+'}\n" +
1130 				"a : \n" +
1131 				"  ;\n");
1132 		Tool antlr = newTool();
1133 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1134 		g.setCodeGenerator(generator);
1135 		generator.genRecognizer(); // forces load of templates
1136 		ActionTranslator translator = new ActionTranslator(generator,"a",
1137 			new CommonToken(ANTLRParser.ACTION,action),1);
1138 		String found = translator.translate();
1139 		assertEquals(expecting, found);
1140 
1141 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1142 	}
1143 
testRuleScopeOutsideRule()1144 	@Test public void testRuleScopeOutsideRule() throws Exception {
1145 		String action = "public void foo() {$a::name;}";
1146 		String expecting = "public void foo() {a_stack.peek().name;}";
1147 
1148 		ErrorQueue equeue = new ErrorQueue();
1149 		ErrorManager.setErrorListener(equeue);
1150 		Grammar g = new Grammar(
1151 			"grammar t;\n"+
1152 				"@members {"+action+"}\n" +
1153 				"a\n" +
1154 				"scope { String name; }\n" +
1155 				"  : {foo();}\n" +
1156 				"  ;\n");
1157 		Tool antlr = newTool();
1158 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1159 		g.setCodeGenerator(generator);
1160 		generator.genRecognizer(); // forces load of templates
1161 		ActionTranslator translator = new ActionTranslator(generator,
1162 			null,
1163 			new CommonToken(ANTLRParser.ACTION,action),0);
1164 		String found = translator.translate();		assertEquals(expecting, found);
1165 
1166 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1167 	}
1168 
testBasicRuleScope()1169 	@Test public void testBasicRuleScope() throws Exception {
1170 		String action = "$a::n;";
1171 		String expecting = "a_stack.peek().n;";
1172 
1173 		ErrorQueue equeue = new ErrorQueue();
1174 		ErrorManager.setErrorListener(equeue);
1175 		Grammar g = new Grammar(
1176 			"grammar t;\n"+
1177 				"a\n" +
1178 				"scope {\n" +
1179 				"  int n;\n" +
1180 				"} : {"+action+"}\n" +
1181 				"  ;\n");
1182 		Tool antlr = newTool();
1183 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1184 		g.setCodeGenerator(generator);
1185 		generator.genRecognizer(); // forces load of templates
1186 		ActionTranslator translator = new ActionTranslator(generator,"a",
1187 			new CommonToken(ANTLRParser.ACTION,action),1);
1188 		String found = translator.translate();
1189 		assertEquals(expecting, found);
1190 
1191 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1192 	}
1193 
testUnqualifiedRuleScopeAccessInsideRule()1194 	@Test public void testUnqualifiedRuleScopeAccessInsideRule() throws Exception {
1195 		String action = "$n;";
1196 		String expecting = action;
1197 
1198 		ErrorQueue equeue = new ErrorQueue();
1199 		ErrorManager.setErrorListener(equeue);
1200 		Grammar g = new Grammar(
1201 			"grammar t;\n"+
1202 				"a\n" +
1203 				"scope {\n" +
1204 				"  int n;\n" +
1205 				"} : {"+action+"}\n" +
1206 				"  ;\n");
1207 		Tool antlr = newTool();
1208 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1209 		g.setCodeGenerator(generator);
1210 		generator.genRecognizer(); // forces load of templates
1211 
1212 		int expectedMsgID = ErrorManager.MSG_ISOLATED_RULE_ATTRIBUTE;
1213 		Object expectedArg = "n";
1214 		Object expectedArg2 = null;
1215 		GrammarSemanticsMessage expectedMessage =
1216 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg,
1217 				expectedArg2);
1218 		checkError(equeue, expectedMessage);
1219 	}
1220 
testIsolatedDynamicRuleScopeRef()1221 	@Test public void testIsolatedDynamicRuleScopeRef() throws Exception {
1222 		String action = "$a;"; // refers to stack not top of stack
1223 		String expecting = "a_stack;";
1224 
1225 		ErrorQueue equeue = new ErrorQueue();
1226 		ErrorManager.setErrorListener(equeue);
1227 		Grammar g = new Grammar(
1228 			"grammar t;\n"+
1229 				"a\n" +
1230 				"scope {\n" +
1231 				"  int n;\n" +
1232 				"} : b ;\n" +
1233 				"b : {"+action+"}\n" +
1234 				"  ;\n");
1235 		Tool antlr = newTool();
1236 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1237 		g.setCodeGenerator(generator);
1238 		generator.genRecognizer(); // forces load of templates
1239 		ActionTranslator translator = new ActionTranslator(generator, "b",
1240 			new CommonToken(ANTLRParser.ACTION,action),1);
1241 		String found = translator.translate();
1242 		assertEquals(expecting, found);
1243 
1244 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1245 	}
1246 
testDynamicRuleScopeRefInSubrule()1247 	@Test public void testDynamicRuleScopeRefInSubrule() throws Exception {
1248 		String action = "$a::n;";
1249 		String expecting = "a_stack.peek().n;";
1250 
1251 		ErrorQueue equeue = new ErrorQueue();
1252 		ErrorManager.setErrorListener(equeue);
1253 		Grammar g = new Grammar(
1254 			"grammar t;\n"+
1255 				"a\n" +
1256 				"scope {\n" +
1257 				"  float n;\n" +
1258 				"} : b ;\n" +
1259 				"b : {"+action+"}\n" +
1260 				"  ;\n");
1261 		Tool antlr = newTool();
1262 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1263 		g.setCodeGenerator(generator);
1264 		generator.genRecognizer(); // forces load of templates
1265 		ActionTranslator translator = new ActionTranslator(generator, "b",
1266 			new CommonToken(ANTLRParser.ACTION,action),1);
1267 		String found = translator.translate();
1268 		assertEquals(expecting, found);
1269 
1270 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1271 	}
1272 
testIsolatedGlobalScopeRef()1273 	@Test public void testIsolatedGlobalScopeRef() throws Exception {
1274 		String action = "$Symbols;";
1275 		String expecting = "Symbols_stack;";
1276 
1277 		ErrorQueue equeue = new ErrorQueue();
1278 		ErrorManager.setErrorListener(equeue);
1279 		Grammar g = new Grammar(
1280 			"grammar t;\n"+
1281 				"scope Symbols {\n" +
1282 				"  String x;\n" +
1283 				"}\n" +
1284 				"a\n"+
1285 				"scope { int y; }\n"+
1286 				"scope Symbols;\n" +
1287 				" : b {"+action+"}\n" +
1288 				" ;\n" +
1289 				"b : ID {$Symbols::x=$ID.text} ;\n" +
1290 				"ID : 'a';\n");
1291 		Tool antlr = newTool();
1292 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1293 		g.setCodeGenerator(generator);
1294 		generator.genRecognizer(); // forces load of templates
1295 		ActionTranslator translator = new ActionTranslator(generator,"a",
1296 			new CommonToken(ANTLRParser.ACTION,action),1);
1297 		String found = translator.translate();
1298 		assertEquals(expecting, found);
1299 
1300 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1301 	}
1302 
testRuleScopeFromAnotherRule()1303 	@Test public void testRuleScopeFromAnotherRule() throws Exception {
1304 		String action = "$a::n;"; // must be qualified
1305 		String expecting = "a_stack.peek().n;";
1306 
1307 		ErrorQueue equeue = new ErrorQueue();
1308 		ErrorManager.setErrorListener(equeue);
1309 		Grammar g = new Grammar(
1310 			"grammar t;\n"+
1311 				"a\n" +
1312 				"scope {\n" +
1313 				"  boolean n;\n" +
1314 				"} : b\n" +
1315 				"  ;\n" +
1316 				"b : {"+action+"}\n" +
1317 				"  ;\n");
1318 		Tool antlr = newTool();
1319 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1320 		g.setCodeGenerator(generator);
1321 		generator.genRecognizer(); // forces load of templates
1322 		ActionTranslator translator = new ActionTranslator(generator, "b",
1323 			new CommonToken(ANTLRParser.ACTION,action),1);
1324 		String found = translator.translate();
1325 		assertEquals(expecting, found);
1326 
1327 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1328 	}
1329 
testFullyQualifiedRefToCurrentRuleParameter()1330 	@Test public void testFullyQualifiedRefToCurrentRuleParameter() throws Exception {
1331 		String action = "$a.i;";
1332 		String expecting = "i;";
1333 
1334 		ErrorQueue equeue = new ErrorQueue();
1335 		ErrorManager.setErrorListener(equeue);
1336 		Grammar g = new Grammar(
1337 			"grammar t;\n"+
1338 				"a[int i]: {"+action+"}\n" +
1339 				"  ;\n");
1340 		Tool antlr = newTool();
1341 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1342 		g.setCodeGenerator(generator);
1343 		generator.genRecognizer(); // forces load of templates
1344 		ActionTranslator translator = new ActionTranslator(generator,"a",
1345 			new CommonToken(ANTLRParser.ACTION,action),1);
1346 		String found = translator.translate();		assertEquals(expecting, found);
1347 
1348 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1349 	}
1350 
testFullyQualifiedRefToCurrentRuleRetVal()1351 	@Test public void testFullyQualifiedRefToCurrentRuleRetVal() throws Exception {
1352 		String action = "$a.i;";
1353 		String expecting = "retval.i;";
1354 
1355 		ErrorQueue equeue = new ErrorQueue();
1356 		ErrorManager.setErrorListener(equeue);
1357 		Grammar g = new Grammar(
1358 			"grammar t;\n"+
1359 				"a returns [int i, int j]: {"+action+"}\n" +
1360 				"  ;\n");
1361 		Tool antlr = newTool();
1362 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1363 		g.setCodeGenerator(generator);
1364 		generator.genRecognizer(); // forces load of templates
1365 		ActionTranslator translator = new ActionTranslator(generator,"a",
1366 			new CommonToken(ANTLRParser.ACTION,action),1);
1367 		String found = translator.translate();
1368 		assertEquals(expecting, found);
1369 
1370 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1371 	}
1372 
testSetFullyQualifiedRefToCurrentRuleRetVal()1373 	@Test public void testSetFullyQualifiedRefToCurrentRuleRetVal() throws Exception {
1374 		String action = "$a.i = 1;";
1375 		String expecting = "retval.i = 1;";
1376 
1377 		ErrorQueue equeue = new ErrorQueue();
1378 		ErrorManager.setErrorListener(equeue);
1379 		Grammar g = new Grammar(
1380 			"grammar t;\n"+
1381 				"a returns [int i, int j]: {"+action+"}\n" +
1382 				"  ;\n");
1383 		Tool antlr = newTool();
1384 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1385 		g.setCodeGenerator(generator);
1386 		generator.genRecognizer(); // forces load of templates
1387 		ActionTranslator translator = new ActionTranslator(generator,"a",
1388 			new CommonToken(ANTLRParser.ACTION,action),1);
1389 		String found = translator.translate();
1390 		assertEquals(expecting, found);
1391 
1392 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1393 	}
1394 
testIsolatedRefToCurrentRule()1395 	@Test public void testIsolatedRefToCurrentRule() throws Exception {
1396 		String action = "$a;";
1397 		String expecting = "";
1398 
1399 		ErrorQueue equeue = new ErrorQueue();
1400 		ErrorManager.setErrorListener(equeue);
1401 		Grammar g = new Grammar(
1402 			"grammar t;\n"+
1403 				"a : 'a' {"+action+"}\n" +
1404 				"  ;\n");
1405 		Tool antlr = newTool();
1406 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1407 		g.setCodeGenerator(generator);
1408 		generator.genRecognizer(); // forces load of templates
1409 
1410 		int expectedMsgID = ErrorManager.MSG_ISOLATED_RULE_SCOPE;
1411 		Object expectedArg = "a";
1412 		Object expectedArg2 = null;
1413 		GrammarSemanticsMessage expectedMessage =
1414 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg,
1415 				expectedArg2);
1416 		checkError(equeue, expectedMessage);
1417 	}
1418 
testIsolatedRefToRule()1419 	@Test public void testIsolatedRefToRule() throws Exception {
1420 		String action = "$x;";
1421 
1422 		ErrorQueue equeue = new ErrorQueue();
1423 		ErrorManager.setErrorListener(equeue);
1424 		Grammar g = new Grammar(
1425 			"grammar t;\n"+
1426 				"a : x=b {"+action+"}\n" +
1427 				"  ;\n" +
1428 				"b : 'b' ;\n");
1429 		Tool antlr = newTool();
1430 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1431 		g.setCodeGenerator(generator);
1432 		generator.genRecognizer(); // forces load of templates
1433 
1434 		int expectedMsgID = ErrorManager.MSG_ISOLATED_RULE_SCOPE;
1435 		Object expectedArg = "x";
1436 		GrammarSemanticsMessage expectedMessage =
1437 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
1438 		checkError(equeue, expectedMessage);
1439 	}
1440 
1441 	/*  I think these have to be errors $a.x makes no sense.
1442 	@Test public void testFullyQualifiedRefToLabelInCurrentRule() throws Exception {
1443 			String action = "$a.x;";
1444 			String expecting = "x;";
1445 
1446 			ErrorQueue equeue = new ErrorQueue();
1447 			ErrorManager.setErrorListener(equeue);
1448 			Grammar g = new Grammar(
1449 				"grammar t;\n"+
1450 					"a : x='a' {"+action+"}\n" +
1451 					"  ;\n");
1452 			Tool antlr = newTool();
1453 			CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1454 			g.setCodeGenerator(generator);
1455 			generator.genRecognizer(); // forces load of templates
1456 			ActionTranslator translator = new ActionTranslator(generator,"a",
1457 															   new CommonToken(ANTLRParser.ACTION,action),1);
1458 			String rawTranslation =
1459 				translator.translate();
1460 			STGroup templates =
1461 				new STGroup();
1462 			ST actionST = new ST(templates, rawTranslation);
1463 			String found = actionST.render();
1464 			assertEquals(expecting, found);
1465 
1466 			assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1467 		}
1468 
1469 	@Test public void testFullyQualifiedRefToListLabelInCurrentRule() throws Exception {
1470 		String action = "$a.x;"; // must be qualified
1471 		String expecting = "list_x;";
1472 
1473 		ErrorQueue equeue = new ErrorQueue();
1474 		ErrorManager.setErrorListener(equeue);
1475 		Grammar g = new Grammar(
1476 			"grammar t;\n"+
1477 				"a : x+='a' {"+action+"}\n" +
1478 				"  ;\n");
1479 		Tool antlr = newTool();
1480 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1481 		g.setCodeGenerator(generator);
1482 		generator.genRecognizer(); // forces load of templates
1483 		ActionTranslator translator = new ActionTranslator(generator,"a",
1484 														   new CommonToken(ANTLRParser.ACTION,action),1);
1485 		String found = translator.translate();		assertEquals(expecting, found);
1486 
1487 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1488 	}
1489 */
testFullyQualifiedRefToTemplateAttributeInCurrentRule()1490 	@Test public void testFullyQualifiedRefToTemplateAttributeInCurrentRule() throws Exception {
1491 		String action = "$a.st;"; // can be qualified
1492 		String expecting = "retval.st;";
1493 
1494 		ErrorQueue equeue = new ErrorQueue();
1495 		ErrorManager.setErrorListener(equeue);
1496 		Grammar g = new Grammar(
1497 			"parser grammar t;\n" +
1498 				"options {output=template;}\n"+
1499 				"a : (A->{$A.text}) {"+action+"}\n" +
1500 				"  ;\n");
1501 		Tool antlr = newTool();
1502 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1503 		g.setCodeGenerator(generator);
1504 		generator.genRecognizer(); // forces load of templates
1505 		ActionTranslator translator = new ActionTranslator(generator,"a",
1506 			new CommonToken(ANTLRParser.ACTION,action),1);
1507 		String found = translator.translate();
1508 		assertEquals(expecting, found);
1509 
1510 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1511 	}
1512 
testRuleRefWhenRuleHasScope()1513 	@Test public void testRuleRefWhenRuleHasScope() throws Exception {
1514 		String action = "$b.start;";
1515 		String expecting = "(b1!=null?(b1.start):null);";
1516 
1517 		ErrorQueue equeue = new ErrorQueue();
1518 		ErrorManager.setErrorListener(equeue);
1519 		Grammar g = new Grammar(
1520 			"grammar t;\n" +
1521 				"a : b {###"+action+"!!!} ;\n" +
1522 				"b\n" +
1523 				"scope {\n" +
1524 				"  int n;\n" +
1525 				"} : 'b' \n" +
1526 				"  ;\n");
1527 		Tool antlr = newTool();
1528 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1529 		g.setCodeGenerator(generator);
1530 		generator.genRecognizer(); // forces load of templates
1531 
1532 		ST codeST = generator.getRecognizerST();
1533 		String code = codeST.render();
1534 		String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!"));
1535 		assertEquals(expecting, found);
1536 
1537 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1538 	}
1539 
testDynamicScopeRefOkEvenThoughRuleRefExists()1540 	@Test public void testDynamicScopeRefOkEvenThoughRuleRefExists() throws Exception {
1541 		String action = "$b::n;";
1542 		String expecting = "b_stack.peek().n;";
1543 
1544 		ErrorQueue equeue = new ErrorQueue();
1545 		ErrorManager.setErrorListener(equeue);
1546 		Grammar g = new Grammar(
1547 			"grammar t;\n" +
1548 				"s : b ;\n"+
1549 				"b\n" +
1550 				"scope {\n" +
1551 				"  int n;\n" +
1552 				"} : '(' b ')' {"+action+"}\n" + // refers to current invocation's n
1553 				"  ;\n");
1554 		Tool antlr = newTool();
1555 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1556 		g.setCodeGenerator(generator);
1557 		generator.genRecognizer(); // forces load of templates
1558 		ActionTranslator translator = new ActionTranslator(generator, "b",
1559 			new CommonToken(ANTLRParser.ACTION,action),1);
1560 		String found = translator.translate();		assertEquals(expecting, found);
1561 
1562 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1563 	}
1564 
testRefToTemplateAttributeForCurrentRule()1565 	@Test public void testRefToTemplateAttributeForCurrentRule() throws Exception {
1566 		String action = "$st=null;";
1567 		String expecting = "retval.st =null;";
1568 
1569 		ErrorQueue equeue = new ErrorQueue();
1570 		ErrorManager.setErrorListener(equeue);
1571 		Grammar g = new Grammar(
1572 			"parser grammar t;\n" +
1573 				"options {output=template;}\n"+
1574 				"a : {"+action+"}\n" +
1575 				"  ;\n");
1576 		Tool antlr = newTool();
1577 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1578 		g.setCodeGenerator(generator);
1579 		generator.genRecognizer(); // forces load of templates
1580 		ActionTranslator translator = new ActionTranslator(generator,"a",
1581 			new CommonToken(ANTLRParser.ACTION,action),1);
1582 		String found = translator.translate();		assertEquals(expecting, found);
1583 
1584 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1585 	}
1586 
testRefToTextAttributeForCurrentRule()1587 	@Test public void testRefToTextAttributeForCurrentRule() throws Exception {
1588 		String action = "$text";
1589 		String expecting = "input.toString(retval.start,input.LT(-1))";
1590 
1591 		ErrorQueue equeue = new ErrorQueue();
1592 		ErrorManager.setErrorListener(equeue);
1593 		Grammar g = new Grammar(
1594 			"parser grammar t;\n" +
1595 				"options {output=template;}\n"+
1596 				"a : {###"+action+"!!!}\n" +
1597 				"  ;\n");
1598 		Tool antlr = newTool();
1599 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1600 		g.setCodeGenerator(generator);
1601 		generator.genRecognizer(); // codegen phase sets some vars we need
1602 		ST codeST = generator.getRecognizerST();
1603 		String code = codeST.render();
1604 		String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!"));
1605 		assertEquals(expecting, found);
1606 
1607 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1608 	}
1609 
testRefToStartAttributeForCurrentRule()1610 	@Test public void testRefToStartAttributeForCurrentRule() throws Exception {
1611 		String action = "$start;";
1612 		String expecting = "(retval.start);";
1613 
1614 		ErrorQueue equeue = new ErrorQueue();
1615 		ErrorManager.setErrorListener(equeue);
1616 		Grammar g = new Grammar(
1617 			"parser grammar t;\n" +
1618 				"a : {###"+action+"!!!}\n" +
1619 				"  ;\n");
1620 		Tool antlr = newTool();
1621 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1622 		g.setCodeGenerator(generator);
1623 		generator.genRecognizer(); // forces load of templates
1624 		ActionTranslator translator = new ActionTranslator(generator,"a",
1625 			new CommonToken(ANTLRParser.ACTION,action),1);
1626 		ST codeST = generator.getRecognizerST();
1627 		String code = codeST.render();
1628 		String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!"));
1629 		assertEquals(expecting, found);
1630 
1631 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1632 	}
1633 
testTokenLabelFromMultipleAlts()1634 	@Test public void testTokenLabelFromMultipleAlts() throws Exception {
1635 		String action = "$ID.text;"; // must be qualified
1636 		String action2 = "$INT.text;"; // must be qualified
1637 		String expecting = "(ID1!=null?ID1.getText():null);";
1638 		String expecting2 = "(INT2!=null?INT2.getText():null);";
1639 
1640 		ErrorQueue equeue = new ErrorQueue();
1641 		ErrorManager.setErrorListener(equeue);
1642 		Grammar g = new Grammar(
1643 			"grammar t;\n"+
1644 				"a : ID {"+action+"}\n" +
1645 				"  | INT {"+action2+"}\n" +
1646 				"  ;\n" +
1647 				"ID : 'a';\n" +
1648 				"INT : '0';\n");
1649 		Tool antlr = newTool();
1650 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1651 		g.setCodeGenerator(generator);
1652 		generator.genRecognizer(); // forces load of templates
1653 		ActionTranslator translator = new ActionTranslator(generator,"a",
1654 			new CommonToken(ANTLRParser.ACTION,action),1);
1655 		String found = translator.translate();		assertEquals(expecting, found);
1656 
1657 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1658 		translator = new ActionTranslator(generator,
1659 			"a",
1660 			new CommonToken(ANTLRParser.ACTION,action2),2);
1661 		found = translator.translate();
1662 		assertEquals(expecting2, found);
1663 
1664 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1665 	}
1666 
testRuleLabelFromMultipleAlts()1667 	@Test public void testRuleLabelFromMultipleAlts() throws Exception {
1668 		String action = "$b.text;"; // must be qualified
1669 		String action2 = "$c.text;"; // must be qualified
1670 		String expecting = "(b1!=null?input.toString(b1.start,b1.stop):null);";
1671 		String expecting2 = "(c2!=null?input.toString(c2.start,c2.stop):null);";
1672 
1673 		ErrorQueue equeue = new ErrorQueue();
1674 		ErrorManager.setErrorListener(equeue);
1675 		Grammar g = new Grammar(
1676 			"grammar t;\n"+
1677 				"a : b {###"+action+"!!!}\n" +
1678 				"  | c {^^^"+action2+"&&&}\n" +
1679 				"  ;\n" +
1680 				"b : 'a';\n" +
1681 				"c : '0';\n");
1682 		Tool antlr = newTool();
1683 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1684 		g.setCodeGenerator(generator);
1685 		generator.genRecognizer(); // codegen phase sets some vars we need
1686 		ST codeST = generator.getRecognizerST();
1687 		String code = codeST.render();
1688 		String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!"));
1689 		assertEquals(expecting, found);
1690 		found = code.substring(code.indexOf("^^^")+3,code.indexOf("&&&"));
1691 		assertEquals(expecting2, found);
1692 
1693 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1694 	}
1695 
testUnknownDynamicAttribute()1696 	@Test public void testUnknownDynamicAttribute() throws Exception {
1697 		String action = "$a::x";
1698 		String expecting = action;
1699 
1700 		ErrorQueue equeue = new ErrorQueue();
1701 		ErrorManager.setErrorListener(equeue);
1702 		Grammar g = new Grammar(
1703 			"grammar t;\n"+
1704 				"a\n" +
1705 				"scope {\n" +
1706 				"  int n;\n" +
1707 				"} : {"+action+"}\n" +
1708 				"  ;\n");
1709 		Tool antlr = newTool();
1710 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1711 		g.setCodeGenerator(generator);
1712 		generator.genRecognizer(); // forces load of templates
1713 		ActionTranslator translator =
1714 			new ActionTranslator(generator,
1715 				"a",
1716 				new CommonToken(ANTLRParser.ACTION,action),1);
1717 		String found = translator.translate();		assertEquals(expecting, found);
1718 
1719 		int expectedMsgID = ErrorManager.MSG_UNKNOWN_DYNAMIC_SCOPE_ATTRIBUTE;
1720 		Object expectedArg = "a";
1721 		Object expectedArg2 = "x";
1722 		GrammarSemanticsMessage expectedMessage =
1723 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
1724 		checkError(equeue, expectedMessage);
1725 	}
1726 
testUnknownGlobalDynamicAttribute()1727 	@Test public void testUnknownGlobalDynamicAttribute() throws Exception {
1728 		String action = "$Symbols::x";
1729 		String expecting = action;
1730 
1731 		ErrorQueue equeue = new ErrorQueue();
1732 		ErrorManager.setErrorListener(equeue);
1733 		Grammar g = new Grammar(
1734 			"grammar t;\n"+
1735 				"scope Symbols {\n" +
1736 				"  int n;\n" +
1737 				"}\n" +
1738 				"a : {'+action+'}\n" +
1739 				"  ;\n");
1740 		Tool antlr = newTool();
1741 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1742 		g.setCodeGenerator(generator);
1743 		generator.genRecognizer(); // forces load of templates
1744 		ActionTranslator translator =
1745 			new ActionTranslator(generator,
1746 				"a",
1747 				new CommonToken(ANTLRParser.ACTION,action),1);
1748 		String found = translator.translate();		assertEquals(expecting, found);
1749 
1750 		int expectedMsgID = ErrorManager.MSG_UNKNOWN_DYNAMIC_SCOPE_ATTRIBUTE;
1751 		Object expectedArg = "Symbols";
1752 		Object expectedArg2 = "x";
1753 		GrammarSemanticsMessage expectedMessage =
1754 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
1755 		checkError(equeue, expectedMessage);
1756 	}
1757 
testUnqualifiedRuleScopeAttribute()1758 	@Test public void testUnqualifiedRuleScopeAttribute() throws Exception {
1759 		String action = "$n;"; // must be qualified
1760 		String expecting = "$n;";
1761 
1762 		ErrorQueue equeue = new ErrorQueue();
1763 		ErrorManager.setErrorListener(equeue);
1764 		Grammar g = new Grammar(
1765 			"grammar t;\n"+
1766 				"a\n" +
1767 				"scope {\n" +
1768 				"  int n;\n" +
1769 				"} : b\n" +
1770 				"  ;\n" +
1771 				"b : {'+action+'}\n" +
1772 				"  ;\n");
1773 		Tool antlr = newTool();
1774 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1775 		ActionTranslator translator =
1776 			new ActionTranslator(generator,
1777 				"b",
1778 				new CommonToken(ANTLRParser.ACTION,action),1);
1779 		String found = translator.translate();		assertEquals(expecting, found);
1780 
1781 		int expectedMsgID = ErrorManager.MSG_UNKNOWN_SIMPLE_ATTRIBUTE;
1782 		Object expectedArg = "n";
1783 		Object expectedArg2 = null;
1784 		GrammarSemanticsMessage expectedMessage =
1785 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
1786 		checkError(equeue, expectedMessage);
1787 	}
1788 
testRuleAndTokenLabelTypeMismatch()1789 	@Test public void testRuleAndTokenLabelTypeMismatch() throws Exception {
1790 		ErrorQueue equeue = new ErrorQueue();
1791 		ErrorManager.setErrorListener(equeue);
1792 		Grammar g = new Grammar(
1793 			"grammar t;\n"+
1794 				"a : id='foo' id=b\n" +
1795 				"  ;\n" +
1796 				"b : ;\n");
1797 		int expectedMsgID = ErrorManager.MSG_LABEL_TYPE_CONFLICT;
1798 		Object expectedArg = "id";
1799 		Object expectedArg2 = "rule!=token";
1800 		GrammarSemanticsMessage expectedMessage =
1801 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
1802 		checkError(equeue, expectedMessage);
1803 	}
1804 
testListAndTokenLabelTypeMismatch()1805 	@Test public void testListAndTokenLabelTypeMismatch() throws Exception {
1806 		ErrorQueue equeue = new ErrorQueue();
1807 		ErrorManager.setErrorListener(equeue);
1808 		Grammar g = new Grammar(
1809 			"grammar t;\n"+
1810 				"a : ids+='a' ids='b'\n" +
1811 				"  ;\n" +
1812 				"b : ;\n");
1813 		int expectedMsgID = ErrorManager.MSG_LABEL_TYPE_CONFLICT;
1814 		Object expectedArg = "ids";
1815 		Object expectedArg2 = "token!=token-list";
1816 		GrammarSemanticsMessage expectedMessage =
1817 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
1818 		checkError(equeue, expectedMessage);
1819 	}
1820 
testListAndRuleLabelTypeMismatch()1821 	@Test public void testListAndRuleLabelTypeMismatch() throws Exception {
1822 		ErrorQueue equeue = new ErrorQueue();
1823 		ErrorManager.setErrorListener(equeue);
1824 		Grammar g = new Grammar(
1825 			"grammar t;\n" +
1826 				"options {output=AST;}\n"+
1827 				"a : bs+=b bs=b\n" +
1828 				"  ;\n" +
1829 				"b : 'b';\n");
1830 		int expectedMsgID = ErrorManager.MSG_LABEL_TYPE_CONFLICT;
1831 		Object expectedArg = "bs";
1832 		Object expectedArg2 = "rule!=rule-list";
1833 		GrammarSemanticsMessage expectedMessage =
1834 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
1835 		checkError(equeue, expectedMessage);
1836 	}
1837 
testArgReturnValueMismatch()1838 	@Test public void testArgReturnValueMismatch() throws Exception {
1839 		ErrorQueue equeue = new ErrorQueue();
1840 		ErrorManager.setErrorListener(equeue);
1841 		Grammar g = new Grammar(
1842 			"grammar t;\n"+
1843 				"a[int i] returns [int x, int i]\n" +
1844 				"  : \n" +
1845 				"  ;\n" +
1846 				"b : ;\n");
1847 		int expectedMsgID = ErrorManager.MSG_ARG_RETVAL_CONFLICT;
1848 		Object expectedArg = "i";
1849 		Object expectedArg2 = "a";
1850 		GrammarSemanticsMessage expectedMessage =
1851 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
1852 		checkError(equeue, expectedMessage);
1853 	}
1854 
testSimplePlusEqualLabel()1855 	@Test public void testSimplePlusEqualLabel() throws Exception {
1856 		String action = "$ids.size();"; // must be qualified
1857 		String expecting = "list_ids.size();";
1858 
1859 		ErrorQueue equeue = new ErrorQueue();
1860 		ErrorManager.setErrorListener(equeue);
1861 		Grammar g = new Grammar(
1862 			"parser grammar t;\n"+
1863 				"a : ids+=ID ( COMMA ids+=ID {"+action+"})* ;\n");
1864 		Tool antlr = newTool();
1865 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1866 		g.setCodeGenerator(generator);
1867 		generator.genRecognizer(); // forces load of templates
1868 		ActionTranslator translator =
1869 			new ActionTranslator(generator,
1870 				"a",
1871 				new CommonToken(ANTLRParser.ACTION,action),1);
1872 		String found = translator.translate();
1873 		assertEquals(expecting, found);
1874 
1875 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1876 	}
1877 
testPlusEqualStringLabel()1878 	@Test public void testPlusEqualStringLabel() throws Exception {
1879 		String action = "$ids.size();"; // must be qualified
1880 		String expecting = "list_ids.size();";
1881 
1882 		ErrorQueue equeue = new ErrorQueue();
1883 		ErrorManager.setErrorListener(equeue);
1884 		Grammar g = new Grammar(
1885 			"grammar t;\n"+
1886 				"a : ids+='if' ( ',' ids+=ID {"+action+"})* ;" +
1887 				"ID : 'a';\n");
1888 		Tool antlr = newTool();
1889 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1890 		g.setCodeGenerator(generator);
1891 		generator.genRecognizer(); // forces load of templates
1892 		ActionTranslator translator =
1893 			new ActionTranslator(generator,
1894 				"a",
1895 				new CommonToken(ANTLRParser.ACTION,action),1);
1896 		String found = translator.translate();
1897 		assertEquals(expecting, found);
1898 
1899 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1900 	}
1901 
testPlusEqualSetLabel()1902 	@Test public void testPlusEqualSetLabel() throws Exception {
1903 		String action = "$ids.size();"; // must be qualified
1904 		String expecting = "list_ids.size();";
1905 
1906 		ErrorQueue equeue = new ErrorQueue();
1907 		ErrorManager.setErrorListener(equeue);
1908 		Grammar g = new Grammar(
1909 			"grammar t;\n"+
1910 				"a : ids+=('a'|'b') ( ',' ids+=ID {"+action+"})* ;" +
1911 				"ID : 'a';\n");
1912 		Tool antlr = newTool();
1913 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1914 		g.setCodeGenerator(generator);
1915 		generator.genRecognizer(); // forces load of templates
1916 		ActionTranslator translator =
1917 			new ActionTranslator(generator,
1918 				"a",
1919 				new CommonToken(ANTLRParser.ACTION,action),1);
1920 		String found = translator.translate();
1921 		assertEquals(expecting, found);
1922 
1923 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1924 	}
1925 
testPlusEqualWildcardLabel()1926 	@Test public void testPlusEqualWildcardLabel() throws Exception {
1927 		String action = "$ids.size();"; // must be qualified
1928 		String expecting = "list_ids.size();";
1929 
1930 		ErrorQueue equeue = new ErrorQueue();
1931 		ErrorManager.setErrorListener(equeue);
1932 		Grammar g = new Grammar(
1933 			"grammar t;\n"+
1934 				"a : ids+=. ( ',' ids+=ID {"+action+"})* ;" +
1935 				"ID : 'a';\n");
1936 		Tool antlr = newTool();
1937 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1938 		ActionTranslator translator =
1939 			new ActionTranslator(generator,
1940 				"a",
1941 				new CommonToken(ANTLRParser.ACTION,action),1);
1942 		g.setCodeGenerator(generator);
1943 		generator.genRecognizer(); // forces load of templates
1944 		String found = translator.translate();
1945 		assertEquals(expecting, found);
1946 
1947 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1948 	}
1949 
testImplicitTokenLabel()1950 	@Test public void testImplicitTokenLabel() throws Exception {
1951 		String action = "$ID; $ID.text; $ID.getText()";
1952 		String expecting = "ID1; (ID1!=null?ID1.getText():null); ID1.getText()";
1953 
1954 		ErrorQueue equeue = new ErrorQueue();
1955 		ErrorManager.setErrorListener(equeue);
1956 		Grammar g = new Grammar(
1957 			"grammar t;\n"+
1958 				"a : ID {"+action+"} ;" +
1959 				"ID : 'a';\n");
1960 		Tool antlr = newTool();
1961 		antlr.setOutputDirectory(null); // write to /dev/null
1962 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1963 
1964 		ActionTranslator translator =
1965 			new ActionTranslator(generator,
1966 				"a",
1967 				new CommonToken(ANTLRParser.ACTION,action),1);
1968 		g.setCodeGenerator(generator);
1969 		generator.genRecognizer(); // forces load of templates
1970 		String found = translator.translate();
1971 		assertEquals(expecting, found);
1972 
1973 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1974 	}
1975 
testImplicitRuleLabel()1976 	@Test public void testImplicitRuleLabel() throws Exception {
1977 		String action = "$r.start;";
1978 		String expecting = "(r1!=null?(r1.start):null);";
1979 
1980 		ErrorQueue equeue = new ErrorQueue();
1981 		ErrorManager.setErrorListener(equeue);
1982 		Grammar g = new Grammar(
1983 			"grammar t;\n"+
1984 				"a : r {###"+action+"!!!} ;" +
1985 				"r : 'a';\n");
1986 		Tool antlr = newTool();
1987 		antlr.setOutputDirectory(null); // write to /dev/null
1988 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
1989 		g.setCodeGenerator(generator);
1990 		generator.genRecognizer();
1991 
1992 		ST codeST = generator.getRecognizerST();
1993 		String code = codeST.render();
1994 		String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!"));
1995 		assertEquals(expecting, found);
1996 
1997 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1998 	}
1999 
testReuseExistingLabelWithImplicitRuleLabel()2000 	@Test public void testReuseExistingLabelWithImplicitRuleLabel() throws Exception {
2001 		String action = "$r.start;";
2002 		String expecting = "(x!=null?(x.start):null);";
2003 
2004 		ErrorQueue equeue = new ErrorQueue();
2005 		ErrorManager.setErrorListener(equeue);
2006 		Grammar g = new Grammar(
2007 			"grammar t;\n"+
2008 				"a : x=r {###"+action+"!!!} ;" +
2009 				"r : 'a';\n");
2010 		Tool antlr = newTool();
2011 		antlr.setOutputDirectory(null); // write to /dev/null
2012 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2013 		g.setCodeGenerator(generator);
2014 		generator.genRecognizer();
2015 
2016 		ST codeST = generator.getRecognizerST();
2017 		String code = codeST.render();
2018 		String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!"));
2019 		assertEquals(expecting, found);
2020 
2021 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2022 	}
2023 
testReuseExistingListLabelWithImplicitRuleLabel()2024 	@Test public void testReuseExistingListLabelWithImplicitRuleLabel() throws Exception {
2025 		String action = "$r.start;";
2026 		String expecting = "(x!=null?(x.start):null);";
2027 
2028 		ErrorQueue equeue = new ErrorQueue();
2029 		ErrorManager.setErrorListener(equeue);
2030 		Grammar g = new Grammar(
2031 			"grammar t;\n"+
2032 				"options {output=AST;}\n" +
2033 				"a : x+=r {###"+action+"!!!} ;" +
2034 				"r : 'a';\n");
2035 		Tool antlr = newTool();
2036 		antlr.setOutputDirectory(null); // write to /dev/null
2037 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2038 		g.setCodeGenerator(generator);
2039 		generator.genRecognizer();
2040 
2041 		ST codeST = generator.getRecognizerST();
2042 		String code = codeST.render();
2043 		String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!"));
2044 		assertEquals(expecting, found);
2045 
2046 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2047 	}
2048 
testReuseExistingLabelWithImplicitTokenLabel()2049 	@Test public void testReuseExistingLabelWithImplicitTokenLabel() throws Exception {
2050 		String action = "$ID.text;";
2051 		String expecting = "(x!=null?x.getText():null);";
2052 
2053 		ErrorQueue equeue = new ErrorQueue();
2054 		ErrorManager.setErrorListener(equeue);
2055 		Grammar g = new Grammar(
2056 			"grammar t;\n"+
2057 				"a : x=ID {"+action+"} ;" +
2058 				"ID : 'a';\n");
2059 		Tool antlr = newTool();
2060 		antlr.setOutputDirectory(null); // write to /dev/null
2061 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2062 		g.setCodeGenerator(generator);
2063 		generator.genRecognizer();
2064 
2065 		ActionTranslator translator = new ActionTranslator(generator,"a",
2066 			new CommonToken(ANTLRParser.ACTION,action),1);
2067 		String found = translator.translate();
2068 		assertEquals(expecting, found);
2069 
2070 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2071 	}
2072 
testReuseExistingListLabelWithImplicitTokenLabel()2073 	@Test public void testReuseExistingListLabelWithImplicitTokenLabel() throws Exception {
2074 		String action = "$ID.text;";
2075 		String expecting = "(x!=null?x.getText():null);";
2076 
2077 		ErrorQueue equeue = new ErrorQueue();
2078 		ErrorManager.setErrorListener(equeue);
2079 		Grammar g = new Grammar(
2080 			"grammar t;\n"+
2081 				"a : x+=ID {"+action+"} ;" +
2082 				"ID : 'a';\n");
2083 		Tool antlr = newTool();
2084 		antlr.setOutputDirectory(null); // write to /dev/null
2085 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2086 		g.setCodeGenerator(generator);
2087 		generator.genRecognizer();
2088 
2089 		ActionTranslator translator = new ActionTranslator(generator,"a",
2090 			new CommonToken(ANTLRParser.ACTION,action),1);
2091 		String found = translator.translate();
2092 		assertEquals(expecting, found);
2093 
2094 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2095 	}
2096 
testRuleLabelWithoutOutputOption()2097 	@Test public void testRuleLabelWithoutOutputOption() throws Exception {
2098 		ErrorQueue equeue = new ErrorQueue();
2099 		ErrorManager.setErrorListener(equeue);
2100 		Grammar g = new Grammar(
2101 			"grammar T;\n"+
2102 				"s : x+=a ;" +
2103 				"a : 'a';\n"+
2104 				"b : 'b';\n"+
2105 				"WS : ' '|'\n';\n");
2106 		Tool antlr = newTool();
2107 		antlr.setOutputDirectory(null); // write to /dev/null
2108 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2109 		g.setCodeGenerator(generator);
2110 		generator.genRecognizer();
2111 
2112 		int expectedMsgID = ErrorManager.MSG_LIST_LABEL_INVALID_UNLESS_RETVAL_STRUCT;
2113 		Object expectedArg = "x";
2114 		Object expectedArg2 = null;
2115 		GrammarSemanticsMessage expectedMessage =
2116 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
2117 		checkError(equeue, expectedMessage);
2118 	}
2119 
testRuleLabelOnTwoDifferentRulesAST()2120 	@Test public void testRuleLabelOnTwoDifferentRulesAST() throws Exception {
2121 		String grammar =
2122 			"grammar T;\n"+
2123 				"options {output=AST;}\n"+
2124 				"s : x+=a x+=b {System.out.println($x);} ;" +
2125 				"a : 'a';\n"+
2126 				"b : 'b';\n"+
2127 				"WS : (' '|'\\n') {skip();};\n";
2128 		String expecting = "[a, b]\na b\n";
2129 		String found = execParser("T.g", grammar, "TParser", "TLexer",
2130 			"s", "a b", false);
2131 		assertEquals(expecting, found);
2132 	}
2133 
testRuleLabelOnTwoDifferentRulesTemplate()2134 	@Test public void testRuleLabelOnTwoDifferentRulesTemplate() throws Exception {
2135 		String grammar =
2136 			"grammar T;\n"+
2137 				"options {output=template;}\n"+
2138 				"s : x+=a x+=b {System.out.println($x);} ;" +
2139 				"a : 'a' -> {%{\"hi\"}} ;\n"+
2140 				"b : 'b' -> {%{\"mom\"}} ;\n"+
2141 				"WS : (' '|'\\n') {skip();};\n";
2142 		String expecting = "[hi, mom]\n";
2143 		String found = execParser("T.g", grammar, "TParser", "TLexer",
2144 			"s", "a b", false);
2145 		assertEquals(expecting, found);
2146 	}
2147 
testMissingArgs()2148 	@Test public void testMissingArgs() throws Exception {
2149 		ErrorQueue equeue = new ErrorQueue();
2150 		ErrorManager.setErrorListener(equeue);
2151 		Grammar g = new Grammar(
2152 			"grammar t;\n"+
2153 				"a : r ;" +
2154 				"r[int i] : 'a';\n");
2155 		Tool antlr = newTool();
2156 		antlr.setOutputDirectory(null); // write to /dev/null
2157 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2158 		g.setCodeGenerator(generator);
2159 		generator.genRecognizer();
2160 
2161 		int expectedMsgID = ErrorManager.MSG_MISSING_RULE_ARGS;
2162 		Object expectedArg = "r";
2163 		Object expectedArg2 = null;
2164 		GrammarSemanticsMessage expectedMessage =
2165 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
2166 		checkError(equeue, expectedMessage);
2167 	}
2168 
testArgsWhenNoneDefined()2169 	@Test public void testArgsWhenNoneDefined() throws Exception {
2170 		ErrorQueue equeue = new ErrorQueue();
2171 		ErrorManager.setErrorListener(equeue);
2172 		Grammar g = new Grammar(
2173 			"grammar t;\n"+
2174 				"a : r[32,34] ;" +
2175 				"r : 'a';\n");
2176 		Tool antlr = newTool();
2177 		antlr.setOutputDirectory(null); // write to /dev/null
2178 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2179 		g.setCodeGenerator(generator);
2180 		generator.genRecognizer();
2181 
2182 		int expectedMsgID = ErrorManager.MSG_RULE_HAS_NO_ARGS;
2183 		Object expectedArg = "r";
2184 		Object expectedArg2 = null;
2185 		GrammarSemanticsMessage expectedMessage =
2186 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
2187 		checkError(equeue, expectedMessage);
2188 	}
2189 
testReturnInitValue()2190 	@Test public void testReturnInitValue() throws Exception {
2191 		ErrorQueue equeue = new ErrorQueue();
2192 		ErrorManager.setErrorListener(equeue);
2193 		Grammar g = new Grammar(
2194 			"grammar t;\n"+
2195 				"a : r ;\n" +
2196 				"r returns [int x=0] : 'a' {$x = 4;} ;\n");
2197 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2198 
2199 		Rule r = g.getRule("r");
2200 		AttributeScope retScope = r.returnScope;
2201 		List<Attribute> parameters = retScope.getAttributes();
2202 		assertNotNull("missing return action", parameters);
2203 		assertEquals(1, parameters.size());
2204 		String found = parameters.get(0).toString();
2205 		String expecting = "int x=0";
2206 		assertEquals(expecting, found);
2207 	}
2208 
testMultipleReturnInitValue()2209 	@Test public void testMultipleReturnInitValue() throws Exception {
2210 		ErrorQueue equeue = new ErrorQueue();
2211 		ErrorManager.setErrorListener(equeue);
2212 		Grammar g = new Grammar(
2213 			"grammar t;\n"+
2214 				"a : r ;\n" +
2215 				"r returns [int x=0, int y, String s=new String(\"foo\")] : 'a' {$x = 4;} ;\n");
2216 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2217 
2218 		Rule r = g.getRule("r");
2219 		AttributeScope retScope = r.returnScope;
2220 		List<Attribute> parameters = retScope.getAttributes();
2221 		assertNotNull("missing return action", parameters);
2222 		assertEquals(3, parameters.size());
2223 		assertEquals("int x=0", parameters.get(0).toString());
2224 		assertEquals("int y", parameters.get(1).toString());
2225 		assertEquals("String s=new String(\"foo\")", parameters.get(2).toString());
2226 	}
2227 
testCStyleReturnInitValue()2228 	@Test public void testCStyleReturnInitValue() throws Exception {
2229 		ErrorQueue equeue = new ErrorQueue();
2230 		ErrorManager.setErrorListener(equeue);
2231 		Grammar g = new Grammar(
2232 			"grammar t;\n"+
2233 				"a : r ;\n" +
2234 				"r returns [int (*x)()=NULL] : 'a' ;\n");
2235 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2236 
2237 		Rule r = g.getRule("r");
2238 		AttributeScope retScope = r.returnScope;
2239 		List<Attribute> parameters = retScope.getAttributes();
2240 		assertNotNull("missing return action", parameters);
2241 		assertEquals(1, parameters.size());
2242 		String found = parameters.get(0).toString();
2243 		String expecting = "int (*)() x=NULL";
2244 		assertEquals(expecting, found);
2245 	}
2246 
testArgsWithInitValues()2247 	@Test public void testArgsWithInitValues() throws Exception {
2248 		ErrorQueue equeue = new ErrorQueue();
2249 		ErrorManager.setErrorListener(equeue);
2250 		Grammar g = new Grammar(
2251 			"grammar t;\n"+
2252 				"a : r[32,34] ;" +
2253 				"r[int x, int y=3] : 'a';\n");
2254 		Tool antlr = newTool();
2255 		antlr.setOutputDirectory(null); // write to /dev/null
2256 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2257 		g.setCodeGenerator(generator);
2258 		generator.genRecognizer();
2259 
2260 		int expectedMsgID = ErrorManager.MSG_ARG_INIT_VALUES_ILLEGAL;
2261 		Object expectedArg = "y";
2262 		Object expectedArg2 = null;
2263 		GrammarSemanticsMessage expectedMessage =
2264 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
2265 		checkError(equeue, expectedMessage);
2266 	}
2267 
testArgsOnToken()2268 	@Test public void testArgsOnToken() throws Exception {
2269 		ErrorQueue equeue = new ErrorQueue();
2270 		ErrorManager.setErrorListener(equeue);
2271 		Grammar g = new Grammar(
2272 			"grammar t;\n"+
2273 				"a : ID[32,34] ;" +
2274 				"ID : 'a';\n");
2275 		Tool antlr = newTool();
2276 		antlr.setOutputDirectory(null); // write to /dev/null
2277 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2278 		g.setCodeGenerator(generator);
2279 		generator.genRecognizer();
2280 
2281 		int expectedMsgID = ErrorManager.MSG_ARGS_ON_TOKEN_REF;
2282 		Object expectedArg = "ID";
2283 		Object expectedArg2 = null;
2284 		GrammarSemanticsMessage expectedMessage =
2285 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
2286 		checkError(equeue, expectedMessage);
2287 	}
2288 
testArgsOnTokenInLexer()2289 	@Test public void testArgsOnTokenInLexer() throws Exception {
2290 		ErrorQueue equeue = new ErrorQueue();
2291 		ErrorManager.setErrorListener(equeue);
2292 		Grammar g = new Grammar(
2293 			"lexer grammar t;\n"+
2294 				"R : 'z' ID[32,34] ;" +
2295 				"ID : 'a';\n");
2296 		Tool antlr = newTool();
2297 		antlr.setOutputDirectory(null); // write to /dev/null
2298 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2299 		g.setCodeGenerator(generator);
2300 		generator.genRecognizer();
2301 
2302 		int expectedMsgID = ErrorManager.MSG_RULE_HAS_NO_ARGS;
2303 		Object expectedArg = "ID";
2304 		Object expectedArg2 = null;
2305 		GrammarSemanticsMessage expectedMessage =
2306 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
2307 		checkError(equeue, expectedMessage);
2308 	}
2309 
testLabelOnRuleRefInLexer()2310 	@Test public void testLabelOnRuleRefInLexer() throws Exception {
2311 		String action = "$i.text";
2312 		String expecting = "(i!=null?i.getText():null)";
2313 		ErrorQueue equeue = new ErrorQueue();
2314 		ErrorManager.setErrorListener(equeue);
2315 		Grammar g = new Grammar(
2316 			"lexer grammar t;\n"+
2317 				"R : 'z' i=ID {"+action+"};" +
2318 				"fragment ID : 'a';\n");
2319 		Tool antlr = newTool();
2320 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2321 		g.setCodeGenerator(generator);
2322 		generator.genRecognizer(); // forces load of templates
2323 		ActionTranslator translator =
2324 			new ActionTranslator(generator,
2325 				"R",
2326 				new CommonToken(ANTLRParser.ACTION,action),1);
2327 		String found = translator.translate();
2328 		assertEquals(expecting, found);
2329 
2330 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2331 	}
2332 
testRefToRuleRefInLexer()2333 	@Test public void testRefToRuleRefInLexer() throws Exception {
2334 		String action = "$ID.text";
2335 		String expecting = "(ID1!=null?ID1.getText():null)";
2336 		ErrorQueue equeue = new ErrorQueue();
2337 		ErrorManager.setErrorListener(equeue);
2338 		Grammar g = new Grammar(
2339 			"lexer grammar t;\n"+
2340 				"R : 'z' ID {"+action+"};" +
2341 				"ID : 'a';\n");
2342 		Tool antlr = newTool();
2343 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2344 		g.setCodeGenerator(generator);
2345 		generator.genRecognizer(); // forces load of templates
2346 		ActionTranslator translator =
2347 			new ActionTranslator(generator,
2348 				"R",
2349 				new CommonToken(ANTLRParser.ACTION,action),1);
2350 		String found = translator.translate();
2351 		assertEquals(expecting, found);
2352 
2353 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2354 	}
2355 
testRefToRuleRefInLexerNoAttribute()2356 	@Test public void testRefToRuleRefInLexerNoAttribute() throws Exception {
2357 		String action = "$ID";
2358 		String expecting = "ID1";
2359 		ErrorQueue equeue = new ErrorQueue();
2360 		ErrorManager.setErrorListener(equeue);
2361 		Grammar g = new Grammar(
2362 			"lexer grammar t;\n"+
2363 				"R : 'z' ID {"+action+"};" +
2364 				"ID : 'a';\n");
2365 		Tool antlr = newTool();
2366 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2367 		g.setCodeGenerator(generator);
2368 		generator.genRecognizer(); // forces load of templates
2369 		ActionTranslator translator =
2370 			new ActionTranslator(generator,
2371 				"R",
2372 				new CommonToken(ANTLRParser.ACTION,action),1);
2373 		String found = translator.translate();
2374 		assertEquals(expecting, found);
2375 
2376 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2377 	}
2378 
testCharLabelInLexer()2379 	@Test public void testCharLabelInLexer() throws Exception {
2380 		ErrorQueue equeue = new ErrorQueue();
2381 		ErrorManager.setErrorListener(equeue);
2382 		Grammar g = new Grammar(
2383 			"lexer grammar t;\n"+
2384 				"R : x='z' ;\n");
2385 
2386 		Tool antlr = newTool();
2387 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2388 		g.setCodeGenerator(generator);
2389 		generator.genRecognizer(); // forces load of templates
2390 
2391 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2392 	}
2393 
testCharListLabelInLexer()2394 	@Test public void testCharListLabelInLexer() throws Exception {
2395 		ErrorQueue equeue = new ErrorQueue();
2396 		ErrorManager.setErrorListener(equeue);
2397 		Grammar g = new Grammar(
2398 			"lexer grammar t;\n"+
2399 				"R : x+='z' ;\n");
2400 
2401 		Tool antlr = newTool();
2402 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2403 		g.setCodeGenerator(generator);
2404 		generator.genRecognizer(); // forces load of templates
2405 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2406 	}
2407 
testWildcardCharLabelInLexer()2408 	@Test public void testWildcardCharLabelInLexer() throws Exception {
2409 		ErrorQueue equeue = new ErrorQueue();
2410 		ErrorManager.setErrorListener(equeue);
2411 		Grammar g = new Grammar(
2412 			"lexer grammar t;\n"+
2413 				"R : x=. ;\n");
2414 
2415 		Tool antlr = newTool();
2416 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2417 		g.setCodeGenerator(generator);
2418 		generator.genRecognizer(); // forces load of templates
2419 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2420 	}
2421 
testWildcardCharListLabelInLexer()2422 	@Test public void testWildcardCharListLabelInLexer() throws Exception {
2423 		ErrorQueue equeue = new ErrorQueue();
2424 		ErrorManager.setErrorListener(equeue);
2425 		Grammar g = new Grammar(
2426 			"lexer grammar t;\n"+
2427 				"R : x+=. ;\n");
2428 
2429 		Tool antlr = newTool();
2430 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2431 		g.setCodeGenerator(generator);
2432 		generator.genRecognizer(); // forces load of templates
2433 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2434 	}
2435 
testMissingArgsInLexer()2436 	@Test public void testMissingArgsInLexer() throws Exception {
2437 		ErrorQueue equeue = new ErrorQueue();
2438 		ErrorManager.setErrorListener(equeue);
2439 		Grammar g = new Grammar(
2440 			"lexer grammar t;\n"+
2441 				"A : R ;" +
2442 				"R[int i] : 'a';\n");
2443 		Tool antlr = newTool();
2444 		antlr.setOutputDirectory(null); // write to /dev/null
2445 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2446 		g.setCodeGenerator(generator);
2447 		generator.genRecognizer();
2448 
2449 		int expectedMsgID = ErrorManager.MSG_MISSING_RULE_ARGS;
2450 		Object expectedArg = "R";
2451 		Object expectedArg2 = null;
2452 		// getting a second error @1:12, probably from nextToken
2453 		GrammarSemanticsMessage expectedMessage =
2454 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
2455 		checkError(equeue, expectedMessage);
2456 	}
2457 
testLexerRulePropertyRefs()2458 	@Test public void testLexerRulePropertyRefs() throws Exception {
2459 		String action = "$text $type $line $pos $channel $index $start $stop";
2460 		String expecting = "getText() _type state.tokenStartLine state.tokenStartCharPositionInLine _channel -1 state.tokenStartCharIndex (getCharIndex()-1)";
2461 		ErrorQueue equeue = new ErrorQueue();
2462 		ErrorManager.setErrorListener(equeue);
2463 		Grammar g = new Grammar(
2464 			"lexer grammar t;\n"+
2465 				"R : 'r' {"+action+"};\n");
2466 		Tool antlr = newTool();
2467 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2468 		g.setCodeGenerator(generator);
2469 		generator.genRecognizer(); // forces load of templates
2470 		ActionTranslator translator =
2471 			new ActionTranslator(generator,
2472 				"R",
2473 				new CommonToken(ANTLRParser.ACTION,action),1);
2474 		String found = translator.translate();
2475 		assertEquals(expecting, found);
2476 
2477 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2478 	}
2479 
testLexerLabelRefs()2480 	@Test public void testLexerLabelRefs() throws Exception {
2481 		String action = "$a $b.text $c $d.text";
2482 		String expecting = "a (b!=null?b.getText():null) c (d!=null?d.getText():null)";
2483 		ErrorQueue equeue = new ErrorQueue();
2484 		ErrorManager.setErrorListener(equeue);
2485 		Grammar g = new Grammar(
2486 			"lexer grammar t;\n"+
2487 				"R : a='c' b='hi' c=. d=DUH {"+action+"};\n" +
2488 				"DUH : 'd' ;\n");
2489 		Tool antlr = newTool();
2490 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2491 		g.setCodeGenerator(generator);
2492 		generator.genRecognizer(); // forces load of templates
2493 		ActionTranslator translator =
2494 			new ActionTranslator(generator,
2495 				"R",
2496 				new CommonToken(ANTLRParser.ACTION,action),1);
2497 		String found = translator.translate();
2498 		assertEquals(expecting, found);
2499 
2500 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2501 	}
2502 
testSettingLexerRulePropertyRefs()2503 	@Test public void testSettingLexerRulePropertyRefs() throws Exception {
2504 		String action = "$text $type=1 $line=1 $pos=1 $channel=1 $index";
2505 		String expecting = "getText() _type=1 state.tokenStartLine=1 state.tokenStartCharPositionInLine=1 _channel=1 -1";
2506 		ErrorQueue equeue = new ErrorQueue();
2507 		ErrorManager.setErrorListener(equeue);
2508 		Grammar g = new Grammar(
2509 			"lexer grammar t;\n"+
2510 				"R : 'r' {"+action+"};\n");
2511 		Tool antlr = newTool();
2512 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2513 		g.setCodeGenerator(generator);
2514 		generator.genRecognizer(); // forces load of templates
2515 		ActionTranslator translator =
2516 			new ActionTranslator(generator,
2517 				"R",
2518 				new CommonToken(ANTLRParser.ACTION,action),1);
2519 		String found = translator.translate();
2520 		assertEquals(expecting, found);
2521 
2522 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2523 	}
2524 
testArgsOnTokenInLexerRuleOfCombined()2525 	@Test public void testArgsOnTokenInLexerRuleOfCombined() throws Exception {
2526 		ErrorQueue equeue = new ErrorQueue();
2527 		ErrorManager.setErrorListener(equeue);
2528 		Grammar g = new Grammar(
2529 			"grammar t;\n"+
2530 				"a : R;\n" +
2531 				"R : 'z' ID[32] ;\n" +
2532 				"ID : 'a';\n");
2533 
2534 		String lexerGrammarStr = g.getLexerGrammar();
2535 		StringReader sr = new StringReader(lexerGrammarStr);
2536 		Grammar lexerGrammar = new Grammar();
2537 		lexerGrammar.setFileName("<internally-generated-lexer>");
2538 		lexerGrammar.importTokenVocabulary(g);
2539 		lexerGrammar.parseAndBuildAST(sr);
2540 		lexerGrammar.defineGrammarSymbols();
2541 		lexerGrammar.checkNameSpaceAndActions();
2542 		sr.close();
2543 
2544 		Tool antlr = newTool();
2545 		antlr.setOutputDirectory(null); // write to /dev/null
2546 		CodeGenerator generator = new CodeGenerator(antlr, lexerGrammar, "Java");
2547 		lexerGrammar.setCodeGenerator(generator);
2548 		generator.genRecognizer();
2549 
2550 		int expectedMsgID = ErrorManager.MSG_RULE_HAS_NO_ARGS;
2551 		Object expectedArg = "ID";
2552 		Object expectedArg2 = null;
2553 		GrammarSemanticsMessage expectedMessage =
2554 			new GrammarSemanticsMessage(expectedMsgID, lexerGrammar, null, expectedArg, expectedArg2);
2555 		checkError(equeue, expectedMessage);
2556 	}
2557 
testMissingArgsOnTokenInLexerRuleOfCombined()2558 	@Test public void testMissingArgsOnTokenInLexerRuleOfCombined() throws Exception {
2559 		ErrorQueue equeue = new ErrorQueue();
2560 		ErrorManager.setErrorListener(equeue);
2561 		Grammar g = new Grammar(
2562 			"grammar t;\n"+
2563 				"a : R;\n" +
2564 				"R : 'z' ID ;\n" +
2565 				"ID[int i] : 'a';\n");
2566 
2567 		String lexerGrammarStr = g.getLexerGrammar();
2568 		StringReader sr = new StringReader(lexerGrammarStr);
2569 		Grammar lexerGrammar = new Grammar();
2570 		lexerGrammar.setFileName("<internally-generated-lexer>");
2571 		lexerGrammar.importTokenVocabulary(g);
2572 		lexerGrammar.parseAndBuildAST(sr);
2573 		lexerGrammar.defineGrammarSymbols();
2574 		lexerGrammar.checkNameSpaceAndActions();
2575 		sr.close();
2576 
2577 		Tool antlr = newTool();
2578 		antlr.setOutputDirectory(null); // write to /dev/null
2579 		CodeGenerator generator = new CodeGenerator(antlr, lexerGrammar, "Java");
2580 		lexerGrammar.setCodeGenerator(generator);
2581 		generator.genRecognizer();
2582 
2583 		int expectedMsgID = ErrorManager.MSG_MISSING_RULE_ARGS;
2584 		Object expectedArg = "ID";
2585 		Object expectedArg2 = null;
2586 		GrammarSemanticsMessage expectedMessage =
2587 			new GrammarSemanticsMessage(expectedMsgID, lexerGrammar, null, expectedArg, expectedArg2);
2588 		checkError(equeue, expectedMessage);
2589 	}
2590 
2591 	// T R E E S
2592 
testTokenLabelTreeProperty()2593 	@Test public void testTokenLabelTreeProperty() throws Exception {
2594 		String action = "$id.tree;";
2595 		String expecting = "id_tree;";
2596 
2597 		ErrorQueue equeue = new ErrorQueue();
2598 		ErrorManager.setErrorListener(equeue);
2599 		Grammar g = new Grammar(
2600 			"grammar t;\n"+
2601 				"a : id=ID {"+action+"} ;\n" +
2602 				"ID : 'a';\n");
2603 
2604 		Tool antlr = newTool();
2605 		antlr.setOutputDirectory(null); // write to /dev/null
2606 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2607 		ActionTranslator translator =
2608 			new ActionTranslator(generator,
2609 				"a",
2610 				new CommonToken(ANTLRParser.ACTION,action),1);
2611 		g.setCodeGenerator(generator);
2612 		generator.genRecognizer(); // forces load of templates
2613 		String found = translator.translate();
2614 		assertEquals(expecting, found);
2615 
2616 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2617 	}
2618 
testTokenRefTreeProperty()2619 	@Test public void testTokenRefTreeProperty() throws Exception {
2620 		String action = "$ID.tree;";
2621 		String expecting = "ID1_tree;";
2622 
2623 		ErrorQueue equeue = new ErrorQueue();
2624 		ErrorManager.setErrorListener(equeue);
2625 		Grammar g = new Grammar(
2626 			"grammar t;\n"+
2627 				"a : ID {"+action+"} ;" +
2628 				"ID : 'a';\n");
2629 		Tool antlr = newTool();
2630 		antlr.setOutputDirectory(null); // write to /dev/null
2631 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2632 		g.setCodeGenerator(generator);
2633 		generator.genRecognizer();
2634 
2635 		ActionTranslator translator = new ActionTranslator(generator,"a",
2636 			new CommonToken(ANTLRParser.ACTION,action),1);
2637 		String found = translator.translate();
2638 		assertEquals(expecting, found);
2639 	}
2640 
testAmbiguousTokenRef()2641 	@Test public void testAmbiguousTokenRef() throws Exception {
2642 		String action = "$ID;";
2643 		String expecting = "";
2644 
2645 		ErrorQueue equeue = new ErrorQueue();
2646 		ErrorManager.setErrorListener(equeue);
2647 		Grammar g = new Grammar(
2648 			"grammar t;\n"+
2649 				"a : ID ID {"+action+"};" +
2650 				"ID : 'a';\n");
2651 		Tool antlr = newTool();
2652 		antlr.setOutputDirectory(null); // write to /dev/null
2653 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2654 		g.setCodeGenerator(generator);
2655 		generator.genRecognizer();
2656 
2657 		int expectedMsgID = ErrorManager.MSG_NONUNIQUE_REF;
2658 		Object expectedArg = "ID";
2659 		GrammarSemanticsMessage expectedMessage =
2660 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
2661 		checkError(equeue, expectedMessage);
2662 	}
2663 
testAmbiguousTokenRefWithProp()2664 	@Test public void testAmbiguousTokenRefWithProp() throws Exception {
2665 		String action = "$ID.text;";
2666 		String expecting = "";
2667 
2668 		ErrorQueue equeue = new ErrorQueue();
2669 		ErrorManager.setErrorListener(equeue);
2670 		Grammar g = new Grammar(
2671 			"grammar t;\n"+
2672 				"a : ID ID {"+action+"};" +
2673 				"ID : 'a';\n");
2674 		Tool antlr = newTool();
2675 		antlr.setOutputDirectory(null); // write to /dev/null
2676 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2677 		g.setCodeGenerator(generator);
2678 		generator.genRecognizer();
2679 
2680 		int expectedMsgID = ErrorManager.MSG_NONUNIQUE_REF;
2681 		Object expectedArg = "ID";
2682 		GrammarSemanticsMessage expectedMessage =
2683 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
2684 		checkError(equeue, expectedMessage);
2685 	}
2686 
testRuleRefWithDynamicScope()2687 	@Test public void testRuleRefWithDynamicScope() throws Exception {
2688 		String action = "$field::x = $field.st;";
2689 		String expecting = "field_stack.peek().x = retval.st;";
2690 
2691 		ErrorQueue equeue = new ErrorQueue();
2692 		ErrorManager.setErrorListener(equeue);
2693 		Grammar g = new Grammar(
2694 			"grammar a;\n" +
2695 				"field\n" +
2696 				"scope { ST x; }\n" +
2697 				"    :   'y' {"+action+"}\n" +
2698 				"    ;\n");
2699 		Tool antlr = newTool();
2700 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2701 		g.setCodeGenerator(generator);
2702 		generator.genRecognizer(); // forces load of templates
2703 		ActionTranslator translator = new ActionTranslator(generator,
2704 			"field",
2705 			new CommonToken(ANTLRParser.ACTION,action),1);
2706 		String found = translator.translate();
2707 		assertEquals(expecting, found);
2708 
2709 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2710 	}
2711 
testAssignToOwnRulenameAttr()2712 	@Test public void testAssignToOwnRulenameAttr() throws Exception {
2713 		String action = "$rule.tree = null;";
2714 		String expecting = "retval.tree = null;";
2715 		ErrorQueue equeue = new ErrorQueue();
2716 		ErrorManager.setErrorListener(equeue);
2717 		Grammar g = new Grammar(
2718 			"grammar a;\n" +
2719 				"rule\n" +
2720 				"    : 'y' {" + action +"}\n" +
2721 				"    ;");
2722 		Tool antlr = newTool();
2723 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2724 		g.setCodeGenerator(generator);
2725 		generator.genRecognizer(); // forces load of templates
2726 		ActionTranslator translator = new ActionTranslator(generator,
2727 			"rule",
2728 			new CommonToken(ANTLRParser.ACTION,action),1);
2729 		String found = translator.translate();
2730 		assertEquals(expecting, found);
2731 
2732 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2733 	}
2734 
testAssignToOwnParamAttr()2735 	@Test public void testAssignToOwnParamAttr() throws Exception {
2736 		String action = "$rule.i = 42; $i = 23;";
2737 		String expecting = "i = 42; i = 23;";
2738 		ErrorQueue equeue = new ErrorQueue();
2739 		ErrorManager.setErrorListener(equeue);
2740 		Grammar g = new Grammar(
2741 			"grammar a;\n" +
2742 				"rule[int i]\n" +
2743 				"    : 'y' {" + action +"}\n" +
2744 				"    ;");
2745 		Tool antlr = newTool();
2746 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2747 		g.setCodeGenerator(generator);
2748 		generator.genRecognizer(); // forces load of templates
2749 		ActionTranslator translator = new ActionTranslator(generator,
2750 			"rule",
2751 			new CommonToken(ANTLRParser.ACTION,action),1);
2752 		String found = translator.translate();
2753 		assertEquals(expecting, found);
2754 
2755 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2756 	}
2757 
testIllegalAssignToOwnRulenameAttr()2758 	@Test public void testIllegalAssignToOwnRulenameAttr() throws Exception {
2759 		String action = "$rule.stop = 0;";
2760 		ErrorQueue equeue = new ErrorQueue();
2761 		ErrorManager.setErrorListener(equeue);
2762 		Grammar g = new Grammar(
2763 			"grammar a;\n" +
2764 				"rule\n" +
2765 				"    : 'y' {" + action +"}\n" +
2766 				"    ;");
2767 		Tool antlr = newTool();
2768 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2769 		g.setCodeGenerator(generator);
2770 		generator.genRecognizer(); // forces load of templates
2771 		ActionTranslator translator = new ActionTranslator(generator,
2772 			"rule",
2773 			new CommonToken(ANTLRParser.ACTION,action),1);
2774 		String rawTranslation =
2775 			translator.translate();
2776 
2777 		int expectedMsgID = ErrorManager.MSG_WRITE_TO_READONLY_ATTR;
2778 		Object expectedArg = "rule";
2779 		Object expectedArg2 = "stop";
2780 		GrammarSemanticsMessage expectedMessage =
2781 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
2782 		checkError(equeue, expectedMessage);
2783 	}
2784 
testIllegalAssignToLocalAttr()2785 	@Test public void testIllegalAssignToLocalAttr() throws Exception {
2786 		String action = "$tree = null; $st = null; $start = 0; $stop = 0; $text = 0;";
2787 		String expecting = "retval.tree = null; retval.st = null;   ";
2788 		ErrorQueue equeue = new ErrorQueue();
2789 		ErrorManager.setErrorListener(equeue);
2790 		Grammar g = new Grammar(
2791 			"grammar a;\n" +
2792 				"rule\n" +
2793 				"    : 'y' {" + action +"}\n" +
2794 				"    ;");
2795 		Tool antlr = newTool();
2796 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2797 		g.setCodeGenerator(generator);
2798 		generator.genRecognizer(); // forces load of templates
2799 		ActionTranslator translator = new ActionTranslator(generator,
2800 			"rule",
2801 			new CommonToken(ANTLRParser.ACTION,action),1);
2802 		String rawTranslation =
2803 			translator.translate();
2804 
2805 		int expectedMsgID = ErrorManager.MSG_WRITE_TO_READONLY_ATTR;
2806 		ArrayList<Message> expectedErrors = new ArrayList<Message>(3);
2807 		GrammarSemanticsMessage expectedMessage =
2808 			new GrammarSemanticsMessage(expectedMsgID, g, null, "start", "");
2809 		expectedErrors.add(expectedMessage);
2810 		GrammarSemanticsMessage expectedMessage2 =
2811 			new GrammarSemanticsMessage(expectedMsgID, g, null, "stop", "");
2812 		expectedErrors.add(expectedMessage2);
2813 		GrammarSemanticsMessage expectedMessage3 =
2814 			new GrammarSemanticsMessage(expectedMsgID, g, null, "text", "");
2815 		expectedErrors.add(expectedMessage3);
2816 		checkErrors(equeue, expectedErrors);
2817 
2818 		STGroup templates =
2819 			new STGroup();
2820 		ST actionST = new ST(templates, rawTranslation);
2821 		String found = actionST.render();
2822 		assertEquals(expecting, found);
2823 	}
2824 
testIllegalAssignRuleRefAttr()2825 	@Test public void testIllegalAssignRuleRefAttr() throws Exception {
2826 		String action = "$other.tree = null;";
2827 		ErrorQueue equeue = new ErrorQueue();
2828 		ErrorManager.setErrorListener(equeue);
2829 		Grammar g = new Grammar(
2830 			"grammar a;\n" +
2831 				"options { output = AST;}" +
2832 				"otherrule\n" +
2833 				"    : 'y' ;" +
2834 				"rule\n" +
2835 				"    : other=otherrule {" + action +"}\n" +
2836 				"    ;");
2837 		Tool antlr = newTool();
2838 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2839 		g.setCodeGenerator(generator);
2840 		generator.genRecognizer(); // forces load of templates
2841 		ActionTranslator translator = new ActionTranslator(generator,
2842 			"rule",
2843 			new CommonToken(ANTLRParser.ACTION,action),1);
2844 		String rawTranslation =
2845 			translator.translate();
2846 
2847 		int expectedMsgID = ErrorManager.MSG_WRITE_TO_READONLY_ATTR;
2848 		Object expectedArg = "other";
2849 		Object expectedArg2 = "tree";
2850 		GrammarSemanticsMessage expectedMessage =
2851 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
2852 		checkError(equeue, expectedMessage);
2853 	}
2854 
testIllegalAssignTokenRefAttr()2855 	@Test public void testIllegalAssignTokenRefAttr() throws Exception {
2856 		String action = "$ID.text = \"test\";";
2857 		ErrorQueue equeue = new ErrorQueue();
2858 		ErrorManager.setErrorListener(equeue);
2859 		Grammar g = new Grammar(
2860 			"grammar a;\n" +
2861 				"ID\n" +
2862 				"    : 'y' ;" +
2863 				"rule\n" +
2864 				"    : ID {" + action +"}\n" +
2865 				"    ;");
2866 		Tool antlr = newTool();
2867 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2868 		g.setCodeGenerator(generator);
2869 		generator.genRecognizer(); // forces load of templates
2870 		ActionTranslator translator = new ActionTranslator(generator,
2871 			"rule",
2872 			new CommonToken(ANTLRParser.ACTION,action),1);
2873 		String rawTranslation =
2874 			translator.translate();
2875 
2876 		int expectedMsgID = ErrorManager.MSG_WRITE_TO_READONLY_ATTR;
2877 		Object expectedArg = "ID";
2878 		Object expectedArg2 = "text";
2879 		GrammarSemanticsMessage expectedMessage =
2880 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
2881 		checkError(equeue, expectedMessage);
2882 	}
2883 
testAssignToTreeNodeAttribute()2884 	@Test public void testAssignToTreeNodeAttribute() throws Exception {
2885 		String action = "$tree.scope = localScope;";
2886 		String expecting = "retval.tree.scope = localScope;";
2887 		ErrorQueue equeue = new ErrorQueue();
2888 		ErrorManager.setErrorListener(equeue);
2889 		Grammar g = new Grammar(
2890 			"grammar a;\n" +
2891 				"options { output=AST; }" +
2892 				"rule\n" +
2893 				"@init {\n" +
2894 				"   Scope localScope=null;\n" +
2895 				"}\n" +
2896 				"@after {\n" +
2897 				"   ###$tree.scope = localScope;!!!\n" +
2898 				"}\n" +
2899 				"   : 'a' -> ^('a')\n" +
2900 				";");
2901 		Tool antlr = newTool();
2902 
2903 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2904 		g.setCodeGenerator(generator);
2905 		generator.genRecognizer(); // codegen phase sets some vars we need
2906 		ST codeST = generator.getRecognizerST();
2907 		String code = codeST.render();
2908 		String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!"));
2909 		assertEquals(expecting, found);
2910 
2911 	}
2912 
testDoNotTranslateAttributeCompare()2913 	@Test public void testDoNotTranslateAttributeCompare() throws Exception {
2914 		String action = "$a.line == $b.line";
2915 		String expecting = "(a!=null?a.getLine():0) == (b!=null?b.getLine():0)";
2916 		ErrorQueue equeue = new ErrorQueue();
2917 		ErrorManager.setErrorListener(equeue);
2918 		Grammar g = new Grammar(
2919 			"lexer grammar a;\n" +
2920 				"RULE:\n" +
2921 				"     a=ID b=ID {" + action + "}" +
2922 				"    ;\n" +
2923 				"ID : 'id';"
2924 		);
2925 		Tool antlr = newTool();
2926 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2927 		g.setCodeGenerator(generator);
2928 		generator.genRecognizer();
2929 		ActionTranslator translator = new ActionTranslator(generator,
2930 			"RULE",
2931 			new CommonToken(ANTLRParser.ACTION,action),1);
2932 		String found = translator.translate();
2933 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2934 		assertEquals(expecting, found);
2935 	}
2936 
testDoNotTranslateScopeAttributeCompare()2937 	@Test public void testDoNotTranslateScopeAttributeCompare() throws Exception {
2938 		String action = "if ($rule::foo == \"foo\" || 1) { System.out.println(\"ouch\"); }";
2939 		String expecting = "if (rule_stack.peek().foo == \"foo\" || 1) { System.out.println(\"ouch\"); }";
2940 		ErrorQueue equeue = new ErrorQueue();
2941 		ErrorManager.setErrorListener(equeue);
2942 		Grammar g = new Grammar(
2943 			"grammar a;\n" +
2944 				"rule\n" +
2945 				"scope {\n" +
2946 				"   String foo;" +
2947 				"} :\n" +
2948 				"     twoIDs" +
2949 				"    ;\n" +
2950 				"twoIDs:\n" +
2951 				"    ID ID {" + action + "}\n" +
2952 				"    ;\n" +
2953 				"ID : 'id';"
2954 		);
2955 		Tool antlr = newTool();
2956 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
2957 		g.setCodeGenerator(generator);
2958 		generator.genRecognizer();
2959 		ActionTranslator translator = new ActionTranslator(generator,
2960 			"twoIDs",
2961 			new CommonToken(ANTLRParser.ACTION,action),1);
2962 		String rawTranslation =
2963 			translator.translate();
2964 		// check that we didn't use scopeSetAttributeRef int translation!
2965 		boolean foundScopeSetAttributeRef = false;
2966 		for (int i = 0; i < translator.chunks.size(); i++) {
2967 			Object chunk = translator.chunks.get(i);
2968 			if (chunk instanceof ST) {
2969 				if (((ST)chunk).getName().equals("/scopeSetAttributeRef")) {
2970 					foundScopeSetAttributeRef = true;
2971 				}
2972 			}
2973 		}
2974 		assertFalse("action translator used scopeSetAttributeRef template in comparison!", foundScopeSetAttributeRef);
2975 		STGroup templates =
2976 			new STGroup();
2977 		ST actionST = new ST(templates, rawTranslation);
2978 		String found = actionST.render();
2979 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
2980 		assertEquals(expecting, found);
2981 	}
2982 
testTreeRuleStopAttributeIsInvalid()2983 	@Test public void testTreeRuleStopAttributeIsInvalid() throws Exception {
2984 		String action = "$r.x; $r.start; $r.stop";
2985 		String expecting = "(r!=null?((t.a_return)r).x:0); (r!=null?((CommonTree)r.start):null); $r.stop";
2986 
2987 		ErrorQueue equeue = new ErrorQueue();
2988 		ErrorManager.setErrorListener(equeue);
2989 		Grammar g = new Grammar(
2990 			"tree grammar t;\n" +
2991 				"options {ASTLabelType=CommonTree;}\n"+
2992 				"a returns [int x]\n" +
2993 				"  :\n" +
2994 				"  ;\n"+
2995 				"b : r=a {###"+action+"!!!}\n" +
2996 				"  ;");
2997 		System.out.println(g.toString());
2998 		Tool antlr = newTool();
2999 		antlr.setOutputDirectory(null); // write to /dev/null
3000 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
3001 		g.setCodeGenerator(generator);
3002 		generator.genRecognizer(); // codegen phase sets some vars we need
3003 		ST codeST = generator.getRecognizerST();
3004 		String code = codeST.render();
3005 		String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!"));
3006 		assertEquals(expecting, found);
3007 
3008 		int expectedMsgID = ErrorManager.MSG_UNKNOWN_RULE_ATTRIBUTE;
3009 		Object expectedArg = "a";
3010 		Object expectedArg2 = "stop";
3011 		GrammarSemanticsMessage expectedMessage =
3012 			new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
3013 		System.out.println("equeue:"+equeue);
3014 		checkError(equeue, expectedMessage);
3015 	}
3016 
testRefToTextAttributeForCurrentTreeRule()3017 	@Test public void testRefToTextAttributeForCurrentTreeRule() throws Exception {
3018 		String action = "$text";
3019 		String expecting = "input.getTokenStream().toString(" +
3020 			"input.getTreeAdaptor().getTokenStartIndex(retval.start)," +
3021 			"input.getTreeAdaptor().getTokenStopIndex(retval.start))";
3022 
3023 		ErrorQueue equeue = new ErrorQueue();
3024 		ErrorManager.setErrorListener(equeue);
3025 		Grammar g = new Grammar(
3026 			"tree grammar t;\n" +
3027 				"options {ASTLabelType=CommonTree;}\n" +
3028 				"a : {###"+action+"!!!}\n" +
3029 				"  ;\n");
3030 
3031 		Tool antlr = newTool();
3032 		antlr.setOutputDirectory(null); // write to /dev/null
3033 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
3034 		g.setCodeGenerator(generator);
3035 		generator.genRecognizer(); // codegen phase sets some vars we need
3036 		ST codeST = generator.getRecognizerST();
3037 		String code = codeST.render();
3038 		String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!"));
3039 		assertEquals(expecting, found);
3040 
3041 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
3042 	}
3043 
testTypeOfGuardedAttributeRefIsCorrect()3044 	@Test public void testTypeOfGuardedAttributeRefIsCorrect() throws Exception {
3045 		String action = "int x = $b::n;";
3046 		String expecting = "int x = b_stack.peek().n;";
3047 
3048 		ErrorQueue equeue = new ErrorQueue();
3049 		ErrorManager.setErrorListener(equeue);
3050 		Grammar g = new Grammar(
3051 			"grammar t;\n" +
3052 				"s : b ;\n"+
3053 				"b\n" +
3054 				"scope {\n" +
3055 				"  int n;\n" +
3056 				"} : '(' b ')' {"+action+"}\n" + // refers to current invocation's n
3057 				"  ;\n");
3058 		Tool antlr = newTool();
3059 		CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
3060 		g.setCodeGenerator(generator);
3061 		generator.genRecognizer(); // forces load of templates
3062 		ActionTranslator translator = new ActionTranslator(generator, "b",
3063 			new CommonToken(ANTLRParser.ACTION,action),1);
3064 		String found = translator.translate();
3065 		assertEquals(expecting, found);
3066 
3067 		assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
3068 	}
3069 
3070 	// S U P P O R T
3071 
checkError(ErrorQueue equeue, GrammarSemanticsMessage expectedMessage)3072 	protected void checkError(ErrorQueue equeue,
3073 							  GrammarSemanticsMessage expectedMessage)
3074 		throws Exception
3075 	{
3076 		/*
3077 		System.out.println(equeue.infos);
3078 		System.out.println(equeue.warnings);
3079 		System.out.println(equeue.errors);
3080 		*/
3081 		Message foundMsg = null;
3082 		for (int i = 0; i < equeue.errors.size(); i++) {
3083 			Message m = equeue.errors.get(i);
3084 			if (m.msgID==expectedMessage.msgID ) {
3085 				foundMsg = m;
3086 			}
3087 		}
3088 		assertTrue("no error; "+expectedMessage.msgID+" expected", equeue.errors.size() > 0);
3089 		assertNotNull("couldn't find expected error: "+expectedMessage.msgID+" in "+equeue, foundMsg);
3090 		assertTrue("error is not a GrammarSemanticsMessage",
3091 			foundMsg instanceof GrammarSemanticsMessage);
3092 		assertEquals(expectedMessage.arg, foundMsg.arg);
3093 		assertEquals(expectedMessage.arg2, foundMsg.arg2);
3094 	}
3095 
3096 	/** Allow checking for multiple errors in one test */
checkErrors(ErrorQueue equeue, ArrayList<Message> expectedMessages)3097 	protected void checkErrors(ErrorQueue equeue,
3098 							   ArrayList<Message> expectedMessages)
3099 		throws Exception
3100 	{
3101 		ArrayList<Boolean> messageExpected = new ArrayList<Boolean>(equeue.errors.size());
3102 		for (int i = 0; i < equeue.errors.size(); i++) {
3103 			Message m = equeue.errors.get(i);
3104 			boolean foundMsg = false;
3105 			for (int j = 0; j < expectedMessages.size(); j++) {
3106 				Message em = expectedMessages.get(j);
3107 				if (m.msgID==em.msgID && m.arg.equals(em.arg) && m.arg2.equals(em.arg2)) {
3108 					foundMsg = true;
3109 				}
3110 			}
3111 			if (foundMsg) {
3112 				messageExpected.add(i, Boolean.TRUE);
3113 			} else
3114 				messageExpected.add(i, Boolean.FALSE);
3115 		}
3116 		for (int i = 0; i < equeue.errors.size(); i++) {
3117 			assertTrue("unexpected error:" + equeue.errors.get(i), messageExpected.get(i));
3118 		}
3119 	}
3120 }
3121