PageRenderTime 69ms CodeModel.GetById 27ms 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

Large files files are truncated, but you can click here to view the full 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 t…

Large files files are truncated, but you can click here to view the full file