From 2ecfe2671a9722b2ef7c100992e7c6772bac56e4 Mon Sep 17 00:00:00 2001 From: Terence Parr Date: Thu, 11 Oct 2012 20:20:02 -0700 Subject: [PATCH] size!=cardinality with BitSet. --- .../v4/runtime/atn/ParserATNSimulator.java | 12 ++++---- tool/playground/T.g | 18 +++++++----- .../antlr/v4/test/TestFullContextParsing.java | 29 +++++++++++++++++-- .../org/antlr/v4/test/TestLeftRecursion.java | 2 +- .../antlr/v4/test/TestSemPredEvalParser.java | 26 ++++++++++++++--- 5 files changed, 65 insertions(+), 22 deletions(-) diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java b/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java index 4b4c4789a..361e75814 100755 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java @@ -255,7 +255,7 @@ import java.util.Set; */ public class ParserATNSimulator extends ATNSimulator { - public static boolean debug = false; + public static boolean debug = true; public static boolean debug_list_atn_decisions = false; public static boolean dfa_debug = false; public static boolean retry_debug = false; @@ -672,6 +672,7 @@ public class ParserATNSimulator extends ATNSimulator { if ( debug ) { System.out.println("SLL altSubSets="+altSubSets+ + ", configs="+reach+ ", predict="+predictedAlt+", allSubsetsConflict="+ allSubsetsConflict(altSubSets)+", conflictingAlts="+ getConflictingAlts(reach)); @@ -753,7 +754,7 @@ public class ParserATNSimulator extends ATNSimulator { BitSet alts = evalSemanticContext(D.predicates, outerContext, true); D.prediction = ATN.INVALID_ALT_NUMBER; // indicate we have preds addDFAEdge(dfa, previousD, t, D); - switch (alts.size()) { + switch (alts.cardinality()) { case 0: throw noViableAlt(input, outerContext, D.configs, startIndex); @@ -828,15 +829,12 @@ public class ParserATNSimulator extends ATNSimulator { System.out.println("LL altSubSets="+altSubSets+ ", predict="+getUniqueAlt(altSubSets)+ ", resolvesToJustOneViableAlt="+ - resolvesToJustOneViableAlt(altSubSets)+ - ", conflictingAlts="+ - getConflictingAlts(reach)); + resolvesToJustOneViableAlt(altSubSets)); } // System.out.println("altSubSets: "+altSubSets); reach.uniqueAlt = getUniqueAlt(altSubSets); if ( reach.uniqueAlt!=ATN.INVALID_ALT_NUMBER ) break; - reach.conflictingAlts = getConflictingAlts(reach); if ( resolvesToJustOneViableAlt(altSubSets) ) break; previous = reach; input.consume(); @@ -878,7 +876,7 @@ public class ParserATNSimulator extends ATNSimulator { reportAmbiguity(dfa, D, startIndex, input.index(), reach.conflictingAlts, reach); } - return reach.conflictingAlts.nextSetBit(0); + return getConflictingAlts(reach).nextSetBit(0); } protected ATNConfigSet computeReachSet(ATNConfigSet closure, int t, diff --git a/tool/playground/T.g b/tool/playground/T.g index 11ed8b3d1..00d674a9e 100644 --- a/tool/playground/T.g +++ b/tool/playground/T.g @@ -1,10 +1,12 @@ grammar T; -s : expr expr - | expr +s : expr[0] ; + +expr[int _p] + : ID + ( {5 >= $_p}? '*' expr[6] + | {4 >= $_p}? '+' expr[5] + )* ; -expr: '@' - | ID '@' - | ID - ; -ID : [a-z]+ ; -WS : [ \r\n\t]+ -> skip ; + +ID : [a-zA-Z]+ ; // match identifiers +WS : [ \t\r\n]+ -> skip ; // toss out whitespace diff --git a/tool/test/org/antlr/v4/test/TestFullContextParsing.java b/tool/test/org/antlr/v4/test/TestFullContextParsing.java index 2bcb3f911..2152805c2 100644 --- a/tool/test/org/antlr/v4/test/TestFullContextParsing.java +++ b/tool/test/org/antlr/v4/test/TestFullContextParsing.java @@ -247,8 +247,33 @@ public class TestFullContextParsing extends BaseTest { assertEquals("pass: a(i)<-x\n", found); String expecting = - "line 1:3 reportAttemptingFullContext d=3, input='a(i)'\n" + - "line 1:7 reportAmbiguity d=3: ambigAlts={2..3}, input='a(i)<-x'\n"; + "line 1:7 reportAttemptingFullContext d=3, input='a(i)<-x'\n" + + "line 1:7 reportAmbiguity d=3: ambigAlts={2, 3}, input='a(i)<-x'\n"; + assertEquals(expecting, this.stderrDuringParse); + } + + @Test + public void testTrueAmbiguityNoLoop() throws Exception { + // simpler version of testLoopsSimulateTailRecursion, no loops + String grammar = + "grammar T;\n" + + "prog: expr expr {System.out.println(\"alt 1\");}\n" + + " | expr\n" + + " ;\n" + + "expr: '@'\n" + + " | ID '@'\n" + + " | ID\n" + + " ;\n" + + "ID : [a-z]+ ;\n" + + "WS : [ \r\n\t]+ -> skip ;\n"; + + String found = execParser("T.g4", grammar, "TParser", "TLexer", "prog", "a@", true); + assertEquals("alt 1\n", found); + + String expecting = + "line 1:2 reportAmbiguity d=0: ambigAlts={1, 2}, input='a@'\n" + + "line 1:2 reportAttemptingFullContext d=1, input='a@'\n" + + "line 1:2 reportContextSensitivity d=1, input='a@'\n"; assertEquals(expecting, this.stderrDuringParse); } diff --git a/tool/test/org/antlr/v4/test/TestLeftRecursion.java b/tool/test/org/antlr/v4/test/TestLeftRecursion.java index b9b48c091..65f6c6faa 100644 --- a/tool/test/org/antlr/v4/test/TestLeftRecursion.java +++ b/tool/test/org/antlr/v4/test/TestLeftRecursion.java @@ -331,7 +331,7 @@ public class TestLeftRecursion extends BaseTest { assertEquals("line 1:1 reportAttemptingFullContext d=3, input='+'\n" + "line 1:1 reportContextSensitivity d=3, input='+'\n" + "line 1:3 reportAttemptingFullContext d=3, input='*'\n" + - "line 1:3 reportAmbiguity d=3: ambigAlts={1..2}, input='*'\n", + "line 1:3 reportAmbiguity d=3: ambigAlts={1, 2}, input='*'\n", stderrDuringParse); result = execParser("Expr.g4", grammar, "ExprParser", "ExprLexer", "prog", "(1+2)*3\n", true); diff --git a/tool/test/org/antlr/v4/test/TestSemPredEvalParser.java b/tool/test/org/antlr/v4/test/TestSemPredEvalParser.java index 99d449766..3c7bec354 100644 --- a/tool/test/org/antlr/v4/test/TestSemPredEvalParser.java +++ b/tool/test/org/antlr/v4/test/TestSemPredEvalParser.java @@ -35,6 +35,24 @@ public class TestSemPredEvalParser extends BaseTest { // TEST VALIDATING PREDS @Test public void testSimpleValidate() throws Exception { + String grammar = + "grammar T;\n" + + "s : a ;\n" + + "a : {false}? ID {System.out.println(\"alt 1\");}\n" + + " | {true}? INT {System.out.println(\"alt 2\");}\n" + + " ;\n" + + "ID : 'a'..'z'+ ;\n" + + "INT : '0'..'9'+;\n" + + "WS : (' '|'\\n') {skip();} ;\n"; + + String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", + "x", false); + + String expecting = "line 1:0 no viable alternative at input 'x'\n"; + assertEquals(expecting, stderrDuringParse); + } + + @Test public void testSimpleValidate2() throws Exception { String grammar = "grammar T;\n" + "s : a a a;\n" + @@ -154,9 +172,9 @@ public class TestSemPredEvalParser extends BaseTest { "alt 1\n"; assertEquals(expecting, found); assertEquals("line 1:0 reportAttemptingFullContext d=0, input='x'\n" + - "line 1:0 reportAmbiguity d=0: ambigAlts={1..2}, input='x'\n" + + "line 1:0 reportAmbiguity d=0: ambigAlts={1, 2}, input='x'\n" + "line 1:3 reportAttemptingFullContext d=0, input='y'\n" + - "line 1:3 reportAmbiguity d=0: ambigAlts={1..2}, input='y'\n", + "line 1:3 reportAmbiguity d=0: ambigAlts={1, 2}, input='y'\n", this.stderrDuringParse); } @@ -188,9 +206,9 @@ public class TestSemPredEvalParser extends BaseTest { "alt 2\n"; assertEquals(expecting, found); assertEquals("line 1:4 reportAttemptingFullContext d=0, input='x'\n" + - "line 1:4 reportAmbiguity d=0: ambigAlts={2..3}, input='x'\n" + + "line 1:4 reportAmbiguity d=0: ambigAlts={2, 3}, input='x'\n" + "line 1:7 reportAttemptingFullContext d=0, input='y'\n" + - "line 1:7 reportAmbiguity d=0: ambigAlts={2..3}, input='y'\n", + "line 1:7 reportAmbiguity d=0: ambigAlts={2, 3}, input='y'\n", this.stderrDuringParse); }