0001: /*
0002: [The "BSD licence"]
0003: Copyright (c) 2005-2006 Terence Parr
0004: All rights reserved.
0005:
0006: Redistribution and use in source and binary forms, with or without
0007: modification, are permitted provided that the following conditions
0008: are met:
0009: 1. Redistributions of source code must retain the above copyright
0010: notice, this list of conditions and the following disclaimer.
0011: 2. Redistributions in binary form must reproduce the above copyright
0012: notice, this list of conditions and the following disclaimer in the
0013: documentation and/or other materials provided with the distribution.
0014: 3. The name of the author may not be used to endorse or promote products
0015: derived from this software without specific prior written permission.
0016:
0017: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0018: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0019: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0020: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0021: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0022: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0023: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0024: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0025: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0026: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0027: */
0028: package org.antlr.test;
0029:
0030: import org.antlr.tool.ErrorManager;
0031: import org.antlr.tool.GrammarSemanticsMessage;
0032: import org.antlr.tool.Message;
0033: import org.antlr.tool.Grammar;
0034: import org.antlr.Tool;
0035: import org.antlr.codegen.CodeGenerator;
0036:
0037: public class TestRewriteAST extends BaseTest {
0038: protected boolean debug = false;
0039:
0040: public void testDelete() throws Exception {
0041: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0042: + "a : ID INT -> ;\n" + "ID : 'a'..'z'+ ;\n"
0043: + "INT : '0'..'9'+;\n"
0044: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0045: String found = execParser("T.g", grammar, "TParser", "TLexer",
0046: "a", "abc 34", debug);
0047: assertEquals("", found);
0048: }
0049:
0050: public void testSingleToken() throws Exception {
0051: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0052: + "a : ID -> ID;\n" + "ID : 'a'..'z'+ ;\n"
0053: + "INT : '0'..'9'+;\n"
0054: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0055: String found = execParser("T.g", grammar, "TParser", "TLexer",
0056: "a", "abc", debug);
0057: assertEquals("abc\n", found);
0058: }
0059:
0060: public void testSingleTokenToNewNode() throws Exception {
0061: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0062: + "a : ID -> ID[\"x\"];\n" + "ID : 'a'..'z'+ ;\n"
0063: + "INT : '0'..'9'+;\n"
0064: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0065: String found = execParser("T.g", grammar, "TParser", "TLexer",
0066: "a", "abc", debug);
0067: assertEquals("x\n", found);
0068: }
0069:
0070: public void testSingleTokenToNewNodeRoot() throws Exception {
0071: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0072: + "a : ID -> ^(ID[\"x\"] INT);\n"
0073: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0074: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0075: String found = execParser("T.g", grammar, "TParser", "TLexer",
0076: "a", "abc", debug);
0077: assertEquals("(x INT)\n", found);
0078: }
0079:
0080: public void testSingleTokenToNewNode2() throws Exception {
0081: // currently this Fails. Allow creation of new nodes w/o args.
0082: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0083: + "a : ID -> ID[ ];\n" + "ID : 'a'..'z'+ ;\n"
0084: + "INT : '0'..'9'+;\n"
0085: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0086: String found = execParser("T.g", grammar, "TParser", "TLexer",
0087: "a", "abc", debug);
0088: assertEquals("abc\n", found);
0089: }
0090:
0091: public void testSingleCharLiteral() throws Exception {
0092: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0093: + "a : 'c' -> 'c';\n" + "ID : 'a'..'z'+ ;\n"
0094: + "INT : '0'..'9'+;\n"
0095: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0096: String found = execParser("T.g", grammar, "TParser", "TLexer",
0097: "a", "c", debug);
0098: assertEquals("c\n", found);
0099: }
0100:
0101: public void testSingleStringLiteral() throws Exception {
0102: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0103: + "a : 'ick' -> 'ick';\n" + "ID : 'a'..'z'+ ;\n"
0104: + "INT : '0'..'9'+;\n"
0105: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0106: String found = execParser("T.g", grammar, "TParser", "TLexer",
0107: "a", "ick", debug);
0108: assertEquals("ick\n", found);
0109: }
0110:
0111: public void testSingleRule() throws Exception {
0112: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0113: + "a : b -> b;\n" + "b : ID ;\n" + "ID : 'a'..'z'+ ;\n"
0114: + "INT : '0'..'9'+;\n"
0115: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0116: String found = execParser("T.g", grammar, "TParser", "TLexer",
0117: "a", "abc", debug);
0118: assertEquals("abc\n", found);
0119: }
0120:
0121: public void testReorderTokens() throws Exception {
0122: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0123: + "a : ID INT -> INT ID;\n" + "ID : 'a'..'z'+ ;\n"
0124: + "INT : '0'..'9'+;\n"
0125: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0126: String found = execParser("T.g", grammar, "TParser", "TLexer",
0127: "a", "abc 34", debug);
0128: assertEquals("34 abc\n", found);
0129: }
0130:
0131: public void testReorderTokenAndRule() throws Exception {
0132: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0133: + "a : b INT -> INT b;\n" + "b : ID ;\n"
0134: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0135: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0136: String found = execParser("T.g", grammar, "TParser", "TLexer",
0137: "a", "abc 34", debug);
0138: assertEquals("34 abc\n", found);
0139: }
0140:
0141: public void testTokenTree() throws Exception {
0142: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0143: + "a : ID INT -> ^(INT ID);\n" + "ID : 'a'..'z'+ ;\n"
0144: + "INT : '0'..'9'+;\n"
0145: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0146: String found = execParser("T.g", grammar, "TParser", "TLexer",
0147: "a", "abc 34", debug);
0148: assertEquals("(34 abc)\n", found);
0149: }
0150:
0151: public void testTokenTreeAfterOtherStuff() throws Exception {
0152: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0153: + "a : 'void' ID INT -> 'void' ^(INT ID);\n"
0154: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0155: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0156: String found = execParser("T.g", grammar, "TParser", "TLexer",
0157: "a", "void abc 34", debug);
0158: assertEquals("void (34 abc)\n", found);
0159: }
0160:
0161: public void testNestedTokenTreeWithOuterLoop() throws Exception {
0162: // verify that ID and INT both iterate over outer index variable
0163: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0164: + "tokens {DUH;}\n"
0165: + "a : ID INT ID INT -> ^( DUH ID ^( DUH INT) )+ ;\n"
0166: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0167: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0168: String found = execParser("T.g", grammar, "TParser", "TLexer",
0169: "a", "a 1 b 2", debug);
0170: assertEquals("(DUH a (DUH 1)) (DUH b (DUH 2))\n", found);
0171: }
0172:
0173: public void testOptionalSingleToken() throws Exception {
0174: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0175: + "a : ID -> ID? ;\n" + "ID : 'a'..'z'+ ;\n"
0176: + "INT : '0'..'9'+;\n"
0177: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0178: String found = execParser("T.g", grammar, "TParser", "TLexer",
0179: "a", "abc", debug);
0180: assertEquals("abc\n", found);
0181: }
0182:
0183: public void testClosureSingleToken() throws Exception {
0184: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0185: + "a : ID ID -> ID* ;\n" + "ID : 'a'..'z'+ ;\n"
0186: + "INT : '0'..'9'+;\n"
0187: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0188: String found = execParser("T.g", grammar, "TParser", "TLexer",
0189: "a", "a b", debug);
0190: assertEquals("a b\n", found);
0191: }
0192:
0193: public void testPositiveClosureSingleToken() throws Exception {
0194: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0195: + "a : ID ID -> ID+ ;\n" + "ID : 'a'..'z'+ ;\n"
0196: + "INT : '0'..'9'+;\n"
0197: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0198: String found = execParser("T.g", grammar, "TParser", "TLexer",
0199: "a", "a b", debug);
0200: assertEquals("a b\n", found);
0201: }
0202:
0203: public void testOptionalSingleRule() throws Exception {
0204: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0205: + "a : b -> b?;\n" + "b : ID ;\n"
0206: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0207: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0208: String found = execParser("T.g", grammar, "TParser", "TLexer",
0209: "a", "abc", debug);
0210: assertEquals("abc\n", found);
0211: }
0212:
0213: public void testClosureSingleRule() throws Exception {
0214: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0215: + "a : b b -> b*;\n" + "b : ID ;\n"
0216: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0217: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0218: String found = execParser("T.g", grammar, "TParser", "TLexer",
0219: "a", "a b", debug);
0220: assertEquals("a b\n", found);
0221: }
0222:
0223: public void testClosureOfLabel() throws Exception {
0224: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0225: + "a : x+=b x+=b -> $x*;\n" + "b : ID ;\n"
0226: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0227: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0228: String found = execParser("T.g", grammar, "TParser", "TLexer",
0229: "a", "a b", debug);
0230: assertEquals("a b\n", found);
0231: }
0232:
0233: public void testOptionalLabelNoListLabel() throws Exception {
0234: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0235: + "a : (x=ID)? -> $x?;\n" + "ID : 'a'..'z'+ ;\n"
0236: + "INT : '0'..'9'+;\n"
0237: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0238: String found = execParser("T.g", grammar, "TParser", "TLexer",
0239: "a", "a", debug);
0240: assertEquals("a\n", found);
0241: }
0242:
0243: public void testPositiveClosureSingleRule() throws Exception {
0244: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0245: + "a : b b -> b+;\n" + "b : ID ;\n"
0246: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0247: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0248: String found = execParser("T.g", grammar, "TParser", "TLexer",
0249: "a", "a b", debug);
0250: assertEquals("a b\n", found);
0251: }
0252:
0253: public void testSinglePredicateT() throws Exception {
0254: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0255: + "a : ID -> {true}? ID -> ;\n" + "ID : 'a'..'z'+ ;\n"
0256: + "INT : '0'..'9'+;\n"
0257: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0258: String found = execParser("T.g", grammar, "TParser", "TLexer",
0259: "a", "abc", debug);
0260: assertEquals("abc\n", found);
0261: }
0262:
0263: public void testSinglePredicateF() throws Exception {
0264: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0265: + "a : ID -> {false}? ID -> ;\n" + "ID : 'a'..'z'+ ;\n"
0266: + "INT : '0'..'9'+;\n"
0267: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0268: String found = execParser("T.g", grammar, "TParser", "TLexer",
0269: "a", "abc", debug);
0270: assertEquals("", found);
0271: }
0272:
0273: public void testMultiplePredicate() throws Exception {
0274: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0275: + "a : ID INT -> {false}? ID\n"
0276: + " -> {true}? INT\n" + " -> \n"
0277: + " ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0278: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0279: String found = execParser("T.g", grammar, "TParser", "TLexer",
0280: "a", "a 2", debug);
0281: assertEquals("2\n", found);
0282: }
0283:
0284: public void testMultiplePredicateTrees() throws Exception {
0285: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0286: + "a : ID INT -> {false}? ^(ID INT)\n"
0287: + " -> {true}? ^(INT ID)\n"
0288: + " -> ID\n" + " ;\n" + "ID : 'a'..'z'+ ;\n"
0289: + "INT : '0'..'9'+;\n"
0290: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0291: String found = execParser("T.g", grammar, "TParser", "TLexer",
0292: "a", "a 2", debug);
0293: assertEquals("(2 a)\n", found);
0294: }
0295:
0296: public void testSimpleTree() throws Exception {
0297: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0298: + "a : op INT -> ^(op INT);\n" + "op : '+'|'-' ;\n"
0299: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0300: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0301: String found = execParser("T.g", grammar, "TParser", "TLexer",
0302: "a", "-34", debug);
0303: assertEquals("(- 34)\n", found);
0304: }
0305:
0306: public void testSimpleTree2() throws Exception {
0307: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0308: + "a : op INT -> ^(INT op);\n" + "op : '+'|'-' ;\n"
0309: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0310: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0311: String found = execParser("T.g", grammar, "TParser", "TLexer",
0312: "a", "+ 34", debug);
0313: assertEquals("(34 +)\n", found);
0314: }
0315:
0316: public void testNestedTrees() throws Exception {
0317: String grammar = "grammar T;\n"
0318: + "options {output=AST;}\n"
0319: + "a : 'var' (ID ':' type ';')+ -> ^('var' ^(':' ID type)+) ;\n"
0320: + "type : 'int' | 'float' ;\n" + "ID : 'a'..'z'+ ;\n"
0321: + "INT : '0'..'9'+;\n"
0322: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0323: String found = execParser("T.g", grammar, "TParser", "TLexer",
0324: "a", "var a:int; b:float;", debug);
0325: assertEquals("(var (: a int) (: b float))\n", found);
0326: }
0327:
0328: public void testImaginaryTokenCopy() throws Exception {
0329: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0330: + "tokens {VAR;}\n"
0331: + "a : ID (',' ID)*-> ^(VAR ID)+ ;\n"
0332: + "type : 'int' | 'float' ;\n" + "ID : 'a'..'z'+ ;\n"
0333: + "INT : '0'..'9'+;\n"
0334: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0335: String found = execParser("T.g", grammar, "TParser", "TLexer",
0336: "a", "a,b,c", debug);
0337: assertEquals("(VAR a) (VAR b) (VAR c)\n", found);
0338: }
0339:
0340: public void testTokenUnreferencedOnLeftButDefined()
0341: throws Exception {
0342: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0343: + "tokens {VAR;}\n" + "a : b -> ID ;\n" + "b : ID ;\n"
0344: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0345: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0346: String found = execParser("T.g", grammar, "TParser", "TLexer",
0347: "a", "a", debug);
0348: assertEquals("ID\n", found);
0349: }
0350:
0351: public void testImaginaryTokenCopySetText() throws Exception {
0352: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0353: + "tokens {VAR;}\n"
0354: + "a : ID (',' ID)*-> ^(VAR[\"var\"] ID)+ ;\n"
0355: + "type : 'int' | 'float' ;\n" + "ID : 'a'..'z'+ ;\n"
0356: + "INT : '0'..'9'+;\n"
0357: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0358: String found = execParser("T.g", grammar, "TParser", "TLexer",
0359: "a", "a,b,c", debug);
0360: assertEquals("(var a) (var b) (var c)\n", found);
0361: }
0362:
0363: public void testImaginaryTokenNoCopyFromToken() throws Exception {
0364: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0365: + "tokens {BLOCK;}\n"
0366: + "a : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ;\n"
0367: + "type : 'int' | 'float' ;\n" + "ID : 'a'..'z'+ ;\n"
0368: + "INT : '0'..'9'+;\n"
0369: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0370: String found = execParser("T.g", grammar, "TParser", "TLexer",
0371: "a", "{a b c}", debug);
0372: assertEquals("({ a b c)\n", found);
0373: }
0374:
0375: public void testImaginaryTokenNoCopyFromTokenSetText()
0376: throws Exception {
0377: String grammar = "grammar T;\n"
0378: + "options {output=AST;}\n"
0379: + "tokens {BLOCK;}\n"
0380: + "a : lc='{' ID+ '}' -> ^(BLOCK[$lc,\"block\"] ID+) ;\n"
0381: + "type : 'int' | 'float' ;\n" + "ID : 'a'..'z'+ ;\n"
0382: + "INT : '0'..'9'+;\n"
0383: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0384: String found = execParser("T.g", grammar, "TParser", "TLexer",
0385: "a", "{a b c}", debug);
0386: assertEquals("(block a b c)\n", found);
0387: }
0388:
0389: public void testMixedRewriteAndAutoAST() throws Exception {
0390: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0391: + "tokens {BLOCK;}\n"
0392: + "a : b b^ ;\n"
0393: + // 2nd b matches only an INT; can make it root
0394: "b : ID INT -> INT ID\n" + " | INT\n" + " ;\n"
0395: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0396: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0397: String found = execParser("T.g", grammar, "TParser", "TLexer",
0398: "a", "a 1 2", debug);
0399: assertEquals("(2 1 a)\n", found);
0400: }
0401:
0402: public void testSubruleWithRewrite() throws Exception {
0403: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0404: + "tokens {BLOCK;}\n" + "a : b b ;\n"
0405: + "b : (ID INT -> INT ID | INT INT -> INT+ )\n"
0406: + " ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0407: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0408: String found = execParser("T.g", grammar, "TParser", "TLexer",
0409: "a", "a 1 2 3", debug);
0410: assertEquals("1 a 2 3\n", found);
0411: }
0412:
0413: public void testSubruleWithRewrite2() throws Exception {
0414: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0415: + "tokens {TYPE;}\n" + "a : b b ;\n" + "b : 'int'\n"
0416: + " ( ID -> ^(TYPE 'int' ID)\n"
0417: + " | ID '=' INT -> ^(TYPE 'int' ID INT)\n"
0418: + " )\n" + " ';'\n" + " ;\n"
0419: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0420: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0421: String found = execParser("T.g", grammar, "TParser", "TLexer",
0422: "a", "int a; int b=3;", debug);
0423: assertEquals("(TYPE int a) (TYPE int b 3)\n", found);
0424: }
0425:
0426: public void testNestedRewriteShutsOffAutoAST() throws Exception {
0427: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0428: + "tokens {BLOCK;}\n" + "a : b b ;\n"
0429: + "b : ID ( ID (last=ID -> $last)+ ) ';'\n"
0430: + // get last ID
0431: " | INT\n"
0432: + // should still get auto AST construction
0433: " ;\n" + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0434: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0435: String found = execParser("T.g", grammar, "TParser", "TLexer",
0436: "a", "a b c d; 42", debug);
0437: assertEquals("d 42\n", found);
0438: }
0439:
0440: public void testRewriteActions() throws Exception {
0441: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0442: + "a : atom -> ^({adaptor.create(INT,\"9\")} atom) ;\n"
0443: + "atom : INT ;\n" + "ID : 'a'..'z'+ ;\n"
0444: + "INT : '0'..'9'+;\n"
0445: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0446: String found = execParser("T.g", grammar, "TParser", "TLexer",
0447: "a", "3", debug);
0448: assertEquals("(9 3)\n", found);
0449: }
0450:
0451: public void testRewriteActions2() throws Exception {
0452: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0453: + "a : atom -> {adaptor.create(INT,\"9\")} atom ;\n"
0454: + "atom : INT ;\n" + "ID : 'a'..'z'+ ;\n"
0455: + "INT : '0'..'9'+;\n"
0456: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0457: String found = execParser("T.g", grammar, "TParser", "TLexer",
0458: "a", "3", debug);
0459: assertEquals("9 3\n", found);
0460: }
0461:
0462: public void testRefToOldValue() throws Exception {
0463: String grammar = "grammar T;\n"
0464: + "options {output=AST;}\n"
0465: + "tokens {BLOCK;}\n"
0466: + "a : (atom -> atom) (op='+' r=atom -> ^($op $a $r) )* ;\n"
0467: + "atom : INT ;\n" + "ID : 'a'..'z'+ ;\n"
0468: + "INT : '0'..'9'+;\n"
0469: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0470: String found = execParser("T.g", grammar, "TParser", "TLexer",
0471: "a", "3+4+5", debug);
0472: assertEquals("(+ (+ 3 4) 5)\n", found);
0473: }
0474:
0475: public void testCopySemanticsForRules() throws Exception {
0476: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0477: + "tokens {BLOCK;}\n"
0478: + "a : atom -> ^(atom atom) ;\n"
0479: + // NOT CYCLE! (dup atom)
0480: "atom : INT ;\n" + "ID : 'a'..'z'+ ;\n"
0481: + "INT : '0'..'9'+;\n"
0482: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0483: String found = execParser("T.g", grammar, "TParser", "TLexer",
0484: "a", "3", debug);
0485: assertEquals("(3 3)\n", found);
0486: }
0487:
0488: public void testCopySemanticsForRules2() throws Exception {
0489: // copy type as a root for each invocation of (...)+ in rewrite
0490: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0491: + "a : type ID (',' ID)* ';' -> ^(type ID)+ ;\n"
0492: + "type : 'int' ;\n" + "ID : 'a'..'z'+ ;\n"
0493: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0494: String found = execParser("T.g", grammar, "TParser", "TLexer",
0495: "a", "int a,b,c;", debug);
0496: assertEquals("(int a) (int b) (int c)\n", found);
0497: }
0498:
0499: public void testCopySemanticsForRules3() throws Exception {
0500: // copy type *and* modifier even though it's optional
0501: // for each invocation of (...)+ in rewrite
0502: String grammar = "grammar T;\n"
0503: + "options {output=AST;}\n"
0504: + "a : modifier? type ID (',' ID)* ';' -> ^(type modifier? ID)+ ;\n"
0505: + "type : 'int' ;\n" + "modifier : 'public' ;\n"
0506: + "ID : 'a'..'z'+ ;\n"
0507: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0508: String found = execParser("T.g", grammar, "TParser", "TLexer",
0509: "a", "public int a,b,c;", debug);
0510: assertEquals("(int public a) (int public b) (int public c)\n",
0511: found);
0512: }
0513:
0514: public void testCopySemanticsForRules3Double() throws Exception {
0515: // copy type *and* modifier even though it's optional
0516: // for each invocation of (...)+ in rewrite
0517: String grammar = "grammar T;\n"
0518: + "options {output=AST;}\n"
0519: + "a : modifier? type ID (',' ID)* ';' -> ^(type modifier? ID)+ ^(type modifier? ID)+ ;\n"
0520: + "type : 'int' ;\n" + "modifier : 'public' ;\n"
0521: + "ID : 'a'..'z'+ ;\n"
0522: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0523: String found = execParser("T.g", grammar, "TParser", "TLexer",
0524: "a", "public int a,b,c;", debug);
0525: assertEquals(
0526: "(int public a) (int public b) (int public c) (int public a) (int public b) (int public c)\n",
0527: found);
0528: }
0529:
0530: public void testCopySemanticsForRules4() throws Exception {
0531: // copy type *and* modifier even though it's optional
0532: // for each invocation of (...)+ in rewrite
0533: String grammar = "grammar T;\n"
0534: + "options {output=AST;}\n"
0535: + "tokens {MOD;}\n"
0536: + "a : modifier? type ID (',' ID)* ';' -> ^(type ^(MOD modifier)? ID)+ ;\n"
0537: + "type : 'int' ;\n" + "modifier : 'public' ;\n"
0538: + "ID : 'a'..'z'+ ;\n"
0539: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0540: String found = execParser("T.g", grammar, "TParser", "TLexer",
0541: "a", "public int a,b,c;", debug);
0542: assertEquals(
0543: "(int (MOD public) a) (int (MOD public) b) (int (MOD public) c)\n",
0544: found);
0545: }
0546:
0547: public void testCopySemanticsLists() throws Exception {
0548: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0549: + "tokens {MOD;}\n"
0550: + "a : ID (',' ID)* ';' -> ID+ ID+ ;\n"
0551: + "ID : 'a'..'z'+ ;\n"
0552: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0553: String found = execParser("T.g", grammar, "TParser", "TLexer",
0554: "a", "a,b,c;", debug);
0555: assertEquals("a b c a b c\n", found);
0556: }
0557:
0558: public void testCopyRuleLabel() throws Exception {
0559: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0560: + "tokens {BLOCK;}\n" + "a : x=b -> $x $x;\n"
0561: + "b : ID ;\n" + "ID : 'a'..'z'+ ;\n"
0562: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0563: String found = execParser("T.g", grammar, "TParser", "TLexer",
0564: "a", "a", debug);
0565: assertEquals("a a\n", found);
0566: }
0567:
0568: public void testCopyRuleLabel2() throws Exception {
0569: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0570: + "tokens {BLOCK;}\n" + "a : x=b -> ^($x $x);\n"
0571: + "b : ID ;\n" + "ID : 'a'..'z'+ ;\n"
0572: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0573: String found = execParser("T.g", grammar, "TParser", "TLexer",
0574: "a", "a", debug);
0575: assertEquals("(a a)\n", found);
0576: }
0577:
0578: public void testQueueingOfTokens() throws Exception {
0579: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0580: + "a : 'int' ID (',' ID)* ';' -> ^('int' ID+) ;\n"
0581: + "op : '+'|'-' ;\n" + "ID : 'a'..'z'+ ;\n"
0582: + "INT : '0'..'9'+;\n"
0583: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0584: String found = execParser("T.g", grammar, "TParser", "TLexer",
0585: "a", "int a,b,c;", debug);
0586: assertEquals("(int a b c)\n", found);
0587: }
0588:
0589: public void testCopyOfTokens() throws Exception {
0590: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0591: + "a : 'int' ID ';' -> 'int' ID 'int' ID ;\n"
0592: + "op : '+'|'-' ;\n" + "ID : 'a'..'z'+ ;\n"
0593: + "INT : '0'..'9'+;\n"
0594: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0595: String found = execParser("T.g", grammar, "TParser", "TLexer",
0596: "a", "int a;", debug);
0597: assertEquals("int a int a\n", found);
0598: }
0599:
0600: public void testTokenCopyInLoop() throws Exception {
0601: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0602: + "a : 'int' ID (',' ID)* ';' -> ^('int' ID)+ ;\n"
0603: + "op : '+'|'-' ;\n" + "ID : 'a'..'z'+ ;\n"
0604: + "INT : '0'..'9'+;\n"
0605: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0606: String found = execParser("T.g", grammar, "TParser", "TLexer",
0607: "a", "int a,b,c;", debug);
0608: assertEquals("(int a) (int b) (int c)\n", found);
0609: }
0610:
0611: public void testTokenCopyInLoopAgainstTwoOthers() throws Exception {
0612: // must smear 'int' copies across as root of multiple trees
0613: String grammar = "grammar T;\n"
0614: + "options {output=AST;}\n"
0615: + "a : 'int' ID ':' INT (',' ID ':' INT)* ';' -> ^('int' ID INT)+ ;\n"
0616: + "op : '+'|'-' ;\n" + "ID : 'a'..'z'+ ;\n"
0617: + "INT : '0'..'9'+;\n"
0618: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0619: String found = execParser("T.g", grammar, "TParser", "TLexer",
0620: "a", "int a:1,b:2,c:3;", debug);
0621: assertEquals("(int a 1) (int b 2) (int c 3)\n", found);
0622: }
0623:
0624: public void testListRefdOneAtATime() throws Exception {
0625: String grammar = "grammar T;\n"
0626: + "options {output=AST;}\n"
0627: + "a : ID+ -> ID ID ID ;\n"
0628: + // works if 3 input IDs
0629: "op : '+'|'-' ;\n" + "ID : 'a'..'z'+ ;\n"
0630: + "INT : '0'..'9'+;\n"
0631: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0632: String found = execParser("T.g", grammar, "TParser", "TLexer",
0633: "a", "a b c", debug);
0634: assertEquals("a b c\n", found);
0635: }
0636:
0637: public void testSplitListWithLabels() throws Exception {
0638: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0639: + "tokens {VAR;}\n"
0640: + "a : first=ID others+=ID* -> $first VAR $others+ ;\n"
0641: + "op : '+'|'-' ;\n" + "ID : 'a'..'z'+ ;\n"
0642: + "INT : '0'..'9'+;\n"
0643: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0644: String found = execParser("T.g", grammar, "TParser", "TLexer",
0645: "a", "a b c", debug);
0646: assertEquals("a VAR b c\n", found);
0647: }
0648:
0649: public void testComplicatedMelange() throws Exception {
0650: String grammar = "grammar T;\n"
0651: + "options {output=AST;}\n"
0652: + "tokens {BLOCK;}\n"
0653: + "a : A A b=B B b=B c+=C C c+=C D {$D.text;} -> A+ B+ C+ D ;\n"
0654: + "type : 'int' | 'float' ;\n" + "A : 'a' ;\n"
0655: + "B : 'b' ;\n" + "C : 'c' ;\n" + "D : 'd' ;\n"
0656: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0657: String found = execParser("T.g", grammar, "TParser", "TLexer",
0658: "a", "a a b b b c c c d", debug);
0659: assertEquals("a a b b b c c c d\n", found);
0660: }
0661:
0662: public void testRuleLabel() throws Exception {
0663: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0664: + "tokens {BLOCK;}\n" + "a : x=b -> $x;\n"
0665: + "b : ID ;\n" + "ID : 'a'..'z'+ ;\n"
0666: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0667: String found = execParser("T.g", grammar, "TParser", "TLexer",
0668: "a", "a", debug);
0669: assertEquals("a\n", found);
0670: }
0671:
0672: public void testRuleListLabel() throws Exception {
0673: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0674: + "tokens {BLOCK;}\n" + "a : x+=b x+=b -> $x+;\n"
0675: + "b : ID ;\n" + "ID : 'a'..'z'+ ;\n"
0676: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0677: String found = execParser("T.g", grammar, "TParser", "TLexer",
0678: "a", "a b", debug);
0679: assertEquals("a b\n", found);
0680: }
0681:
0682: public void testRuleListLabel2() throws Exception {
0683: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0684: + "tokens {BLOCK;}\n" + "a : x+=b x+=b -> $x $x*;\n"
0685: + "b : ID ;\n" + "ID : 'a'..'z'+ ;\n"
0686: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0687: String found = execParser("T.g", grammar, "TParser", "TLexer",
0688: "a", "a b", debug);
0689: assertEquals("a b\n", found);
0690: }
0691:
0692: public void testOptional() throws Exception {
0693: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0694: + "tokens {BLOCK;}\n" + "a : x=b (y=b)? -> $x $y?;\n"
0695: + "b : ID ;\n" + "ID : 'a'..'z'+ ;\n"
0696: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0697: String found = execParser("T.g", grammar, "TParser", "TLexer",
0698: "a", "a", debug);
0699: assertEquals("a\n", found);
0700: }
0701:
0702: public void testOptional2() throws Exception {
0703: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0704: + "tokens {BLOCK;}\n" + "a : x=ID (y=b)? -> $x $y?;\n"
0705: + "b : ID ;\n" + "ID : 'a'..'z'+ ;\n"
0706: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0707: String found = execParser("T.g", grammar, "TParser", "TLexer",
0708: "a", "a b", debug);
0709: assertEquals("a b\n", found);
0710: }
0711:
0712: public void testOptional3() throws Exception {
0713: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0714: + "tokens {BLOCK;}\n"
0715: + "a : x=ID (y=b)? -> ($x $y)?;\n" + "b : ID ;\n"
0716: + "ID : 'a'..'z'+ ;\n"
0717: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0718: String found = execParser("T.g", grammar, "TParser", "TLexer",
0719: "a", "a b", debug);
0720: assertEquals("a b\n", found);
0721: }
0722:
0723: public void testOptional4() throws Exception {
0724: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0725: + "tokens {BLOCK;}\n"
0726: + "a : x+=ID (y=b)? -> ($x $y)?;\n" + "b : ID ;\n"
0727: + "ID : 'a'..'z'+ ;\n"
0728: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0729: String found = execParser("T.g", grammar, "TParser", "TLexer",
0730: "a", "a b", debug);
0731: assertEquals("a b\n", found);
0732: }
0733:
0734: public void testOptional5() throws Exception {
0735: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0736: + "tokens {BLOCK;}\n" + "a : ID -> ID? ;\n"
0737: + // match an ID to optional ID
0738: "b : ID ;\n" + "ID : 'a'..'z'+ ;\n"
0739: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0740: String found = execParser("T.g", grammar, "TParser", "TLexer",
0741: "a", "a", debug);
0742: assertEquals("a\n", found);
0743: }
0744:
0745: public void testArbitraryExprType() throws Exception {
0746: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0747: + "tokens {BLOCK;}\n"
0748: + "a : x+=b x+=b -> {new CommonTree()};\n"
0749: + "b : ID ;\n" + "ID : 'a'..'z'+ ;\n"
0750: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0751: String found = execParser("T.g", grammar, "TParser", "TLexer",
0752: "a", "a b", debug);
0753: //assertEquals("[not sure what this should be!]\n", found);
0754: //ATTENTION: I changed this one's behavior from the above. Is it right?
0755: assertEquals("nil\n", found);
0756: }
0757:
0758: public void testSet() throws Exception {
0759: String grammar = "grammar T;\n"
0760: + "options { output = AST; } \n"
0761: + "a: (INT|ID)+ -> INT+ ID+ ;\n" + "INT: '0'..'9'+;\n"
0762: + "ID : 'a'..'z'+;\n"
0763: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0764: String found = execParser("T.g", grammar, "TParser", "TLexer",
0765: "a", "2 a 34 de", debug);
0766: assertEquals("2 34 a de\n", found);
0767: }
0768:
0769: public void testRewriteAction() throws Exception {
0770: String grammar = "grammar T; \n"
0771: + "options { output = AST; }\n"
0772: + "tokens { FLOAT; }\n"
0773: + "r\n"
0774: + " : INT -> {new CommonTree(new CommonToken(FLOAT,$INT.text+\".0\"))} \n"
0775: + " ; \n" + "INT : '0'..'9'+; \n"
0776: + "WS: (' ' | '\\n' | '\\t')+ {$channel = HIDDEN;}; \n";
0777: String found = execParser("T.g", grammar, "TParser", "TLexer",
0778: "r", "25", debug);
0779: assertEquals("25.0\n", found);
0780: }
0781:
0782: public void testOptionalSubruleWithoutRealElements()
0783: throws Exception {
0784: // copy type *and* modifier even though it's optional
0785: // for each invocation of (...)+ in rewrite
0786: String grammar = "grammar T;\n"
0787: + "options {output=AST;} \n"
0788: + "tokens {PARMS;} \n"
0789: + "\n"
0790: + "modulo \n"
0791: + " : 'modulo' ID ('(' parms+ ')')? -> ^('modulo' ID ^(PARMS parms+)?) \n"
0792: + " ; \n" + "parms : '#'|ID; \n"
0793: + "ID : ('a'..'z' | 'A'..'Z')+;\n"
0794: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0795: String found = execParser("T.g", grammar, "TParser", "TLexer",
0796: "modulo", "modulo abc (x y #)", debug);
0797: assertEquals("(modulo abc (PARMS x y #))\n", found);
0798: }
0799:
0800: // C A R D I N A L I T Y I S S U E S
0801:
0802: public void testCardinality() throws Exception {
0803: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0804: + "tokens {BLOCK;}\n"
0805: + "a : ID ID INT INT INT -> (ID INT)+;\n"
0806: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+; \n"
0807: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0808: execParser("T.g", grammar, "TParser", "TLexer", "a",
0809: "a b 3 4 5", debug);
0810: String expecting = "org.antlr.runtime.tree.RewriteCardinalityException: token ID";
0811: String found = getFirstLineOfException();
0812: assertEquals(expecting, found);
0813: }
0814:
0815: public void testCardinality2() throws Exception {
0816: String grammar = "grammar T;\n"
0817: + "options {output=AST;}\n"
0818: + "a : ID+ -> ID ID ID ;\n"
0819: + // only 2 input IDs
0820: "op : '+'|'-' ;\n" + "ID : 'a'..'z'+ ;\n"
0821: + "INT : '0'..'9'+;\n"
0822: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0823: execParser("T.g", grammar, "TParser", "TLexer", "a", "a b",
0824: debug);
0825: String expecting = "org.antlr.runtime.tree.RewriteCardinalityException: token ID";
0826: String found = getFirstLineOfException();
0827: assertEquals(expecting, found);
0828: }
0829:
0830: public void testCardinality3() throws Exception {
0831: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0832: + "a : ID? INT -> ID INT ;\n" + "op : '+'|'-' ;\n"
0833: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0834: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0835: execParser("T.g", grammar, "TParser", "TLexer", "a", "3", debug);
0836: String expecting = "org.antlr.runtime.tree.RewriteEmptyStreamException: token ID";
0837: String found = getFirstLineOfException();
0838: assertEquals(expecting, found);
0839: }
0840:
0841: public void testLoopCardinality() throws Exception {
0842: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0843: + "a : ID? INT -> ID+ INT ;\n" + "op : '+'|'-' ;\n"
0844: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0845: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0846: execParser("T.g", grammar, "TParser", "TLexer", "a", "3", debug);
0847: String expecting = "org.antlr.runtime.tree.RewriteEarlyExitException";
0848: String found = getFirstLineOfException();
0849: assertEquals(expecting, found);
0850: }
0851:
0852: // E R R O R S
0853:
0854: public void testUnknownRule() throws Exception {
0855: ErrorQueue equeue = new ErrorQueue();
0856: ErrorManager.setErrorListener(equeue);
0857:
0858: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0859: + "a : INT -> ugh ;\n" + "ID : 'a'..'z'+ ;\n"
0860: + "INT : '0'..'9'+;\n"
0861: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0862:
0863: Grammar g = new Grammar(grammar);
0864: Tool antlr = newTool();
0865: antlr.setOutputDirectory(null); // write to /dev/null
0866: CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
0867: g.setCodeGenerator(generator);
0868: generator.genRecognizer();
0869:
0870: int expectedMsgID = ErrorManager.MSG_UNDEFINED_RULE_REF;
0871: Object expectedArg = "ugh";
0872: Object expectedArg2 = null;
0873: GrammarSemanticsMessage expectedMessage = new GrammarSemanticsMessage(
0874: expectedMsgID, g, null, expectedArg, expectedArg2);
0875:
0876: checkError(equeue, expectedMessage);
0877: }
0878:
0879: public void testKnownRuleButNotInLHS() throws Exception {
0880: ErrorQueue equeue = new ErrorQueue();
0881: ErrorManager.setErrorListener(equeue);
0882:
0883: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0884: + "a : INT -> b ;\n" + "b : 'b' ;\n"
0885: + "ID : 'a'..'z'+ ;\n" + "INT : '0'..'9'+;\n"
0886: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0887:
0888: Grammar g = new Grammar(grammar);
0889: Tool antlr = newTool();
0890: antlr.setOutputDirectory(null); // write to /dev/null
0891: CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
0892: g.setCodeGenerator(generator);
0893: generator.genRecognizer();
0894:
0895: int expectedMsgID = ErrorManager.MSG_REWRITE_ELEMENT_NOT_PRESENT_ON_LHS;
0896: Object expectedArg = "b";
0897: Object expectedArg2 = null;
0898: GrammarSemanticsMessage expectedMessage = new GrammarSemanticsMessage(
0899: expectedMsgID, g, null, expectedArg, expectedArg2);
0900:
0901: checkError(equeue, expectedMessage);
0902: }
0903:
0904: public void testUnknownToken() throws Exception {
0905: ErrorQueue equeue = new ErrorQueue();
0906: ErrorManager.setErrorListener(equeue);
0907:
0908: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0909: + "a : INT -> ICK ;\n" + "ID : 'a'..'z'+ ;\n"
0910: + "INT : '0'..'9'+;\n"
0911: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0912:
0913: Grammar g = new Grammar(grammar);
0914: Tool antlr = newTool();
0915: antlr.setOutputDirectory(null); // write to /dev/null
0916: CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
0917: g.setCodeGenerator(generator);
0918: generator.genRecognizer();
0919:
0920: int expectedMsgID = ErrorManager.MSG_UNDEFINED_TOKEN_REF_IN_REWRITE;
0921: Object expectedArg = "ICK";
0922: Object expectedArg2 = null;
0923: GrammarSemanticsMessage expectedMessage = new GrammarSemanticsMessage(
0924: expectedMsgID, g, null, expectedArg, expectedArg2);
0925:
0926: checkError(equeue, expectedMessage);
0927: }
0928:
0929: public void testUnknownLabel() throws Exception {
0930: ErrorQueue equeue = new ErrorQueue();
0931: ErrorManager.setErrorListener(equeue);
0932:
0933: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0934: + "a : INT -> $foo ;\n" + "ID : 'a'..'z'+ ;\n"
0935: + "INT : '0'..'9'+;\n"
0936: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0937:
0938: Grammar g = new Grammar(grammar);
0939: Tool antlr = newTool();
0940: antlr.setOutputDirectory(null); // write to /dev/null
0941: CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
0942: g.setCodeGenerator(generator);
0943: generator.genRecognizer();
0944:
0945: int expectedMsgID = ErrorManager.MSG_UNDEFINED_LABEL_REF_IN_REWRITE;
0946: Object expectedArg = "foo";
0947: Object expectedArg2 = null;
0948: GrammarSemanticsMessage expectedMessage = new GrammarSemanticsMessage(
0949: expectedMsgID, g, null, expectedArg, expectedArg2);
0950:
0951: checkError(equeue, expectedMessage);
0952: }
0953:
0954: public void testUnknownCharLiteralToken() throws Exception {
0955: ErrorQueue equeue = new ErrorQueue();
0956: ErrorManager.setErrorListener(equeue);
0957:
0958: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0959: + "a : INT -> 'a' ;\n" + "ID : 'a'..'z'+ ;\n"
0960: + "INT : '0'..'9'+;\n"
0961: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0962:
0963: Grammar g = new Grammar(grammar);
0964: Tool antlr = newTool();
0965: antlr.setOutputDirectory(null); // write to /dev/null
0966: CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
0967: g.setCodeGenerator(generator);
0968: generator.genRecognizer();
0969:
0970: int expectedMsgID = ErrorManager.MSG_UNDEFINED_TOKEN_REF_IN_REWRITE;
0971: Object expectedArg = "'a'";
0972: Object expectedArg2 = null;
0973: GrammarSemanticsMessage expectedMessage = new GrammarSemanticsMessage(
0974: expectedMsgID, g, null, expectedArg, expectedArg2);
0975:
0976: checkError(equeue, expectedMessage);
0977: }
0978:
0979: public void testUnknownStringLiteralToken() throws Exception {
0980: ErrorQueue equeue = new ErrorQueue();
0981: ErrorManager.setErrorListener(equeue);
0982:
0983: String grammar = "grammar T;\n" + "options {output=AST;}\n"
0984: + "a : INT -> 'foo' ;\n" + "ID : 'a'..'z'+ ;\n"
0985: + "INT : '0'..'9'+;\n"
0986: + "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
0987:
0988: Grammar g = new Grammar(grammar);
0989: Tool antlr = newTool();
0990: antlr.setOutputDirectory(null); // write to /dev/null
0991: CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
0992: g.setCodeGenerator(generator);
0993: generator.genRecognizer();
0994:
0995: int expectedMsgID = ErrorManager.MSG_UNDEFINED_TOKEN_REF_IN_REWRITE;
0996: Object expectedArg = "'foo'";
0997: Object expectedArg2 = null;
0998: GrammarSemanticsMessage expectedMessage = new GrammarSemanticsMessage(
0999: expectedMsgID, g, null, expectedArg, expectedArg2);
1000:
1001: checkError(equeue, expectedMessage);
1002: }
1003:
1004: // S U P P O R T
1005:
1006: protected void checkError(ErrorQueue equeue,
1007: GrammarSemanticsMessage expectedMessage) throws Exception {
1008: //System.out.println("errors="+equeue);
1009: Message foundMsg = null;
1010: for (int i = 0; i < equeue.errors.size(); i++) {
1011: Message m = (Message) equeue.errors.get(i);
1012: if (m.msgID == expectedMessage.msgID) {
1013: foundMsg = m;
1014: }
1015: }
1016: assertTrue("no error; " + expectedMessage.msgID + " expected",
1017: equeue.errors.size() > 0);
1018: assertTrue("too many errors; " + equeue.errors, equeue.errors
1019: .size() <= 1);
1020: assertNotNull("couldn't find expected error: "
1021: + expectedMessage.msgID, foundMsg);
1022: assertTrue("error is not a GrammarSemanticsMessage",
1023: foundMsg instanceof GrammarSemanticsMessage);
1024: assertEquals(expectedMessage.arg, foundMsg.arg);
1025: assertEquals(expectedMessage.arg2, foundMsg.arg2);
1026: ErrorManager.resetErrorState(); // wack errors for next test
1027: }
1028:
1029: }
|