001: /*
002: [The "BSD licence"]
003: Copyright (c) 2005-2006 Terence Parr
004: All rights reserved.
005:
006: Redistribution and use in source and binary forms, with or without
007: modification, are permitted provided that the following conditions
008: are met:
009: 1. Redistributions of source code must retain the above copyright
010: notice, this list of conditions and the following disclaimer.
011: 2. Redistributions in binary form must reproduce the above copyright
012: notice, this list of conditions and the following disclaimer in the
013: documentation and/or other materials provided with the distribution.
014: 3. The name of the author may not be used to endorse or promote products
015: derived from this software without specific prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
018: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
019: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
020: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
021: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
022: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
023: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
024: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
026: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: */
028: package org.antlr.test;
029:
030: import org.antlr.Tool;
031: import org.antlr.codegen.CodeGenerator;
032: import org.antlr.tool.ErrorManager;
033: import org.antlr.tool.Grammar;
034:
035: public class TestRewriteTemplates extends BaseTest {
036: protected boolean debug = false;
037:
038: public void testDelete() throws Exception {
039: String grammar = "grammar T;\n"
040: + "options {output=template;}\n" + "a : ID INT -> ;\n"
041: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
042: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
043: String found = execParser("T.g", grammar, "TParser", "TLexer",
044: "a", "abc 34", debug);
045: assertEquals("", found);
046: }
047:
048: public void testAction() throws Exception {
049: String grammar = "grammar T;\n"
050: + "options {output=template;}\n"
051: + "a : ID INT -> {new StringTemplate($ID.text)} ;\n"
052: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
053: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
054: String found = execParser("T.g", grammar, "TParser", "TLexer",
055: "a", "abc 34", debug);
056: assertEquals("abc\n", found);
057: }
058:
059: public void testEmbeddedLiteralConstructor() throws Exception {
060: String grammar = "grammar T;\n"
061: + "options {output=template;}\n"
062: + "a : ID INT -> {%{$ID.text}} ;\n"
063: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
064: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
065: String found = execParser("T.g", grammar, "TParser", "TLexer",
066: "a", "abc 34", debug);
067: assertEquals("abc\n", found);
068: }
069:
070: public void testInlineTemplate() throws Exception {
071: String grammar = "grammar T;\n"
072: + "options {output=template;}\n"
073: + "a : ID INT -> template(x={$ID},y={$INT}) <<x:<x.text>, y:<y.text>;>> ;\n"
074: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
075: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
076: String found = execParser("T.g", grammar, "TParser", "TLexer",
077: "a", "abc 34", debug);
078: assertEquals("x:abc, y:34;\n", found);
079: }
080:
081: public void testNamedTemplate() throws Exception {
082: // the support code adds template group in it's output Test.java
083: // that defines template foo.
084: String grammar = "grammar T;\n"
085: + "options {output=template;}\n"
086: + "a : ID INT -> foo(x={$ID.text},y={$INT.text}) ;\n"
087: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
088: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
089: String found = execParser("T.g", grammar, "TParser", "TLexer",
090: "a", "abc 34", debug);
091: assertEquals("abc 34\n", found);
092: }
093:
094: public void testIndirectTemplate() throws Exception {
095: // the support code adds template group in it's output Test.java
096: // that defines template foo.
097: String grammar = "grammar T;\n"
098: + "options {output=template;}\n"
099: + "a : ID INT -> ({\"foo\"})(x={$ID.text},y={$INT.text}) ;\n"
100: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
101: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
102: String found = execParser("T.g", grammar, "TParser", "TLexer",
103: "a", "abc 34", debug);
104: assertEquals("abc 34\n", found);
105: }
106:
107: public void testInlineTemplateInvokingLib() throws Exception {
108: String grammar = "grammar T;\n"
109: + "options {output=template;}\n"
110: + "a : ID INT -> template(x={$ID.text},y={$INT.text}) \"<foo(...)>\" ;\n"
111: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
112: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
113: String found = execParser("T.g", grammar, "TParser", "TLexer",
114: "a", "abc 34", debug);
115: assertEquals("abc 34\n", found);
116: }
117:
118: public void testPredicatedAlts() throws Exception {
119: // the support code adds template group in it's output Test.java
120: // that defines template foo.
121: String grammar = "grammar T;\n"
122: + "options {output=template;}\n"
123: + "a : ID INT -> {false}? foo(x={$ID.text},y={$INT.text})\n"
124: + " -> foo(x={\"hi\"}, y={$ID.text})\n"
125: + " ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
126: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
127: String found = execParser("T.g", grammar, "TParser", "TLexer",
128: "a", "abc 34", debug);
129: assertEquals("hi abc\n", found);
130: }
131:
132: public void testTemplateReturn() throws Exception {
133: String grammar = "grammar T;\n"
134: + "options {output=template;}\n"
135: + "a : b {System.out.println($b.st);} ;\n"
136: + "b : ID INT -> foo(x={$ID.text},y={$INT.text}) ;\n"
137: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
138: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
139: String found = execParser("T.g", grammar, "TParser", "TLexer",
140: "a", "abc 34", debug);
141: assertEquals("abc 34\n", found);
142: }
143:
144: public void testReturnValueWithTemplate() throws Exception {
145: String grammar = "grammar T;\n"
146: + "options {output=template;}\n"
147: + "a : b {System.out.println($b.i);} ;\n"
148: + "b returns [int i] : ID INT {$i=8;} ;\n"
149: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
150: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
151: String found = execParser("T.g", grammar, "TParser", "TLexer",
152: "a", "abc 34", debug);
153: assertEquals("8\n", found);
154: }
155:
156: public void testTemplateRefToDynamicAttributes() throws Exception {
157: String grammar = "grammar T;\n"
158: + "options {output=template;}\n"
159: + "a scope {String id;} : ID {$a::id=$ID.text;} b\n"
160: + " {System.out.println($b.st.toString());}\n"
161: + " ;\n" + "b : INT -> foo(x={$a::id}) ;\n"
162: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
163: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
164: String found = execParser("T.g", grammar, "TParser", "TLexer",
165: "a", "abc 34", debug);
166: assertEquals("abc \n", found);
167: }
168:
169: // tests for rewriting templates in tree parsers
170:
171: public void testSingleNode() throws Exception {
172: String grammar = "grammar T;\n" + "options {output=AST;}\n"
173: + "a : ID ;\n" + "ID : 'a'..'z'+ ;\n"
174: + "INT : '0'..'9'+;\n"
175: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
176:
177: String treeGrammar = "tree grammar TP;\n"
178: + "options {ASTLabelType=CommonTree; output=template;}\n"
179: + "s : a {System.out.println($a.st);} ;\n"
180: + "a : ID -> template(x={$ID.text}) <<|<x>|>> ;\n";
181:
182: String found = execTreeParser("T.g", grammar, "TParser",
183: "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc");
184: assertEquals("|abc|\n", found);
185: }
186:
187: /** tree parsing with output=template and rewrite=true */
188: public void testSingleNodeRewriteMode() throws Exception {
189: String grammar = "grammar T;\n" + "options {output=AST;}\n"
190: + "a : ID ;\n" + "ID : 'a'..'z'+ ;\n"
191: + "INT : '0'..'9'+;\n"
192: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
193:
194: String treeGrammar = "tree grammar TP;\n"
195: + "options {ASTLabelType=CommonTree; output=template; rewrite=true;}\n"
196: + "s : a {System.out.println(input.getTokenStream().toString(0,0));} ;\n"
197: + "a : ID -> template(x={$ID.text}) <<|<x>|>> ;\n";
198:
199: String found = execTreeParser("T.g", grammar, "TParser",
200: "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc");
201: assertEquals("|abc|\n", found);
202: }
203:
204: public void testRewriteRuleAndRewriteModeOnSimpleElements()
205: throws Exception {
206: ErrorQueue equeue = new ErrorQueue();
207: ErrorManager.setErrorListener(equeue);
208: Grammar g = new Grammar(
209: "tree grammar TP;\n"
210: + "options {ASTLabelType=CommonTree; output=template; rewrite=true;}\n"
211: + "a: ^(A B) -> {ick}\n"
212: + " | y+=INT -> {ick}\n" + " | x=ID -> {ick}\n"
213: + " | BLORT -> {ick}\n" + " ;\n");
214: Tool antlr = newTool();
215: antlr.setOutputDirectory(null); // write to /dev/null
216: CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
217: g.setCodeGenerator(generator);
218: generator.genRecognizer();
219:
220: assertEquals("unexpected errors: " + equeue, 0, equeue.warnings
221: .size());
222: }
223:
224: public void testRewriteRuleAndRewriteModeIgnoreActionsPredicates()
225: throws Exception {
226: ErrorQueue equeue = new ErrorQueue();
227: ErrorManager.setErrorListener(equeue);
228: Grammar g = new Grammar(
229: "tree grammar TP;\n"
230: + "options {ASTLabelType=CommonTree; output=template; rewrite=true;}\n"
231: + "a: {action} {action2} x=A -> {ick}\n"
232: + " | {pred1}? y+=B -> {ick}\n"
233: + " | C {action} -> {ick}\n"
234: + " | {pred2}?=> z+=D -> {ick}\n"
235: + " | (E)=> ^(F G) -> {ick}\n" + " ;\n");
236: Tool antlr = newTool();
237: antlr.setOutputDirectory(null); // write to /dev/null
238: CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
239: g.setCodeGenerator(generator);
240: generator.genRecognizer();
241:
242: assertEquals("unexpected errors: " + equeue, 0, equeue.warnings
243: .size());
244: }
245:
246: public void testRewriteRuleAndRewriteModeNotSimple()
247: throws Exception {
248: ErrorQueue equeue = new ErrorQueue();
249: ErrorManager.setErrorListener(equeue);
250: Grammar g = new Grammar(
251: "tree grammar TP;\n"
252: + "options {ASTLabelType=CommonTree; output=template; rewrite=true;}\n"
253: + "a : ID+ -> {ick}\n"
254: + " | INT INT -> {ick}\n" + " ;\n");
255: Tool antlr = newTool();
256: antlr.setOutputDirectory(null); // write to /dev/null
257: CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
258: g.setCodeGenerator(generator);
259: generator.genRecognizer();
260:
261: assertEquals("unexpected errors: " + equeue, 2, equeue.warnings
262: .size());
263: }
264:
265: public void testRewriteRuleAndRewriteModeRefRule() throws Exception {
266: ErrorQueue equeue = new ErrorQueue();
267: ErrorManager.setErrorListener(equeue);
268: Grammar g = new Grammar(
269: "tree grammar TP;\n"
270: + "options {ASTLabelType=CommonTree; output=template; rewrite=true;}\n"
271: + "a : b+ -> {ick}\n"
272: + " | b b A -> {ick}\n" + " ;\n"
273: + "b : B ;\n");
274: Tool antlr = newTool();
275: antlr.setOutputDirectory(null); // write to /dev/null
276: CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
277: g.setCodeGenerator(generator);
278: generator.genRecognizer();
279:
280: assertEquals("unexpected errors: " + equeue, 2, equeue.warnings
281: .size());
282: }
283:
284: }
|