blob: 4ff774e29a3e1a181163f4783db1c5b12f596e06 [file] [log] [blame]
/*
* [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.analysis.State;
import org.antlr.tool.FASerializer;
import org.antlr.tool.Grammar;
import org.junit.Test;
public class TestNFAConstruction extends BaseTest {
/** Public default constructor used by TestRig */
public TestNFAConstruction() {
}
@Test public void testA() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : A;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2-A->.s3\n" +
".s3->:s4\n" +
":s4-EOF->.s5\n";
checkRule(g, "a", expecting);
}
@Test public void testAB() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : A B ;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2-A->.s3\n" +
".s3-B->.s4\n" +
".s4->:s5\n" +
":s5-EOF->.s6\n";
checkRule(g, "a", expecting);
}
@Test public void testAorB() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : A | B {;} ;");
/* expecting (0)--Ep-->(1)--Ep-->(2)--A-->(3)--Ep-->(4)--Ep-->(5,end)
| ^
(6)--Ep-->(7)--B-->(8)--------|
*/
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s1->.s7\n" +
".s10->.s4\n" +
".s2-A->.s3\n" +
".s3->.s4\n" +
".s4->:s5\n" +
".s7->.s8\n" +
".s8-B->.s9\n" +
".s9-{}->.s10\n" +
":s5-EOF->.s6\n";
checkRule(g, "a", expecting);
}
@Test public void testRangeOrRange() throws Exception {
Grammar g = new Grammar(
"lexer grammar P;\n"+
"A : ('a'..'c' 'h' | 'q' 'j'..'l') ;"
);
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s10-'q'->.s11\n" +
".s11-'j'..'l'->.s12\n" +
".s12->.s6\n" +
".s2->.s3\n" +
".s2->.s9\n" +
".s3-'a'..'c'->.s4\n" +
".s4-'h'->.s5\n" +
".s5->.s6\n" +
".s6->:s7\n" +
".s9->.s10\n" +
":s7-<EOT>->.s8\n";
checkRule(g, "A", expecting);
}
@Test public void testRange() throws Exception {
Grammar g = new Grammar(
"lexer grammar P;\n"+
"A : 'a'..'c' ;"
);
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2-'a'..'c'->.s3\n" +
".s3->:s4\n" +
":s4-<EOT>->.s5\n";
checkRule(g, "A", expecting);
}
@Test public void testCharSetInParser() throws Exception {
Grammar g = new Grammar(
"grammar P;\n"+
"a : A|'b' ;"
);
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2-A..'b'->.s3\n" +
".s3->:s4\n" +
":s4-EOF->.s5\n";
checkRule(g, "a", expecting);
}
@Test public void testABorCD() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : A B | C D;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s1->.s8\n" +
".s10-D->.s11\n" +
".s11->.s5\n" +
".s2-A->.s3\n" +
".s3-B->.s4\n" +
".s4->.s5\n" +
".s5->:s6\n" +
".s8->.s9\n" +
".s9-C->.s10\n" +
":s6-EOF->.s7\n";
checkRule(g, "a", expecting);
}
@Test public void testbA() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : b A ;\n"+
"b : B ;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2->.s3\n" +
".s3->.s4\n" +
".s4->.s5\n" +
".s5-B->.s6\n" +
".s6->:s7\n" +
".s8-A->.s9\n" +
".s9->:s10\n" +
":s10-EOF->.s11\n" +
":s7->.s8\n";
checkRule(g, "a", expecting);
}
@Test public void testbA_bC() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : b A ;\n"+
"b : B ;\n"+
"c : b C;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s12->.s13\n" +
".s13-C->.s14\n" +
".s14->:s15\n" +
".s2->.s3\n" +
".s3->.s4\n" +
".s4->.s5\n" +
".s5-B->.s6\n" +
".s6->:s7\n" +
".s8-A->.s9\n" +
".s9->:s10\n" +
":s10-EOF->.s11\n" +
":s15-EOF->.s16\n" +
":s7->.s12\n" +
":s7->.s8\n";
checkRule(g, "a", expecting);
}
@Test public void testAorEpsilon() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : A | ;");
/* expecting (0)--Ep-->(1)--Ep-->(2)--A-->(3)--Ep-->(4)--Ep-->(5,end)
| ^
(6)--Ep-->(7)--Ep-->(8)-------|
*/
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s1->.s7\n" +
".s2-A->.s3\n" +
".s3->.s4\n" +
".s4->:s5\n" +
".s7->.s8\n" +
".s8->.s9\n" +
".s9->.s4\n" +
":s5-EOF->.s6\n";
checkRule(g, "a", expecting);
}
@Test public void testAOptional() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : (A)?;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2->.s3\n" +
".s2->.s8\n" +
".s3-A->.s4\n" +
".s4->.s5\n" +
".s5->:s6\n" +
".s8->.s5\n" +
":s6-EOF->.s7\n";
checkRule(g, "a", expecting);
}
@Test public void testNakedAoptional() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : A?;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2->.s3\n" +
".s2->.s8\n" +
".s3-A->.s4\n" +
".s4->.s5\n" +
".s5->:s6\n" +
".s8->.s5\n" +
":s6-EOF->.s7\n";
checkRule(g, "a", expecting);
}
@Test public void testAorBthenC() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : (A | B) C;");
/* expecting
(0)--Ep-->(1)--Ep-->(2)--A-->(3)--Ep-->(4)--Ep-->(5)--C-->(6)--Ep-->(7,end)
| ^
(8)--Ep-->(9)--B-->(10)-------|
*/
}
@Test public void testAplus() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : (A)+;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2->.s3\n" +
".s3->.s4\n" +
".s4-A->.s5\n" +
".s5->.s3\n" +
".s5->.s6\n" +
".s6->:s7\n" +
":s7-EOF->.s8\n";
checkRule(g, "a", expecting);
}
@Test public void testNakedAplus() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : A+;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2->.s3\n" +
".s3->.s4\n" +
".s4-A->.s5\n" +
".s5->.s3\n" +
".s5->.s6\n" +
".s6->:s7\n" +
":s7-EOF->.s8\n";
checkRule(g, "a", expecting);
}
@Test public void testAplusNonGreedy() throws Exception {
Grammar g = new Grammar(
"lexer grammar t;\n"+
"A : (options {greedy=false;}:'0'..'9')+ ;\n");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2->.s3\n" +
".s3->.s4\n" +
".s4-'0'..'9'->.s5\n" +
".s5->.s3\n" +
".s5->.s6\n" +
".s6->:s7\n" +
":s7-<EOT>->.s8\n";
checkRule(g, "A", expecting);
}
@Test public void testAorBplus() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : (A | B{action})+ ;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s10->.s11\n" +
".s11-B->.s12\n" +
".s12-{}->.s13\n" +
".s13->.s6\n" +
".s2->.s3\n" +
".s3->.s10\n" +
".s3->.s4\n" +
".s4-A->.s5\n" +
".s5->.s6\n" +
".s6->.s3\n" +
".s6->.s7\n" +
".s7->:s8\n" +
":s8-EOF->.s9\n";
checkRule(g, "a", expecting);
}
@Test public void testAorBorEmptyPlus() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : (A | B | )+ ;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s10->.s11\n" +
".s10->.s13\n" +
".s11-B->.s12\n" +
".s12->.s6\n" +
".s13->.s14\n" +
".s14->.s15\n" +
".s15->.s6\n" +
".s2->.s3\n" +
".s3->.s10\n" +
".s3->.s4\n" +
".s4-A->.s5\n" +
".s5->.s6\n" +
".s6->.s3\n" +
".s6->.s7\n" +
".s7->:s8\n" +
":s8-EOF->.s9\n";
checkRule(g, "a", expecting);
}
@Test public void testAStar() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : (A)*;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2->.s3\n" +
".s2->.s9\n" +
".s3->.s4\n" +
".s4-A->.s5\n" +
".s5->.s3\n" +
".s5->.s6\n" +
".s6->:s7\n" +
".s9->.s6\n" +
":s7-EOF->.s8\n";
checkRule(g, "a", expecting);
}
@Test public void testNestedAstar() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : (A*)*;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s10->:s11\n" +
".s13->.s8\n" +
".s14->.s10\n" +
".s2->.s14\n" +
".s2->.s3\n" +
".s3->.s4\n" +
".s4->.s13\n" +
".s4->.s5\n" +
".s5->.s6\n" +
".s6-A->.s7\n" +
".s7->.s5\n" +
".s7->.s8\n" +
".s8->.s9\n" +
".s9->.s10\n" +
".s9->.s3\n" +
":s11-EOF->.s12\n";
checkRule(g, "a", expecting);
}
@Test public void testPlusNestedInStar() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : (A+)*;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s10->:s11\n" +
".s13->.s10\n" +
".s2->.s13\n" +
".s2->.s3\n" +
".s3->.s4\n" +
".s4->.s5\n" +
".s5->.s6\n" +
".s6-A->.s7\n" +
".s7->.s5\n" +
".s7->.s8\n" +
".s8->.s9\n" +
".s9->.s10\n" +
".s9->.s3\n" +
":s11-EOF->.s12\n";
checkRule(g, "a", expecting);
}
@Test public void testStarNestedInPlus() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : (A*)+;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s10->:s11\n" +
".s13->.s8\n" +
".s2->.s3\n" +
".s3->.s4\n" +
".s4->.s13\n" +
".s4->.s5\n" +
".s5->.s6\n" +
".s6-A->.s7\n" +
".s7->.s5\n" +
".s7->.s8\n" +
".s8->.s9\n" +
".s9->.s10\n" +
".s9->.s3\n" +
":s11-EOF->.s12\n";
checkRule(g, "a", expecting);
}
@Test public void testNakedAstar() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : A*;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2->.s3\n" +
".s2->.s9\n" +
".s3->.s4\n" +
".s4-A->.s5\n" +
".s5->.s3\n" +
".s5->.s6\n" +
".s6->:s7\n" +
".s9->.s6\n" +
":s7-EOF->.s8\n";
checkRule(g, "a", expecting);
}
@Test public void testAorBstar() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : (A | B{action})* ;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s10->.s11\n" +
".s11-B->.s12\n" +
".s12-{}->.s13\n" +
".s13->.s6\n" +
".s14->.s7\n" +
".s2->.s14\n" +
".s2->.s3\n" +
".s3->.s10\n" +
".s3->.s4\n" +
".s4-A->.s5\n" +
".s5->.s6\n" +
".s6->.s3\n" +
".s6->.s7\n" +
".s7->:s8\n" +
":s8-EOF->.s9\n";
checkRule(g, "a", expecting);
}
@Test public void testAorBOptionalSubrule() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : ( A | B )? ;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2->.s3\n" +
".s2->.s8\n" +
".s3-A..B->.s4\n" +
".s4->.s5\n" +
".s5->:s6\n" +
".s8->.s5\n" +
":s6-EOF->.s7\n";
checkRule(g, "a", expecting);
}
@Test public void testPredicatedAorB() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : {p1}? A | {p2}? B ;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s1->.s8\n" +
".s10-B->.s11\n" +
".s11->.s5\n" +
".s2-{p1}?->.s3\n" +
".s3-A->.s4\n" +
".s4->.s5\n" +
".s5->:s6\n" +
".s8->.s9\n" +
".s9-{p2}?->.s10\n" +
":s6-EOF->.s7\n";
checkRule(g, "a", expecting);
}
@Test public void testMultiplePredicates() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : {p1}? {p1a}? A | {p2}? B | {p3} b;\n" +
"b : {p4}? B ;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s1->.s9\n" +
".s10-{p2}?->.s11\n" +
".s11-B->.s12\n" +
".s12->.s6\n" +
".s13->.s14\n" +
".s14-{}->.s15\n" +
".s15->.s16\n" +
".s16->.s17\n" +
".s17->.s18\n" +
".s18-{p4}?->.s19\n" +
".s19-B->.s20\n" +
".s2-{p1}?->.s3\n" +
".s20->:s21\n" +
".s22->.s6\n" +
".s3-{p1a}?->.s4\n" +
".s4-A->.s5\n" +
".s5->.s6\n" +
".s6->:s7\n" +
".s9->.s10\n" +
".s9->.s13\n" +
":s21->.s22\n" +
":s7-EOF->.s8\n";
checkRule(g, "a", expecting);
}
@Test public void testSets() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"a : ( A | B )+ ;\n" +
"b : ( A | B{;} )+ ;\n" +
"c : (A|B) (A|B) ;\n" +
"d : ( A | B )* ;\n" +
"e : ( A | B )? ;");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2->.s3\n" +
".s3->.s4\n" +
".s4-A..B->.s5\n" +
".s5->.s3\n" +
".s5->.s6\n" +
".s6->:s7\n" +
":s7-EOF->.s8\n";
checkRule(g, "a", expecting);
expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s10->.s11\n" +
".s11-B->.s12\n" +
".s12-{}->.s13\n" +
".s13->.s6\n" +
".s2->.s3\n" +
".s3->.s10\n" +
".s3->.s4\n" +
".s4-A->.s5\n" +
".s5->.s6\n" +
".s6->.s3\n" +
".s6->.s7\n" +
".s7->:s8\n" +
":s8-EOF->.s9\n";
checkRule(g, "b", expecting);
expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2-A..B->.s3\n" +
".s3-A..B->.s4\n" +
".s4->:s5\n" +
":s5-EOF->.s6\n";
checkRule(g, "c", expecting);
expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2->.s3\n" +
".s2->.s9\n" +
".s3->.s4\n" +
".s4-A..B->.s5\n" +
".s5->.s3\n" +
".s5->.s6\n" +
".s6->:s7\n" +
".s9->.s6\n" +
":s7-EOF->.s8\n";
checkRule(g, "d", expecting);
expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2->.s3\n" +
".s2->.s8\n" +
".s3-A..B->.s4\n" +
".s4->.s5\n" +
".s5->:s6\n" +
".s8->.s5\n" +
":s6-EOF->.s7\n";
checkRule(g, "e", expecting);
}
@Test public void testNotSet() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"tokens { A; B; C; }\n"+
"a : ~A ;\n");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2-B..C->.s3\n" +
".s3->:s4\n" +
":s4-EOF->.s5\n";
checkRule(g, "a", expecting);
String expectingGrammarStr =
"1:8: parser grammar P;\n" +
"a : ~ A ;";
assertEquals(expectingGrammarStr, g.toString());
}
@Test public void testNotSingletonBlockSet() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"tokens { A; B; C; }\n"+
"a : ~(A) ;\n");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2-B..C->.s3\n" +
".s3->:s4\n" +
":s4-EOF->.s5\n";
checkRule(g, "a", expecting);
String expectingGrammarStr =
"1:8: parser grammar P;\n" +
"a : ~ ( A ) ;";
assertEquals(expectingGrammarStr, g.toString());
}
@Test public void testNotCharSet() throws Exception {
Grammar g = new Grammar(
"lexer grammar P;\n"+
"A : ~'3' ;\n");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2-{'\\u0000'..'2', '4'..'\\uFFFF'}->.s3\n" +
".s3->:s4\n" +
":s4-<EOT>->.s5\n";
checkRule(g, "A", expecting);
String expectingGrammarStr =
"1:7: lexer grammar P;\n" +
"A : ~ '3' ;\n"+
"Tokens : A ;";
assertEquals(expectingGrammarStr, g.toString());
}
@Test public void testNotBlockSet() throws Exception {
Grammar g = new Grammar(
"lexer grammar P;\n"+
"A : ~('3'|'b') ;\n");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2-{'\\u0000'..'2', '4'..'a', 'c'..'\\uFFFF'}->.s3\n" +
".s3->:s4\n" +
":s4-<EOT>->.s5\n";
checkRule(g, "A", expecting);
String expectingGrammarStr =
"1:7: lexer grammar P;\n" +
"A : ~ ( '3' | 'b' ) ;\n" +
"Tokens : A ;";
assertEquals(expectingGrammarStr, g.toString());
}
@Test public void testNotSetLoop() throws Exception {
Grammar g = new Grammar(
"lexer grammar P;\n"+
"A : ~('3')* ;\n");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2->.s3\n" +
".s2->.s9\n" +
".s3->.s4\n" +
".s4-{'\\u0000'..'2', '4'..'\\uFFFF'}->.s5\n" +
".s5->.s3\n" +
".s5->.s6\n" +
".s6->:s7\n" +
".s9->.s6\n" +
":s7-<EOT>->.s8\n";
checkRule(g, "A", expecting);
String expectingGrammarStr =
"1:7: lexer grammar P;\n" +
"A : (~ ( '3' ) )* ;\n" +
"Tokens : A ;";
assertEquals(expectingGrammarStr, g.toString());
}
@Test public void testNotBlockSetLoop() throws Exception {
Grammar g = new Grammar(
"lexer grammar P;\n"+
"A : ~('3'|'b')* ;\n");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2->.s3\n" +
".s2->.s9\n" +
".s3->.s4\n" +
".s4-{'\\u0000'..'2', '4'..'a', 'c'..'\\uFFFF'}->.s5\n" +
".s5->.s3\n" +
".s5->.s6\n" +
".s6->:s7\n" +
".s9->.s6\n" +
":s7-<EOT>->.s8\n";
checkRule(g, "A", expecting);
String expectingGrammarStr =
"1:7: lexer grammar P;\n" +
"A : (~ ( '3' | 'b' ) )* ;\n" +
"Tokens : A ;";
assertEquals(expectingGrammarStr, g.toString());
}
@Test public void testSetsInCombinedGrammarSentToLexer() throws Exception {
// not sure this belongs in this test suite, but whatever.
Grammar g = new Grammar(
"grammar t;\n"+
"A : '{' ~('}')* '}';\n");
String result = g.getLexerGrammar();
String expecting =
"lexer grammar t;" +newline +
"// $ANTLR src \"<string>\" 2"+newline+
"A : '{' ~('}')* '}';";
assertEquals(result, expecting);
}
@Test public void testLabeledNotSet() throws Exception {
Grammar g = new Grammar(
"parser grammar P;\n"+
"tokens { A; B; C; }\n"+
"a : t=~A ;\n");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2-B..C->.s3\n" +
".s3->:s4\n" +
":s4-EOF->.s5\n";
checkRule(g, "a", expecting);
String expectingGrammarStr =
"1:8: parser grammar P;\n" +
"a : t=~ A ;";
assertEquals(expectingGrammarStr, g.toString());
}
@Test public void testLabeledNotCharSet() throws Exception {
Grammar g = new Grammar(
"lexer grammar P;\n"+
"A : t=~'3' ;\n");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2-{'\\u0000'..'2', '4'..'\\uFFFF'}->.s3\n" +
".s3->:s4\n" +
":s4-<EOT>->.s5\n";
checkRule(g, "A", expecting);
String expectingGrammarStr =
"1:7: lexer grammar P;\n" +
"A : t=~ '3' ;\n"+
"Tokens : A ;";
assertEquals(expectingGrammarStr, g.toString());
}
@Test public void testLabeledNotBlockSet() throws Exception {
Grammar g = new Grammar(
"lexer grammar P;\n"+
"A : t=~('3'|'b') ;\n");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2-{'\\u0000'..'2', '4'..'a', 'c'..'\\uFFFF'}->.s3\n" +
".s3->:s4\n" +
":s4-<EOT>->.s5\n";
checkRule(g, "A", expecting);
String expectingGrammarStr =
"1:7: lexer grammar P;\n" +
"A : t=~ ( '3' | 'b' ) ;\n" +
"Tokens : A ;";
assertEquals(expectingGrammarStr, g.toString());
}
@Test public void testEscapedCharLiteral() throws Exception {
Grammar g = new Grammar(
"grammar P;\n"+
"a : '\\n';");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2-'\\n'->.s3\n" +
".s3->:s4\n" +
":s4-EOF->.s5\n";
checkRule(g, "a", expecting);
}
@Test public void testEscapedStringLiteral() throws Exception {
Grammar g = new Grammar(
"grammar P;\n"+
"a : 'a\\nb\\u0030c\\'';");
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2-'a\\nb\\u0030c\\''->.s3\n" +
".s3->:s4\n" +
":s4-EOF->.s5\n";
checkRule(g, "a", expecting);
}
// AUTO BACKTRACKING STUFF
@Test public void testAutoBacktracking_RuleBlock() throws Exception {
Grammar g = new Grammar(
"grammar t;\n" +
"options {backtrack=true;}\n"+
"a : 'a'{;}|'b';"
);
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s1->.s9\n" +
".s10-'b'->.s11\n" +
".s11->.s6\n" +
".s2-{synpred1_t}?->.s3\n" +
".s3-'a'->.s4\n" +
".s4-{}->.s5\n" +
".s5->.s6\n" +
".s6->:s7\n" +
".s9->.s10\n" +
":s7-EOF->.s8\n";
checkRule(g, "a", expecting);
}
@Test public void testAutoBacktracking_RuleSetBlock() throws Exception {
Grammar g = new Grammar(
"grammar t;\n" +
"options {backtrack=true;}\n"+
"a : 'a'|'b';"
);
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2-'a'..'b'->.s3\n" +
".s3->:s4\n" +
":s4-EOF->.s5\n";
checkRule(g, "a", expecting);
}
@Test public void testAutoBacktracking_SimpleBlock() throws Exception {
Grammar g = new Grammar(
"grammar t;\n" +
"options {backtrack=true;}\n"+
"a : ('a'{;}|'b') ;"
);
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s10->.s11\n" +
".s11-'b'->.s12\n" +
".s12->.s7\n" +
".s2->.s10\n" +
".s2->.s3\n" +
".s3-{synpred1_t}?->.s4\n" +
".s4-'a'->.s5\n" +
".s5-{}->.s6\n" +
".s6->.s7\n" +
".s7->:s8\n" +
":s8-EOF->.s9\n";
checkRule(g, "a", expecting);
}
@Test public void testAutoBacktracking_SetBlock() throws Exception {
Grammar g = new Grammar(
"grammar t;\n" +
"options {backtrack=true;}\n"+
"a : ('a'|'b') ;"
);
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2-'a'..'b'->.s3\n" +
".s3->:s4\n" +
":s4-EOF->.s5\n";
checkRule(g, "a", expecting);
}
@Test public void testAutoBacktracking_StarBlock() throws Exception {
Grammar g = new Grammar(
"grammar t;\n" +
"options {backtrack=true;}\n"+
"a : ('a'{;}|'b')* ;"
);
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s12->.s13\n" +
".s13-{synpred2_t}?->.s14\n" +
".s14-'b'->.s15\n" +
".s15->.s8\n" +
".s16->.s9\n" +
".s2->.s16\n" +
".s2->.s3\n" +
".s3->.s12\n" +
".s3->.s4\n" +
".s4-{synpred1_t}?->.s5\n" +
".s5-'a'->.s6\n" +
".s6-{}->.s7\n" +
".s7->.s8\n" +
".s8->.s3\n" +
".s8->.s9\n" +
".s9->:s10\n" +
":s10-EOF->.s11\n";
checkRule(g, "a", expecting);
}
@Test public void testAutoBacktracking_StarSetBlock_IgnoresPreds() throws Exception {
Grammar g = new Grammar(
"grammar t;\n" +
"options {backtrack=true;}\n"+
"a : ('a'|'b')* ;"
);
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2->.s3\n" +
".s2->.s9\n" +
".s3->.s4\n" +
".s4-'a'..'b'->.s5\n" +
".s5->.s3\n" +
".s5->.s6\n" +
".s6->:s7\n" +
".s9->.s6\n" +
":s7-EOF->.s8\n";
checkRule(g, "a", expecting);
}
@Test public void testAutoBacktracking_StarSetBlock() throws Exception {
Grammar g = new Grammar(
"grammar t;\n" +
"options {backtrack=true;}\n"+
"a : ('a'|'b'{;})* ;"
);
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s11->.s12\n" +
".s12-{synpred2_t}?->.s13\n" +
".s13-'b'->.s14\n" +
".s14-{}->.s15\n" +
".s15->.s7\n" +
".s16->.s8\n" +
".s2->.s16\n" +
".s2->.s3\n" +
".s3->.s11\n" +
".s3->.s4\n" +
".s4-{synpred1_t}?->.s5\n" +
".s5-'a'->.s6\n" +
".s6->.s7\n" +
".s7->.s3\n" +
".s7->.s8\n" +
".s8->:s9\n" +
":s9-EOF->.s10\n";
checkRule(g, "a", expecting);
}
@Test public void testAutoBacktracking_StarBlock1Alt() throws Exception {
Grammar g = new Grammar(
"grammar t;\n" +
"options {backtrack=true;}\n"+
"a : ('a')* ;"
);
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s10->.s7\n" +
".s2->.s10\n" +
".s2->.s3\n" +
".s3->.s4\n" +
".s4-{synpred1_t}?->.s5\n" +
".s5-'a'->.s6\n" +
".s6->.s3\n" +
".s6->.s7\n" +
".s7->:s8\n" +
":s8-EOF->.s9\n";
checkRule(g, "a", expecting);
}
@Test public void testAutoBacktracking_PlusBlock() throws Exception {
Grammar g = new Grammar(
"grammar t;\n" +
"options {backtrack=true;}\n"+
"a : ('a'{;}|'b')+ ;"
);
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s12->.s13\n" +
".s13-{synpred2_t}?->.s14\n" +
".s14-'b'->.s15\n" +
".s15->.s8\n" +
".s2->.s3\n" +
".s3->.s12\n" +
".s3->.s4\n" +
".s4-{synpred1_t}?->.s5\n" +
".s5-'a'->.s6\n" +
".s6-{}->.s7\n" +
".s7->.s8\n" +
".s8->.s3\n" +
".s8->.s9\n" +
".s9->:s10\n" +
":s10-EOF->.s11\n";
checkRule(g, "a", expecting);
}
@Test public void testAutoBacktracking_PlusSetBlock() throws Exception {
Grammar g = new Grammar(
"grammar t;\n" +
"options {backtrack=true;}\n"+
"a : ('a'|'b'{;})+ ;"
);
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s11->.s12\n" +
".s12-{synpred2_t}?->.s13\n" +
".s13-'b'->.s14\n" +
".s14-{}->.s15\n" +
".s15->.s7\n" +
".s2->.s3\n" +
".s3->.s11\n" +
".s3->.s4\n" +
".s4-{synpred1_t}?->.s5\n" +
".s5-'a'->.s6\n" +
".s6->.s7\n" +
".s7->.s3\n" +
".s7->.s8\n" +
".s8->:s9\n" +
":s9-EOF->.s10\n";
checkRule(g, "a", expecting);
}
@Test public void testAutoBacktracking_PlusBlock1Alt() throws Exception {
Grammar g = new Grammar(
"grammar t;\n" +
"options {backtrack=true;}\n"+
"a : ('a')+ ;"
);
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2->.s3\n" +
".s3->.s4\n" +
".s4-{synpred1_t}?->.s5\n" +
".s5-'a'->.s6\n" +
".s6->.s3\n" +
".s6->.s7\n" +
".s7->:s8\n" +
":s8-EOF->.s9\n";
checkRule(g, "a", expecting);
}
@Test public void testAutoBacktracking_OptionalBlock2Alts() throws Exception {
Grammar g = new Grammar(
"grammar t;\n" +
"options {backtrack=true;}\n"+
"a : ('a'{;}|'b')?;"
);
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s10->.s11\n" +
".s10->.s14\n" +
".s11-{synpred2_t}?->.s12\n" +
".s12-'b'->.s13\n" +
".s13->.s7\n" +
".s14->.s7\n" +
".s2->.s10\n" +
".s2->.s3\n" +
".s3-{synpred1_t}?->.s4\n" +
".s4-'a'->.s5\n" +
".s5-{}->.s6\n" +
".s6->.s7\n" +
".s7->:s8\n" +
":s8-EOF->.s9\n";
checkRule(g, "a", expecting);
}
@Test public void testAutoBacktracking_OptionalBlock1Alt() throws Exception {
Grammar g = new Grammar(
"grammar t;\n" +
"options {backtrack=true;}\n"+
"a : ('a')?;"
);
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s2->.s3\n" +
".s2->.s9\n" +
".s3-{synpred1_t}?->.s4\n" +
".s4-'a'->.s5\n" +
".s5->.s6\n" +
".s6->:s7\n" +
".s9->.s6\n" +
":s7-EOF->.s8\n";
checkRule(g, "a", expecting);
}
@Test public void testAutoBacktracking_ExistingPred() throws Exception {
Grammar g = new Grammar(
"grammar t;\n" +
"options {backtrack=true;}\n"+
"a : ('a')=> 'a' | 'b';"
);
String expecting =
".s0->.s1\n" +
".s1->.s2\n" +
".s1->.s8\n" +
".s10->.s5\n" +
".s2-{synpred1_t}?->.s3\n" +
".s3-'a'->.s4\n" +
".s4->.s5\n" +
".s5->:s6\n" +
".s8->.s9\n" +
".s9-'b'->.s10\n" +
":s6-EOF->.s7\n";
checkRule(g, "a", expecting);
}
private void checkRule(Grammar g, String rule, String expecting)
{
g.buildNFA();
State startState = g.getRuleStartState(rule);
FASerializer serializer = new FASerializer(g);
String result = serializer.serialize(startState);
//System.out.print(result);
assertEquals(expecting, result);
}
}