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.junit.Test; 31 32 public class TestTreeParsing extends BaseTest { testFlatList()33 @Test public void testFlatList() throws Exception { 34 String grammar = 35 "grammar T;\n" + 36 "options {output=AST;}\n" + 37 "a : ID INT;\n" + 38 "ID : 'a'..'z'+ ;\n" + 39 "INT : '0'..'9'+;\n" + 40 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 41 42 String treeGrammar = 43 "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + 44 "a : ID INT\n" + 45 " {System.out.println($ID+\", \"+$INT);}\n" + 46 " ;\n"; 47 48 String found = execTreeParser("T.g", grammar, "TParser", "TP.g", 49 treeGrammar, "TP", "TLexer", "a", "a", "abc 34"); 50 assertEquals("abc, 34\n", found); 51 } 52 testSimpleTree()53 @Test public void testSimpleTree() throws Exception { 54 String grammar = 55 "grammar T;\n" + 56 "options {output=AST;}\n" + 57 "a : ID INT -> ^(ID INT);\n" + 58 "ID : 'a'..'z'+ ;\n" + 59 "INT : '0'..'9'+;\n" + 60 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 61 62 String treeGrammar = 63 "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + 64 "a : ^(ID INT)\n" + 65 " {System.out.println($ID+\", \"+$INT);}\n" + 66 " ;\n"; 67 68 String found = execTreeParser("T.g", grammar, "TParser", "TP.g", 69 treeGrammar, "TP", "TLexer", "a", "a", "abc 34"); 70 assertEquals("abc, 34\n", found); 71 } 72 testFlatVsTreeDecision()73 @Test public void testFlatVsTreeDecision() throws Exception { 74 String grammar = 75 "grammar T;\n" + 76 "options {output=AST;}\n" + 77 "a : b c ;\n" + 78 "b : ID INT -> ^(ID INT);\n" + 79 "c : ID INT;\n" + 80 "ID : 'a'..'z'+ ;\n" + 81 "INT : '0'..'9'+;\n" + 82 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 83 84 String treeGrammar = 85 "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + 86 "a : b b ;\n" + 87 "b : ID INT {System.out.print($ID+\" \"+$INT);}\n" + 88 " | ^(ID INT) {System.out.print(\"^(\"+$ID+\" \"+$INT+')');}\n" + 89 " ;\n"; 90 91 String found = execTreeParser("T.g", grammar, "TParser", "TP.g", 92 treeGrammar, "TP", "TLexer", "a", "a", "a 1 b 2"); 93 assertEquals("^(a 1)b 2\n", found); 94 } 95 testFlatVsTreeDecision2()96 @Test public void testFlatVsTreeDecision2() throws Exception { 97 String grammar = 98 "grammar T;\n" + 99 "options {output=AST;}\n" + 100 "a : b c ;\n" + 101 "b : ID INT+ -> ^(ID INT+);\n" + 102 "c : ID INT+;\n" + 103 "ID : 'a'..'z'+ ;\n" + 104 "INT : '0'..'9'+;\n" + 105 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 106 107 String treeGrammar = 108 "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + 109 "a : b b ;\n" + 110 "b : ID INT+ {System.out.print($ID+\" \"+$INT);}\n" + 111 " | ^(x=ID (y=INT)+) {System.out.print(\"^(\"+$x+' '+$y+')');}\n" + 112 " ;\n"; 113 114 String found = execTreeParser("T.g", grammar, "TParser", "TP.g", 115 treeGrammar, "TP", "TLexer", "a", "a", 116 "a 1 2 3 b 4 5"); 117 assertEquals("^(a 3)b 5\n", found); 118 } 119 testCyclicDFALookahead()120 @Test public void testCyclicDFALookahead() throws Exception { 121 String grammar = 122 "grammar T;\n" + 123 "options {output=AST;}\n" + 124 "a : ID INT+ PERIOD;\n" + 125 "ID : 'a'..'z'+ ;\n" + 126 "INT : '0'..'9'+;\n" + 127 "SEMI : ';' ;\n"+ 128 "PERIOD : '.' ;\n"+ 129 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 130 131 String treeGrammar = 132 "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + 133 "a : ID INT+ PERIOD {System.out.print(\"alt 1\");}"+ 134 " | ID INT+ SEMI {System.out.print(\"alt 2\");}\n" + 135 " ;\n"; 136 137 String found = execTreeParser("T.g", grammar, "TParser", "TP.g", 138 treeGrammar, "TP", "TLexer", "a", "a", "a 1 2 3."); 139 assertEquals("alt 1\n", found); 140 } 141 testTemplateOutput()142 @Test public void testTemplateOutput() throws Exception { 143 String grammar = 144 "grammar T;\n" + 145 "options {output=AST;}\n" + 146 "a : ID INT;\n" + 147 "ID : 'a'..'z'+ ;\n" + 148 "INT : '0'..'9'+;\n" + 149 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 150 151 String treeGrammar = 152 "tree grammar TP;\n" + 153 "options {output=template; ASTLabelType=CommonTree;}\n" + 154 "s : a {System.out.println($a.st);};\n" + 155 "a : ID INT -> {new StringTemplate($INT.text)}\n" + 156 " ;\n"; 157 158 String found = execTreeParser("T.g", grammar, "TParser", "TP.g", 159 treeGrammar, "TP", "TLexer", "a", "s", "abc 34"); 160 assertEquals("34\n", found); 161 } 162 testNullableChildList()163 @Test public void testNullableChildList() throws Exception { 164 String grammar = 165 "grammar T;\n" + 166 "options {output=AST;}\n" + 167 "a : ID INT? -> ^(ID INT?);\n" + 168 "ID : 'a'..'z'+ ;\n" + 169 "INT : '0'..'9'+;\n" + 170 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 171 172 String treeGrammar = 173 "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + 174 "a : ^(ID INT?)\n" + 175 " {System.out.println($ID);}\n" + 176 " ;\n"; 177 178 String found = execTreeParser("T.g", grammar, "TParser", "TP.g", 179 treeGrammar, "TP", "TLexer", "a", "a", "abc"); 180 assertEquals("abc\n", found); 181 } 182 testNullableChildList2()183 @Test public void testNullableChildList2() throws Exception { 184 String grammar = 185 "grammar T;\n" + 186 "options {output=AST;}\n" + 187 "a : ID INT? SEMI -> ^(ID INT?) SEMI ;\n" + 188 "ID : 'a'..'z'+ ;\n" + 189 "INT : '0'..'9'+;\n" + 190 "SEMI : ';' ;\n"+ 191 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 192 193 String treeGrammar = 194 "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + 195 "a : ^(ID INT?) SEMI\n" + 196 " {System.out.println($ID);}\n" + 197 " ;\n"; 198 199 String found = execTreeParser("T.g", grammar, "TParser", "TP.g", 200 treeGrammar, "TP", "TLexer", "a", "a", "abc;"); 201 assertEquals("abc\n", found); 202 } 203 testNullableChildList3()204 @Test public void testNullableChildList3() throws Exception { 205 String grammar = 206 "grammar T;\n" + 207 "options {output=AST;}\n" + 208 "a : x=ID INT? (y=ID)? SEMI -> ^($x INT? $y?) SEMI ;\n" + 209 "ID : 'a'..'z'+ ;\n" + 210 "INT : '0'..'9'+;\n" + 211 "SEMI : ';' ;\n"+ 212 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 213 214 String treeGrammar = 215 "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + 216 "a : ^(ID INT? b) SEMI\n" + 217 " {System.out.println($ID+\", \"+$b.text);}\n" + 218 " ;\n"+ 219 "b : ID? ;\n"; 220 221 String found = execTreeParser("T.g", grammar, "TParser", "TP.g", 222 treeGrammar, "TP", "TLexer", "a", "a", "abc def;"); 223 assertEquals("abc, def\n", found); 224 } 225 testActionsAfterRoot()226 @Test public void testActionsAfterRoot() throws Exception { 227 String grammar = 228 "grammar T;\n" + 229 "options {output=AST;}\n" + 230 "a : x=ID INT? SEMI -> ^($x INT?) ;\n" + 231 "ID : 'a'..'z'+ ;\n" + 232 "INT : '0'..'9'+;\n" + 233 "SEMI : ';' ;\n"+ 234 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 235 236 String treeGrammar = 237 "tree grammar TP; options {ASTLabelType=CommonTree;}\n" + 238 "a @init {int x=0;} : ^(ID {x=1;} {x=2;} INT?)\n" + 239 " {System.out.println($ID+\", \"+x);}\n" + 240 " ;\n"; 241 242 String found = execTreeParser("T.g", grammar, "TParser", "TP.g", 243 treeGrammar, "TP", "TLexer", "a", "a", "abc;"); 244 assertEquals("abc, 2\n", found); 245 } 246 testWildcardLookahead()247 @Test public void testWildcardLookahead() throws Exception { 248 String grammar = 249 "grammar T;\n" + 250 "options {output=AST;}\n" + 251 "a : ID '+'^ INT;\n" + 252 "ID : 'a'..'z'+ ;\n" + 253 "INT : '0'..'9'+;\n" + 254 "SEMI : ';' ;\n"+ 255 "PERIOD : '.' ;\n"+ 256 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 257 258 String treeGrammar = 259 "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonTree;}\n" + 260 "a : ^('+' . INT) {System.out.print(\"alt 1\");}"+ 261 " ;\n"; 262 263 String found = execTreeParser("T.g", grammar, "TParser", "TP.g", 264 treeGrammar, "TP", "TLexer", "a", "a", "a + 2"); 265 assertEquals("alt 1\n", found); 266 } 267 testWildcardLookahead2()268 @Test public void testWildcardLookahead2() throws Exception { 269 String grammar = 270 "grammar T;\n" + 271 "options {output=AST;}\n" + 272 "a : ID '+'^ INT;\n" + 273 "ID : 'a'..'z'+ ;\n" + 274 "INT : '0'..'9'+;\n" + 275 "SEMI : ';' ;\n"+ 276 "PERIOD : '.' ;\n"+ 277 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 278 279 String treeGrammar = 280 "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonTree;}\n" + 281 "a : ^('+' . INT) {System.out.print(\"alt 1\");}"+ 282 " | ^('+' . .) {System.out.print(\"alt 2\");}\n" + 283 " ;\n"; 284 285 // AMBIG upon '+' DOWN INT UP etc.. but so what. 286 287 String found = execTreeParser("T.g", grammar, "TParser", "TP.g", 288 treeGrammar, "TP", "TLexer", "a", "a", "a + 2"); 289 assertEquals("alt 1\n", found); 290 } 291 testWildcardLookahead3()292 @Test public void testWildcardLookahead3() throws Exception { 293 String grammar = 294 "grammar T;\n" + 295 "options {output=AST;}\n" + 296 "a : ID '+'^ INT;\n" + 297 "ID : 'a'..'z'+ ;\n" + 298 "INT : '0'..'9'+;\n" + 299 "SEMI : ';' ;\n"+ 300 "PERIOD : '.' ;\n"+ 301 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 302 303 String treeGrammar = 304 "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonTree;}\n" + 305 "a : ^('+' ID INT) {System.out.print(\"alt 1\");}"+ 306 " | ^('+' . .) {System.out.print(\"alt 2\");}\n" + 307 " ;\n"; 308 309 // AMBIG upon '+' DOWN INT UP etc.. but so what. 310 311 String found = execTreeParser("T.g", grammar, "TParser", "TP.g", 312 treeGrammar, "TP", "TLexer", "a", "a", "a + 2"); 313 assertEquals("alt 1\n", found); 314 } 315 testWildcardPlusLookahead()316 @Test public void testWildcardPlusLookahead() throws Exception { 317 String grammar = 318 "grammar T;\n" + 319 "options {output=AST;}\n" + 320 "a : ID '+'^ INT;\n" + 321 "ID : 'a'..'z'+ ;\n" + 322 "INT : '0'..'9'+;\n" + 323 "SEMI : ';' ;\n"+ 324 "PERIOD : '.' ;\n"+ 325 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 326 327 String treeGrammar = 328 "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonTree;}\n" + 329 "a : ^('+' INT INT ) {System.out.print(\"alt 1\");}"+ 330 " | ^('+' .+) {System.out.print(\"alt 2\");}\n" + 331 " ;\n"; 332 333 // AMBIG upon '+' DOWN INT UP etc.. but so what. 334 335 String found = execTreeParser("T.g", grammar, "TParser", "TP.g", 336 treeGrammar, "TP", "TLexer", "a", "a", "a + 2"); 337 assertEquals("alt 2\n", found); 338 } 339 340 } 341