001: /*
002: [The "BSD licence"]
003: Copyright (c) 2005-2006 Terence Parr
004: All rights reserved.
005:
006: Redistribution and use in source and binary forms, with or without
007: modification, are permitted provided that the following conditions
008: are met:
009: 1. Redistributions of source code must retain the above copyright
010: notice, this list of conditions and the following disclaimer.
011: 2. Redistributions in binary form must reproduce the above copyright
012: notice, this list of conditions and the following disclaimer in the
013: documentation and/or other materials provided with the distribution.
014: 3. The name of the author may not be used to endorse or promote products
015: derived from this software without specific prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
018: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
019: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
020: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
021: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
022: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
023: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
024: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
026: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: */
028: package org.antlr.test;
029:
030: public class TestSemanticPredicateEvaluation extends BaseTest {
031: public void testSimpleCyclicDFAWithPredicate() throws Exception {
032: String grammar = "grammar foo;\n"
033: + "a : {false}? 'x'* 'y' {System.out.println(\"alt1\");}\n"
034: + " | {true}? 'x'* 'y' {System.out.println(\"alt2\");}\n"
035: + " ;\n";
036: String found = execParser("foo.g", grammar, "fooParser",
037: "fooLexer", "a", "xxxy", false);
038: assertEquals("alt2\n", found);
039: }
040:
041: public void testSimpleCyclicDFAWithInstanceVarPredicate()
042: throws Exception {
043: String grammar = "grammar foo;\n"
044: + "@members {boolean v=true;}\n"
045: + "a : {false}? 'x'* 'y' {System.out.println(\"alt1\");}\n"
046: + " | {v}? 'x'* 'y' {System.out.println(\"alt2\");}\n"
047: + " ;\n";
048: String found = execParser("foo.g", grammar, "fooParser",
049: "fooLexer", "a", "xxxy", false);
050: assertEquals("alt2\n", found);
051: }
052:
053: public void testPredicateValidation() throws Exception {
054: String grammar = "grammar foo;\n" + "@members {\n"
055: + "public void reportError(RecognitionException e) {\n"
056: + " System.out.println(\"error: \"+e.toString());\n"
057: + "}\n" + "}\n" + "\n" + "a : {false}? 'x'\n" + " ;\n";
058: String found = execParser("foo.g", grammar, "fooParser",
059: "fooLexer", "a", "x", false);
060: assertEquals("error: FailedPredicateException(a,{false}?)\n",
061: found);
062: }
063:
064: public void testLexerPreds() throws Exception {
065: String grammar = "grammar foo;"
066: + "@lexer::members {boolean p=false;}\n"
067: + "a : (A|B)+ ;\n"
068: + "A : {p}? 'a' {System.out.println(\"token 1\");} ;\n"
069: + "B : {!p}? 'a' {System.out.println(\"token 2\");} ;\n";
070: String found = execParser("foo.g", grammar, "fooParser",
071: "fooLexer", "a", "a", false);
072: // "a" is ambig; can match both A, B. Pred says match 2
073: assertEquals("token 2\n", found);
074: }
075:
076: public void testLexerPreds2() throws Exception {
077: String grammar = "grammar foo;"
078: + "@lexer::members {boolean p=true;}\n"
079: + "a : (A|B)+ ;\n"
080: + "A : {p}? 'a' {System.out.println(\"token 1\");} ;\n"
081: + "B : ('a'|'b')+ {System.out.println(\"token 2\");} ;\n";
082: String found = execParser("foo.g", grammar, "fooParser",
083: "fooLexer", "a", "a", false);
084: // "a" is ambig; can match both A, B. Pred says match 1
085: assertEquals("token 1\n", found);
086: }
087:
088: public void testLexerPredInExitBranch() throws Exception {
089: // p says it's ok to exit; it has precendence over the !p loopback branch
090: String grammar = "grammar foo;"
091: + "@lexer::members {boolean p=true;}\n"
092: + "a : (A|B)+ ;\n"
093: + "A : ('a' {System.out.print(\"1\");})*\n"
094: + " {p}?\n"
095: + " ('a' {System.out.print(\"2\");})* ;\n";
096: String found = execParser("foo.g", grammar, "fooParser",
097: "fooLexer", "a", "aaa", false);
098: assertEquals("222\n", found);
099: }
100:
101: public void testLexerPredInExitBranch2() throws Exception {
102: String grammar = "grammar foo;"
103: + "@lexer::members {boolean p=true;}\n"
104: + "a : (A|B)+ ;\n"
105: + "A : ({p}? 'a' {System.out.print(\"1\");})*\n"
106: + " ('a' {System.out.print(\"2\");})* ;\n";
107: String found = execParser("foo.g", grammar, "fooParser",
108: "fooLexer", "a", "aaa", false);
109: assertEquals("111\n", found);
110: }
111:
112: public void testLexerPredInExitBranch3() throws Exception {
113: String grammar = "grammar foo;"
114: + "@lexer::members {boolean p=true;}\n"
115: + "a : (A|B)+ ;\n"
116: + "A : ({p}? 'a' {System.out.print(\"1\");} | )\n"
117: + " ('a' {System.out.print(\"2\");})* ;\n";
118: String found = execParser("foo.g", grammar, "fooParser",
119: "fooLexer", "a", "aaa", false);
120: assertEquals("122\n", found);
121: }
122:
123: public void testLexerPredInExitBranch4() throws Exception {
124: String grammar = "grammar foo;"
125: + "a : (A|B)+ ;\n"
126: + "A @init {int n=0;} : ({n<2}? 'a' {System.out.print(n++);})+\n"
127: + " ('a' {System.out.print(\"x\");})* ;\n";
128: String found = execParser("foo.g", grammar, "fooParser",
129: "fooLexer", "a", "aaaaa", false);
130: assertEquals("01xxx\n", found);
131: }
132:
133: public void testLexerPredsInCyclicDFA() throws Exception {
134: String grammar = "grammar foo;"
135: + "@lexer::members {boolean p=false;}\n"
136: + "a : (A|B)+ ;\n"
137: + "A : {p}? ('a')+ 'x' {System.out.println(\"token 1\");} ;\n"
138: + "B : ('a')+ 'x' {System.out.println(\"token 2\");} ;\n";
139: String found = execParser("foo.g", grammar, "fooParser",
140: "fooLexer", "a", "aax", false);
141: assertEquals("token 2\n", found);
142: }
143:
144: public void testLexerPredsInCyclicDFA2() throws Exception {
145: String grammar = "grammar foo;"
146: + "@lexer::members {boolean p=false;}\n"
147: + "a : (A|B)+ ;\n"
148: + "A : {p}? ('a')+ 'x' ('y')? {System.out.println(\"token 1\");} ;\n"
149: + "B : ('a')+ 'x' {System.out.println(\"token 2\");} ;\n";
150: String found = execParser("foo.g", grammar, "fooParser",
151: "fooLexer", "a", "aax", false);
152: assertEquals("token 2\n", found);
153: }
154:
155: public void testGatedPred() throws Exception {
156: String grammar = "grammar foo;"
157: + "a : (A|B)+ ;\n"
158: + "A : {true}?=> 'a' {System.out.println(\"token 1\");} ;\n"
159: + "B : {false}?=>('a'|'b')+ {System.out.println(\"token 2\");} ;\n";
160: String found = execParser("foo.g", grammar, "fooParser",
161: "fooLexer", "a", "aa", false);
162: // "a" is ambig; can match both A, B. Pred says match A twice
163: assertEquals("token 1\ntoken 1\n", found);
164: }
165:
166: public void testGatedPred2() throws Exception {
167: String grammar = "grammar foo;\n"
168: + "@lexer::members {boolean sig=false;}\n"
169: + "a : (A|B)+ ;\n"
170: + "A : 'a' {System.out.print(\"A\"); sig=true;} ;\n"
171: + "B : 'b' ;\n"
172: + "C : {sig}?=> ('a'|'b') {System.out.print(\"C\");} ;\n";
173: String found = execParser("foo.g", grammar, "fooParser",
174: "fooLexer", "a", "aa", false);
175: assertEquals("AC\n", found);
176: }
177:
178: public void testPredWithActionTranslation() throws Exception {
179: String grammar = "grammar foo;\n"
180: + "a : b[2] ;\n"
181: + "b[int i]\n"
182: + " : {$i==1}? 'a' {System.out.println(\"alt 1\");}\n"
183: + " | {$b.i==2}? 'a' {System.out.println(\"alt 2\");}\n"
184: + " ;\n";
185: String found = execParser("foo.g", grammar, "fooParser",
186: "fooLexer", "a", "aa", false);
187: assertEquals("alt 2\n", found);
188: }
189:
190: public void testPredicatesOnEOTTarget() throws Exception {
191: String grammar = "grammar foo; \n"
192: + "@lexer::members {boolean p=true, q=false;}"
193: + "a : B ;\n" + "A: '</'; \n"
194: + "B: {p}? '<!' {System.out.println(\"B\");};\n"
195: + "C: {q}? '<' {System.out.println(\"C\");}; \n"
196: + "D: '<';\n";
197: String found = execParser("foo.g", grammar, "fooParser",
198: "fooLexer", "a", "<!", false);
199: assertEquals("B\n", found);
200: }
201:
202: // S U P P O R T
203:
204: public void _test() throws Exception {
205: String grammar = "grammar T;\n" + "options {output=AST;}\n"
206: + "a : ;\n" + "ID : 'a'..'z'+ ;\n"
207: + "INT : '0'..'9'+;\n"
208: + "WS : (' '|'\\n') {channel=99;} ;\n";
209: String found = execParser("t.g", grammar, "T", "TLexer", "a",
210: "abc 34", false);
211: assertEquals("\n", found);
212: }
213:
214: }
|