/* * [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.runtime.RecognitionException; import org.antlr.tool.ErrorManager; import org.antlr.tool.Grammar; import org.antlr.tool.GrammarSyntaxMessage; import org.junit.Ignore; import org.junit.Test; /** Tree rewrites in tree parsers are basically identical to rewrites * in a normal grammar except that the atomic element is a node not * a Token. Tests here ensure duplication of nodes occurs properly * and basic functionality. */ public class TestTreeGrammarRewriteAST extends BaseTest { protected boolean debug = false; @Test public void testFlatList() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ID INT -> INT ID\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "abc 34"); assertEquals("34 abc\n", found); } @Test public void testSimpleTree() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID INT);\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ^(ID INT) -> ^(INT ID)\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "abc 34"); assertEquals("(34 abc)\n", found); } @Test public void testNonImaginaryWithCtor() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : INT ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : INT -> INT[\"99\"]\n" + // make new INT node " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "34"); assertEquals("99\n", found); } @Test public void testCombinedRewriteAndAuto() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID INT) | INT ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ^(ID INT) -> ^(INT ID) | INT\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "abc 34"); assertEquals("(34 abc)\n", found); found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "34"); assertEquals("34\n", found); } @Test public void testAvoidDup() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ID -> ^(ID ID)\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "abc"); assertEquals("(abc abc)\n", found); } @Test public void testLoop() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID+ INT+ -> (^(ID INT))+ ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : (^(ID INT))+ -> INT+ ID+\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "a b c 3 4 5"); assertEquals("3 4 5 a b c\n", found); } @Test public void testAutoDup() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ID \n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "abc"); assertEquals("abc\n", found); } @Test public void testAutoDupRule() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : b c ;\n" + "b : ID ;\n" + "c : INT ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "a 1"); assertEquals("a 1\n", found); } @Test public void testAutoWildcard() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ID . \n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "abc 34"); assertEquals("abc 34\n", found); } @Test public void testNoWildcardAsRootError() throws Exception { ErrorQueue equeue = new ErrorQueue(); ErrorManager.setErrorListener(equeue); String treeGrammar = "tree grammar TP;\n"+ "options {output=AST;}\n" + "a : ^(. INT) \n" + " ;\n"; Grammar g = new Grammar(treeGrammar); Tool antlr = newTool(); antlr.setOutputDirectory(null); // write to /dev/null CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); g.setCodeGenerator(generator); generator.genRecognizer(); assertEquals("unexpected errors: "+equeue, 1, equeue.errors.size()); int expectedMsgID = ErrorManager.MSG_WILDCARD_AS_ROOT; Object expectedArg = null; RecognitionException expectedExc = null; GrammarSyntaxMessage expectedMessage = new GrammarSyntaxMessage(expectedMsgID, g, null, expectedArg, expectedExc); checkError(equeue, expectedMessage); } @Test public void testAutoWildcard2() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID INT);\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ^(ID .) \n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "abc 34"); assertEquals("(abc 34)\n", found); } @Test public void testAutoWildcardWithLabel() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ID c=. \n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "abc 34"); assertEquals("abc 34\n", found); } @Test public void testAutoWildcardWithListLabel() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ID c+=. \n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "abc 34"); assertEquals("abc 34\n", found); } @Test public void testAutoDupMultiple() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID ID INT;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ID ID INT\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "a b 3"); assertEquals("a b 3\n", found); } @Test public void testAutoDupTree() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID INT);\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ^(ID INT)\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "a 3"); assertEquals("(a 3)\n", found); } @Test public void testAutoDupTree2() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT INT -> ^(ID INT INT);\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ^(ID b b)\n" + " ;\n" + "b : INT ;"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "a 3 4"); assertEquals("(a 3 4)\n", found); } @Test public void testAutoDupTreeWithLabels() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID INT);\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ^(x=ID y=INT)\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "a 3"); assertEquals("(a 3)\n", found); } @Test public void testAutoDupTreeWithListLabels() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID INT);\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ^(x+=ID y+=INT)\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "a 3"); assertEquals("(a 3)\n", found); } @Test public void testAutoDupTreeWithRuleRoot() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID INT);\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ^(b INT) ;\n" + "b : ID ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "a 3"); assertEquals("(a 3)\n", found); } @Test public void testAutoDupTreeWithRuleRootAndLabels() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID INT);\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ^(x=b INT) ;\n" + "b : ID ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "a 3"); assertEquals("(a 3)\n", found); } @Test public void testAutoDupTreeWithRuleRootAndListLabels() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID INT);\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ^(x+=b y+=c) ;\n" + "b : ID ;\n" + "c : INT ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "a 3"); assertEquals("(a 3)\n", found); } @Test public void testAutoDupNestedTree() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : x=ID y=ID INT -> ^($x ^($y INT));\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ^(ID ^(ID INT))\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "a b 3"); assertEquals("(a (b 3))\n", found); } @Test public void testAutoDupTreeWithSubruleInside() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "tokens {OP;}\n" + "a : (x=ID|x=INT) -> ^(OP $x) ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ^(OP (b|c)) ;\n" + "b : ID ;\n" + "c : INT ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "a"); assertEquals("(OP a)\n", found); } @Test public void testDelete() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ID -> \n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "abc"); assertEquals("", found); } @Test public void testSetMatchNoRewrite() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : b INT\n" + " ;\n" + "b : ID | INT ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "abc 34"); assertEquals("abc 34\n", found); } @Test public void testSetOptionalMatchNoRewrite() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : (ID|INT)? INT ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "abc 34"); assertEquals("abc 34\n", found); } @Test public void testSetMatchNoRewriteLevel2() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : x=ID INT -> ^($x INT);\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ^(ID (ID | INT) ) ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "abc 34"); assertEquals("(abc 34)\n", found); } @Test public void testSetMatchNoRewriteLevel2Root() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : x=ID INT -> ^($x INT);\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ^((ID | INT) INT) ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "abc 34"); assertEquals("(abc 34)\n", found); } // REWRITE MODE @Test public void testRewriteModeCombinedRewriteAndAuto() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID INT) | INT ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" + "a : ^(ID INT) -> ^(ID[\"ick\"] INT)\n" + " | INT\n" + // leaves it alone, returning $a.start " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "abc 34"); assertEquals("(ick 34)\n", found); found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "34"); assertEquals("34\n", found); } @Test public void testRewriteModeFlatTree() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ID INT | INT ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" + "s : ID a ;\n" + "a : INT -> INT[\"1\"]\n"+ " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc 34"); assertEquals("abc 1\n", found); } @Test public void testRewriteModeChainRuleFlatTree() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ID INT | INT ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" + "s : a ;\n" + "a : b ;\n" + "b : ID INT -> INT ID\n"+ " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc 34"); assertEquals("34 abc\n", found); } @Test public void testRewriteModeChainRuleTree() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID INT) ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" + "s : a ;\n" + "a : b ;\n" + // a.tree must become b.tree "b : ^(ID INT) -> INT\n"+ " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc 34"); assertEquals("34\n", found); } @Test public void testRewriteModeChainRuleTree2() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID INT) ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" + "tokens { X; }\n" + "s : a* b ;\n" + // only b contributes to tree, but it's after a*; s.tree = b.tree "a : X ;\n" + "b : ^(ID INT) -> INT\n"+ " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc 34"); assertEquals("34\n", found); } @Test public void testRewriteModeChainRuleTree3() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : 'boo' ID INT -> 'boo' ^(ID INT) ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" + "tokens { X; }\n" + "s : 'boo' a* b ;\n" + // don't reset s.tree to b.tree due to 'boo' "a : X ;\n" + "b : ^(ID INT) -> INT\n"+ " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "boo abc 34"); assertEquals("boo 34\n", found); } @Test public void testRewriteModeChainRuleTree4() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : 'boo' ID INT -> ^('boo' ^(ID INT)) ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" + "tokens { X; }\n" + "s : ^('boo' a* b) ;\n" + // don't reset s.tree to b.tree due to 'boo' "a : X ;\n" + "b : ^(ID INT) -> INT\n"+ " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "boo abc 34"); assertEquals("(boo 34)\n", found); } @Test public void testRewriteModeChainRuleTree5() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : 'boo' ID INT -> ^('boo' ^(ID INT)) ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" + "tokens { X; }\n" + "s : ^(a b) ;\n" + // s.tree is a.tree "a : 'boo' ;\n" + "b : ^(ID INT) -> INT\n"+ " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "boo abc 34"); assertEquals("(boo 34)\n", found); } @Test public void testRewriteOfRuleRef() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ID INT | INT ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" + "s : a -> a ;\n" + "a : ID INT -> ID INT ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc 34"); assertEquals("abc 34\n", found); } @Test public void testRewriteOfRuleRefRoot() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT INT -> ^(INT ^(ID INT));\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" + "s : ^(a ^(ID INT)) -> a ;\n" + "a : INT ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc 12 34"); // emits whole tree when you ref the root since I can't know whether // you want the children or not. You might be returning a whole new // tree. Hmm...still seems weird. oh well. assertEquals("(12 (abc 34))\n", found); } @Test public void testRewriteOfRuleRefRootLabeled() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT INT -> ^(INT ^(ID INT));\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" + "s : ^(label=a ^(ID INT)) -> a ;\n" + "a : INT ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc 12 34"); // emits whole tree when you ref the root since I can't know whether // you want the children or not. You might be returning a whole new // tree. Hmm...still seems weird. oh well. assertEquals("(12 (abc 34))\n", found); } @Ignore @Test public void testRewriteOfRuleRefRootListLabeled() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT INT -> ^(INT ^(ID INT));\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" + "s : ^(label+=a ^(ID INT)) -> a ;\n" + "a : INT ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc 12 34"); // emits whole tree when you ref the root since I can't know whether // you want the children or not. You might be returning a whole new // tree. Hmm...still seems weird. oh well. assertEquals("(12 (abc 34))\n", found); } @Test public void testRewriteOfRuleRefChild() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID ^(INT INT));\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" + "s : ^(ID a) -> a ;\n" + "a : ^(INT INT) ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc 34"); assertEquals("(34 34)\n", found); } @Test public void testRewriteOfRuleRefLabel() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID ^(INT INT));\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" + "s : ^(ID label=a) -> a ;\n" + "a : ^(INT INT) ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc 34"); assertEquals("(34 34)\n", found); } @Test public void testRewriteOfRuleRefListLabel() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID ^(INT INT));\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" + "s : ^(ID label+=a) -> a ;\n" + "a : ^(INT INT) ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc 34"); assertEquals("(34 34)\n", found); } @Test public void testRewriteModeWithPredicatedRewrites() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID[\"root\"] ^(ID INT)) | INT -> ^(ID[\"root\"] INT) ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" + "s : ^(ID a) {System.out.println(\"altered tree=\"+$s.start.toStringTree());};\n" + "a : ^(ID INT) -> {true}? ^(ID[\"ick\"] INT)\n" + " -> INT\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc 34"); assertEquals("altered tree=(root (ick 34))\n" + "(root (ick 34))\n", found); } @Test public void testWildcardSingleNode() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID[\"root\"] INT);\n"+ "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "s : ^(ID c=.) -> $c\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc 34"); assertEquals("34\n", found); } @Test public void testWildcardUnlabeledSingleNode() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID INT -> ^(ID INT);\n"+ "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "s : ^(ID .) -> ID\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc 34"); assertEquals("abc\n", found); } @Test public void testWildcardGrabsSubtree() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID x=INT y=INT z=INT -> ^(ID[\"root\"] ^($x $y $z));\n"+ "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "s : ^(ID c=.) -> $c\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc 1 2 3"); assertEquals("(1 2 3)\n", found); } @Test public void testWildcardGrabsSubtree2() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID x=INT y=INT z=INT -> ID ^($x $y $z);\n"+ "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "s : ID c=. -> $c\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "abc 1 2 3"); assertEquals("(1 2 3)\n", found); } @Test public void testWildcardListLabel() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : INT INT INT ;\n"+ "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "s : (c+=.)+ -> $c+\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "1 2 3"); assertEquals("1 2 3\n", found); } @Test public void testWildcardListLabel2() throws Exception { String grammar = "grammar T;\n" + "options {output=AST; ASTLabelType=CommonTree;}\n" + "a : x=INT y=INT z=INT -> ^($x ^($y $z) ^($y $z));\n"+ "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" + "s : ^(INT (c+=.)+) -> $c+\n" + " ;\n"; String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "s", "1 2 3"); assertEquals("(2 3) (2 3)\n", found); } @Test public void testRuleResultAsRoot() throws Exception { String grammar = "grammar T;\n" + "options {output=AST;}\n" + "a : ID '=' INT -> ^('=' ID INT);\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n" + "COLON : ':' ;\n" + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; String treeGrammar = "tree grammar TP;\n"+ "options {output=AST; rewrite=true; ASTLabelType=CommonTree; tokenVocab=T;}\n" + "a : ^(eq e1=ID e2=.) -> ^(eq $e2 $e1) ;\n" + "eq : '=' | ':' {;} ;\n"; // bug in set match, doesn't add to tree!! booh. force nonset. String found = execTreeParser("T.g", grammar, "TParser", "TP.g", treeGrammar, "TP", "TLexer", "a", "a", "abc = 34"); assertEquals("(= 34 abc)\n", found); } }