PageRenderTime 37ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/antlr-3.4/tool/src/test/java/org/antlr/test/TestAttributes.java

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