Ensure that serialized transitions only point to states which weren't removed. Add unit test for a current failure case (will be a regression test once fixed).

This commit is contained in:
Sam Harwell 2012-03-19 08:32:34 -05:00
parent ea7037dd2d
commit 4bc615d72f
2 changed files with 29 additions and 0 deletions

View File

@ -133,6 +133,11 @@ public class ATNSerializer {
if ( s==null ) continue; // might be optimized away
for (int i=0; i<s.getNumberOfTransitions(); i++) {
Transition t = s.transition(i);
if (atn.states.get(t.target.stateNumber) == null) {
throw new IllegalStateException("Cannot serialize a transition to a removed state.");
}
int src = s.stateNumber;
int trg = t.target.stateNumber;
int edgeType = Transition.serializationTypes.get(t.getClass());

View File

@ -28,6 +28,7 @@
package org.antlr.v4.test;
import org.antlr.v4.automata.ATNSerializer;
import org.junit.Test;
/** test runtime parse errors */
@ -253,4 +254,27 @@ public class TestParseErrors extends BaseTest {
assertEquals(expecting, result);
}
/**
* This is a regression test for #45 "NullPointerException in ATNConfig.hashCode".
* https://github.com/antlr/antlr4/issues/45
*
* The original cause of this issue was an error in the tool's ATN state optimization,
* which is now detected early in {@link ATNSerializer} by ensuring that all
* serialized transitions point to states which were not removed.
*/
@Test
public void testInvalidATNStateRemoval() throws Exception {
String grammar =
"grammar T;\n" +
"start : ID ':' expr;\n" +
"expr : primary expr? {} | expr '->' ID;\n" +
"primary : ID;\n" +
"ID : [a-z]+;\n" +
"\n";
String result = execParser("T.g", grammar, "TParser", "TLexer", "start", "x:x", true);
String expecting = "";
assertEquals(expecting, result);
assertNull(this.stderrDuringParse);
}
}