1 /* 2 * [The "BSD license"] 3 * Copyright (c) 2010 Terence Parr 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 package org.antlr.test; 29 30 import org.antlr.Tool; 31 import org.antlr.codegen.CodeGenerator; 32 import org.antlr.tool.*; 33 import org.junit.Test; 34 35 public class TestRewriteTemplates extends BaseTest { 36 protected boolean debug = false; 37 testDelete()38 @Test public void testDelete() throws Exception { 39 String grammar = 40 "grammar T;\n" + 41 "options {output=template;}\n" + 42 "a : ID INT -> ;\n" + 43 "ID : 'a'..'z'+ ;\n" + 44 "INT : '0'..'9'+;\n" + 45 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 46 String found = execParser("T.g", grammar, "TParser", "TLexer", 47 "a", "abc 34", debug); 48 assertEquals("", found); 49 } 50 testAction()51 @Test public void testAction() throws Exception { 52 String grammar = 53 "grammar T;\n" + 54 "options {output=template;}\n" + 55 "a : ID INT -> {new StringTemplate($ID.text)} ;\n" + 56 "ID : 'a'..'z'+ ;\n" + 57 "INT : '0'..'9'+;\n" + 58 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 59 String found = execParser("T.g", grammar, "TParser", "TLexer", 60 "a", "abc 34", debug); 61 assertEquals("abc\n", found); 62 } 63 testEmbeddedLiteralConstructor()64 @Test public void testEmbeddedLiteralConstructor() throws Exception { 65 String grammar = 66 "grammar T;\n" + 67 "options {output=template;}\n" + 68 "a : ID INT -> {%{$ID.text}} ;\n" + 69 "ID : 'a'..'z'+ ;\n" + 70 "INT : '0'..'9'+;\n" + 71 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 72 String found = execParser("T.g", grammar, "TParser", "TLexer", 73 "a", "abc 34", debug); 74 assertEquals("abc\n", found); 75 } 76 testInlineTemplate()77 @Test public void testInlineTemplate() throws Exception { 78 String grammar = 79 "grammar T;\n" + 80 "options {output=template;}\n" + 81 "a : ID INT -> template(x={$ID},y={$INT}) <<x:<x.text>, y:<y.text>;>> ;\n" + 82 "ID : 'a'..'z'+ ;\n" + 83 "INT : '0'..'9'+;\n" + 84 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 85 String found = execParser("T.g", grammar, "TParser", "TLexer", 86 "a", "abc 34", debug); 87 assertEquals("x:abc, y:34;\n", found); 88 } 89 testNamedTemplate()90 @Test public void testNamedTemplate() throws Exception { 91 // the support code adds template group in it's output Test.java 92 // that defines template foo. 93 String grammar = 94 "grammar T;\n" + 95 "options {output=template;}\n" + 96 "a : ID INT -> foo(x={$ID.text},y={$INT.text}) ;\n" + 97 "ID : 'a'..'z'+ ;\n" + 98 "INT : '0'..'9'+;\n" + 99 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 100 String found = execParser("T.g", grammar, "TParser", "TLexer", 101 "a", "abc 34", debug); 102 assertEquals("abc 34\n", found); 103 } 104 testIndirectTemplate()105 @Test public void testIndirectTemplate() throws Exception { 106 // the support code adds template group in it's output Test.java 107 // that defines template foo. 108 String grammar = 109 "grammar T;\n" + 110 "options {output=template;}\n" + 111 "a : ID INT -> ({\"foo\"})(x={$ID.text},y={$INT.text}) ;\n" + 112 "ID : 'a'..'z'+ ;\n" + 113 "INT : '0'..'9'+;\n" + 114 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 115 String found = execParser("T.g", grammar, "TParser", "TLexer", 116 "a", "abc 34", debug); 117 assertEquals("abc 34\n", found); 118 } 119 testInlineTemplateInvokingLib()120 @Test public void testInlineTemplateInvokingLib() throws Exception { 121 String grammar = 122 "grammar T;\n" + 123 "options {output=template;}\n" + 124 "a : ID INT -> template(x={$ID.text},y={$INT.text}) \"<foo(...)>\" ;\n" + 125 "ID : 'a'..'z'+ ;\n" + 126 "INT : '0'..'9'+;\n" + 127 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 128 String found = execParser("T.g", grammar, "TParser", "TLexer", 129 "a", "abc 34", debug); 130 assertEquals("abc 34\n", found); 131 } 132 testPredicatedAlts()133 @Test public void testPredicatedAlts() throws Exception { 134 // the support code adds template group in it's output Test.java 135 // that defines template foo. 136 String grammar = 137 "grammar T;\n" + 138 "options {output=template;}\n" + 139 "a : ID INT -> {false}? foo(x={$ID.text},y={$INT.text})\n" + 140 " -> foo(x={\"hi\"}, y={$ID.text})\n" + 141 " ;\n" + 142 "ID : 'a'..'z'+ ;\n" + 143 "INT : '0'..'9'+;\n" + 144 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 145 String found = execParser("T.g", grammar, "TParser", "TLexer", 146 "a", "abc 34", debug); 147 assertEquals("hi abc\n", found); 148 } 149 testTemplateReturn()150 @Test public void testTemplateReturn() throws Exception { 151 String grammar = 152 "grammar T;\n" + 153 "options {output=template;}\n" + 154 "a : b {System.out.println($b.st);} ;\n" + 155 "b : ID INT -> foo(x={$ID.text},y={$INT.text}) ;\n" + 156 "ID : 'a'..'z'+ ;\n" + 157 "INT : '0'..'9'+;\n" + 158 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 159 String found = execParser("T.g", grammar, "TParser", "TLexer", 160 "a", "abc 34", debug); 161 assertEquals("abc 34\n", found); 162 } 163 testReturnValueWithTemplate()164 @Test public void testReturnValueWithTemplate() throws Exception { 165 String grammar = 166 "grammar T;\n" + 167 "options {output=template;}\n" + 168 "a : b {System.out.println($b.i);} ;\n" + 169 "b returns [int i] : ID INT {$i=8;} ;\n" + 170 "ID : 'a'..'z'+ ;\n" + 171 "INT : '0'..'9'+;\n" + 172 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 173 String found = execParser("T.g", grammar, "TParser", "TLexer", 174 "a", "abc 34", debug); 175 assertEquals("8\n", found); 176 } 177 testTemplateRefToDynamicAttributes()178 @Test public void testTemplateRefToDynamicAttributes() throws Exception { 179 String grammar = 180 "grammar T;\n" + 181 "options {output=template;}\n" + 182 "a scope {String id;} : ID {$a::id=$ID.text;} b\n" + 183 " {System.out.println($b.st.toString());}\n" + 184 " ;\n" + 185 "b : INT -> foo(x={$a::id}) ;\n" + 186 "ID : 'a'..'z'+ ;\n" + 187 "INT : '0'..'9'+;\n" + 188 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 189 String found = execParser("T.g", grammar, "TParser", "TLexer", 190 "a", "abc 34", debug); 191 assertEquals("abc \n", found); 192 } 193 194 // tests for rewriting templates in tree parsers 195 testSingleNode()196 @Test public void testSingleNode() throws Exception { 197 String grammar = 198 "grammar T;\n" + 199 "options {output=AST;}\n" + 200 "a : ID ;\n" + 201 "ID : 'a'..'z'+ ;\n" + 202 "INT : '0'..'9'+;\n" + 203 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 204 205 String treeGrammar = 206 "tree grammar TP;\n"+ 207 "options {ASTLabelType=CommonTree; output=template;}\n" + 208 "s : a {System.out.println($a.st);} ;\n" + 209 "a : ID -> template(x={$ID.text}) <<|<x>|>> ;\n"; 210 211 String found = execTreeParser("T.g", grammar, "TParser", "TP.g", 212 treeGrammar, "TP", "TLexer", "a", "s", "abc"); 213 assertEquals("|abc|\n", found); 214 } 215 testSingleNodeRewriteMode()216 @Test public void testSingleNodeRewriteMode() throws Exception { 217 String grammar = 218 "grammar T;\n" + 219 "options {output=AST;}\n" + 220 "a : ID ;\n" + 221 "ID : 'a'..'z'+ ;\n" + 222 "INT : '0'..'9'+;\n" + 223 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 224 225 String treeGrammar = 226 "tree grammar TP;\n"+ 227 "options {ASTLabelType=CommonTree; output=template; rewrite=true;}\n" + 228 "s : a {System.out.println(input.getTokenStream().toString(0,0));} ;\n" + 229 "a : ID -> template(x={$ID.text}) <<|<x>|>> ;\n"; 230 231 String found = execTreeParser("T.g", grammar, "TParser", "TP.g", 232 treeGrammar, "TP", "TLexer", "a", "s", "abc"); 233 assertEquals("|abc|\n", found); 234 } 235 testRewriteRuleAndRewriteModeOnSimpleElements()236 @Test public void testRewriteRuleAndRewriteModeOnSimpleElements() throws Exception { 237 ErrorQueue equeue = new ErrorQueue(); 238 ErrorManager.setErrorListener(equeue); 239 Grammar g = new Grammar( 240 "tree grammar TP;\n"+ 241 "options {ASTLabelType=CommonTree; output=template; rewrite=true;}\n" + 242 "a: ^(A B) -> {ick}\n" + 243 " | y+=INT -> {ick}\n" + 244 " | x=ID -> {ick}\n" + 245 " | BLORT -> {ick}\n" + 246 " ;\n" 247 ); 248 Tool antlr = newTool(); 249 antlr.setOutputDirectory(null); // write to /dev/null 250 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 251 g.setCodeGenerator(generator); 252 generator.genRecognizer(); 253 254 assertEquals("unexpected errors: "+equeue, 0, equeue.warnings.size()); 255 } 256 testRewriteRuleAndRewriteModeIgnoreActionsPredicates()257 @Test public void testRewriteRuleAndRewriteModeIgnoreActionsPredicates() throws Exception { 258 ErrorQueue equeue = new ErrorQueue(); 259 ErrorManager.setErrorListener(equeue); 260 Grammar g = new Grammar( 261 "tree grammar TP;\n"+ 262 "options {ASTLabelType=CommonTree; output=template; rewrite=true;}\n" + 263 "a: {action} {action2} x=A -> {ick}\n" + 264 " | {pred1}? y+=B -> {ick}\n" + 265 " | C {action} -> {ick}\n" + 266 " | {pred2}?=> z+=D -> {ick}\n" + 267 " | (E)=> ^(F G) -> {ick}\n" + 268 " ;\n" 269 ); 270 Tool antlr = newTool(); 271 antlr.setOutputDirectory(null); // write to /dev/null 272 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 273 g.setCodeGenerator(generator); 274 generator.genRecognizer(); 275 276 assertEquals("unexpected errors: "+equeue, 0, equeue.warnings.size()); 277 } 278 testRewriteRuleAndRewriteModeNotSimple()279 @Test public void testRewriteRuleAndRewriteModeNotSimple() throws Exception { 280 ErrorQueue equeue = new ErrorQueue(); 281 ErrorManager.setErrorListener(equeue); 282 Grammar g = new Grammar( 283 "tree grammar TP;\n"+ 284 "options {ASTLabelType=CommonTree; output=template; rewrite=true;}\n" + 285 "a : ID+ -> {ick}\n" + 286 " | INT INT -> {ick}\n" + 287 " ;\n" 288 ); 289 Tool antlr = newTool(); 290 antlr.setOutputDirectory(null); // write to /dev/null 291 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 292 g.setCodeGenerator(generator); 293 generator.genRecognizer(); 294 295 assertEquals("unexpected errors: "+equeue, 0, equeue.warnings.size()); 296 } 297 testRewriteRuleAndRewriteModeRefRule()298 @Test public void testRewriteRuleAndRewriteModeRefRule() throws Exception { 299 ErrorQueue equeue = new ErrorQueue(); 300 ErrorManager.setErrorListener(equeue); 301 Grammar g = new Grammar( 302 "tree grammar TP;\n"+ 303 "options {ASTLabelType=CommonTree; output=template; rewrite=true;}\n" + 304 "a : b+ -> {ick}\n" + 305 " | b b A -> {ick}\n" + 306 " ;\n" + 307 "b : B ;\n" 308 ); 309 Tool antlr = newTool(); 310 antlr.setOutputDirectory(null); // write to /dev/null 311 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 312 g.setCodeGenerator(generator); 313 generator.genRecognizer(); 314 315 assertEquals("unexpected errors: "+equeue, 0, equeue.warnings.size()); 316 } 317 318 } 319