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