aboutsummaryrefslogtreecommitdiff
path: root/tool/src/test/java/org/antlr/test/TestTemplates.java
diff options
context:
space:
mode:
Diffstat (limited to 'tool/src/test/java/org/antlr/test/TestTemplates.java')
-rw-r--r--tool/src/test/java/org/antlr/test/TestTemplates.java374
1 files changed, 374 insertions, 0 deletions
diff --git a/tool/src/test/java/org/antlr/test/TestTemplates.java b/tool/src/test/java/org/antlr/test/TestTemplates.java
new file mode 100644
index 0000000..8026319
--- /dev/null
+++ b/tool/src/test/java/org/antlr/test/TestTemplates.java
@@ -0,0 +1,374 @@
+/*
+ * [The "BSD license"]
+ * Copyright (c) 2010 Terence Parr
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.antlr.test;
+
+import org.antlr.Tool;
+import org.antlr.codegen.CodeGenerator;
+import org.antlr.grammar.v3.ANTLRParser;
+import org.antlr.grammar.v3.ActionTranslator;
+import org.antlr.runtime.CommonToken;
+import org.stringtemplate.v4.ST;
+import org.stringtemplate.v4.STGroup;
+import org.antlr.tool.ErrorManager;
+import org.antlr.tool.Grammar;
+import org.antlr.tool.GrammarSemanticsMessage;
+import org.antlr.tool.Message;
+import org.junit.Test;
+
+/** Test templates in actions; %... shorthands */
+public class TestTemplates extends BaseTest {
+ private static final String LINE_SEP = System.getProperty("line.separator");
+
+ @Test
+ public void testTemplateConstructor() throws Exception {
+ String action = "x = %foo(name={$ID.text});";
+ String expecting = "x = templateLib.getInstanceOf(\"foo\"," +
+ "new STAttrMap().put(\"name\", (ID1!=null?ID1.getText():null)));";
+
+ ErrorQueue equeue = new ErrorQueue();
+ ErrorManager.setErrorListener(equeue);
+ Grammar g = new Grammar(
+ "grammar t;\n" +
+ "options {\n" +
+ " output=template;\n" +
+ "}\n" +
+ "\n" +
+ "a : ID {"+action+"}\n" +
+ " ;\n" +
+ "\n" +
+ "ID : 'a';\n");
+ Tool antlr = newTool();
+ CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
+ g.setCodeGenerator(generator);
+ generator.genRecognizer(); // forces load of templates
+ ActionTranslator translator =
+ new ActionTranslator(generator,
+ "a",
+ new CommonToken(ANTLRParser.ACTION,action),1);
+ String rawTranslation =
+ translator.translate();
+ STGroup templates =
+ new STGroup();
+ ST actionST = new ST(templates, rawTranslation);
+ String found = actionST.render();
+
+ assertNoErrors(equeue);
+
+ assertEquals(expecting, found);
+ }
+
+ @Test
+ public void testTemplateConstructorNoArgs() throws Exception {
+ String action = "x = %foo();";
+ String expecting = "x = templateLib.getInstanceOf(\"foo\");";
+
+ ErrorQueue equeue = new ErrorQueue();
+ ErrorManager.setErrorListener(equeue);
+ Grammar g = new Grammar(
+ "grammar t;\n" +
+ "options {\n" +
+ " output=template;\n" +
+ "}\n" +
+ "\n" +
+ "a : ID {"+action+"}\n" +
+ " ;\n" +
+ "\n" +
+ "ID : 'a';\n");
+ Tool antlr = newTool();
+ CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
+ g.setCodeGenerator(generator);
+ generator.genRecognizer(); // forces load of templates
+ ActionTranslator translator =
+ new ActionTranslator(generator,
+ "a",
+ new CommonToken(ANTLRParser.ACTION,action),1);
+ String rawTranslation =
+ translator.translate();
+ STGroup templates =
+ new STGroup();
+ ST actionST = new ST(templates, rawTranslation);
+ String found = actionST.render();
+
+ assertNoErrors(equeue);
+
+ assertEquals(expecting, found);
+ }
+
+ @Test
+ public void testIndirectTemplateConstructor() throws Exception {
+ String action = "x = %({\"foo\"})(name={$ID.text});";
+ String expecting = "x = templateLib.getInstanceOf(\"foo\"," +
+ "new STAttrMap().put(\"name\", (ID1!=null?ID1.getText():null)));";
+
+ ErrorQueue equeue = new ErrorQueue();
+ ErrorManager.setErrorListener(equeue);
+ Grammar g = new Grammar(
+ "grammar t;\n" +
+ "options {\n" +
+ " output=template;\n" +
+ "}\n" +
+ "\n" +
+ "a : ID {"+action+"}\n" +
+ " ;\n" +
+ "\n" +
+ "ID : 'a';\n");
+ Tool antlr = newTool();
+ CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
+ g.setCodeGenerator(generator);
+ generator.genRecognizer(); // forces load of templates
+ ActionTranslator translator =
+ new ActionTranslator(generator,
+ "a",
+ new CommonToken(ANTLRParser.ACTION,action),1);
+ String rawTranslation =
+ translator.translate();
+ STGroup templates =
+ new STGroup();
+ ST actionST = new ST(templates, rawTranslation);
+ String found = actionST.render();
+
+ assertNoErrors(equeue);
+
+ assertEquals(expecting, found);
+ }
+
+ @Test public void testStringConstructor() throws Exception {
+ String action = "x = %{$ID.text};";
+ String expecting = "x = new StringTemplate(templateLib,(ID1!=null?ID1.getText():null));";
+
+ ErrorQueue equeue = new ErrorQueue();
+ ErrorManager.setErrorListener(equeue);
+ Grammar g = new Grammar(
+ "grammar t;\n" +
+ "options {\n" +
+ " output=template;\n" +
+ "}\n" +
+ "\n" +
+ "a : ID {"+action+"}\n" +
+ " ;\n" +
+ "\n" +
+ "ID : 'a';\n");
+ Tool antlr = newTool();
+ CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
+ g.setCodeGenerator(generator);
+ generator.genRecognizer(); // forces load of templates
+ ActionTranslator translator = new ActionTranslator(generator,
+ "a",
+ new CommonToken(ANTLRParser.ACTION,action),1);
+ String rawTranslation =
+ translator.translate();
+ STGroup templates =
+ new STGroup();
+ ST actionST = new ST(templates, rawTranslation);
+ String found = actionST.render();
+
+ assertNoErrors(equeue);
+
+ assertEquals(expecting, found);
+ }
+
+ @Test public void testSetAttr() throws Exception {
+ String action = "%x.y = z;";
+ String expecting = "(x).setAttribute(\"y\", z);";
+
+ ErrorQueue equeue = new ErrorQueue();
+ ErrorManager.setErrorListener(equeue);
+ Grammar g = new Grammar(
+ "grammar t;\n" +
+ "options {\n" +
+ " output=template;\n" +
+ "}\n" +
+ "\n" +
+ "a : ID {"+action+"}\n" +
+ " ;\n" +
+ "\n" +
+ "ID : 'a';\n");
+ Tool antlr = newTool();
+ CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
+ g.setCodeGenerator(generator);
+ generator.genRecognizer(); // forces load of templates
+ ActionTranslator translator =
+ new ActionTranslator(generator,
+ "a",
+ new CommonToken(ANTLRParser.ACTION,action),1);
+ String rawTranslation =
+ translator.translate();
+ STGroup templates =
+ new STGroup();
+ ST actionST = new ST(templates, rawTranslation);
+ String found = actionST.render();
+
+ assertNoErrors(equeue);
+
+ assertEquals(expecting, found);
+ }
+
+ @Test public void testSetAttrOfExpr() throws Exception {
+ String action = "%{foo($ID.text).getST()}.y = z;";
+ String expecting = "(foo((ID1!=null?ID1.getText():null)).getST()).setAttribute(\"y\", z);";
+
+ ErrorQueue equeue = new ErrorQueue();
+ ErrorManager.setErrorListener(equeue);
+ Grammar g = new Grammar(
+ "grammar t;\n" +
+ "options {\n" +
+ " output=template;\n" +
+ "}\n" +
+ "\n" +
+ "a : ID {"+action+"}\n" +
+ " ;\n" +
+ "\n" +
+ "ID : 'a';\n");
+ Tool antlr = newTool();
+ CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
+ g.setCodeGenerator(generator);
+ generator.genRecognizer(); // forces load of templates
+ ActionTranslator translator = new ActionTranslator(generator,
+ "a",
+ new CommonToken(ANTLRParser.ACTION,action),1);
+ String rawTranslation =
+ translator.translate();
+ STGroup templates =
+ new STGroup();
+ ST actionST = new ST(templates, rawTranslation);
+ String found = actionST.render();
+
+ assertNoErrors(equeue);
+
+ assertEquals(expecting, found);
+ }
+
+ @Test public void testSetAttrOfExprInMembers() throws Exception {
+ ErrorQueue equeue = new ErrorQueue();
+ ErrorManager.setErrorListener(equeue);
+ Grammar g = new Grammar(
+ "grammar t;\n" +
+ "options {\n" +
+ " output=template;\n" +
+ "}\n" +
+ "@members {\n" +
+ "%code.instr = o;" + // must not get null ptr!
+ "}\n" +
+ "a : ID\n" +
+ " ;\n" +
+ "\n" +
+ "ID : 'a';\n");
+ Tool antlr = newTool();
+ CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
+ g.setCodeGenerator(generator);
+ generator.genRecognizer(); // forces load of templates
+
+ assertNoErrors(equeue);
+ }
+
+ @Test public void testCannotHaveSpaceBeforeDot() throws Exception {
+ String action = "%x .y = z;";
+ String expecting = null;
+
+ ErrorQueue equeue = new ErrorQueue();
+ ErrorManager.setErrorListener(equeue);
+ Grammar g = new Grammar(
+ "grammar t;\n" +
+ "options {\n" +
+ " output=template;\n" +
+ "}\n" +
+ "\n" +
+ "a : ID {"+action+"}\n" +
+ " ;\n" +
+ "\n" +
+ "ID : 'a';\n");
+ Tool antlr = newTool();
+ CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
+ g.setCodeGenerator(generator);
+ generator.genRecognizer(); // forces load of templates
+
+ int expectedMsgID = ErrorManager.MSG_INVALID_TEMPLATE_ACTION;
+ Object expectedArg = "%x";
+ GrammarSemanticsMessage expectedMessage =
+ new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
+ checkError(equeue, expectedMessage);
+ }
+
+ @Test public void testCannotHaveSpaceAfterDot() throws Exception {
+ String action = "%x. y = z;";
+ String expecting = null;
+
+ ErrorQueue equeue = new ErrorQueue();
+ ErrorManager.setErrorListener(equeue);
+ Grammar g = new Grammar(
+ "grammar t;\n" +
+ "options {\n" +
+ " output=template;\n" +
+ "}\n" +
+ "\n" +
+ "a : ID {"+action+"}\n" +
+ " ;\n" +
+ "\n" +
+ "ID : 'a';\n");
+ Tool antlr = newTool();
+ CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
+ g.setCodeGenerator(generator);
+ generator.genRecognizer(); // forces load of templates
+
+ int expectedMsgID = ErrorManager.MSG_INVALID_TEMPLATE_ACTION;
+ Object expectedArg = "%x.";
+ GrammarSemanticsMessage expectedMessage =
+ new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
+ checkError(equeue, expectedMessage);
+ }
+
+ protected void checkError(ErrorQueue equeue,
+ GrammarSemanticsMessage expectedMessage)
+ throws Exception
+ {
+ /*
+ System.out.println(equeue.infos);
+ System.out.println(equeue.warnings);
+ System.out.println(equeue.errors);
+ */
+ Message foundMsg = null;
+ for (int i = 0; i < equeue.errors.size(); i++) {
+ Message m = (Message)equeue.errors.get(i);
+ if (m.msgID==expectedMessage.msgID ) {
+ foundMsg = m;
+ }
+ }
+ assertTrue("no error; "+expectedMessage.msgID+" expected", equeue.errors.size()>0);
+ assertTrue("too many errors; "+equeue.errors, equeue.errors.size()<=1);
+ assertTrue("couldn't find expected error: "+expectedMessage.msgID, foundMsg!=null);
+ assertTrue("error is not a GrammarSemanticsMessage",
+ foundMsg instanceof GrammarSemanticsMessage);
+ assertEquals(expectedMessage.arg, foundMsg.arg);
+ assertEquals(expectedMessage.arg2, foundMsg.arg2);
+ }
+
+ // S U P P O R T
+ private void assertNoErrors(ErrorQueue equeue) {
+ assertTrue("unexpected errors: "+equeue, equeue.errors.size()==0);
+ }
+}