strip epsilons between alternative elements and also stripped the final epsilons before block ends. added an ATN visitor for general use. updated all of the unit tests so they pass new smaller ATNs. had to do some work in the serialization and deserialization to handle state numbers without state information. did not want to reorder state numbers during optimization.

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 9512]
This commit is contained in:
parrt 2011-12-01 17:46:12 -08:00
parent 682e60b065
commit ae74881de6
10 changed files with 365 additions and 306 deletions

View File

@ -32,6 +32,7 @@ package org.antlr.v4.runtime.atn;
import org.antlr.v4.runtime.RuleContext; import org.antlr.v4.runtime.RuleContext;
import org.antlr.v4.runtime.misc.IntervalSet; import org.antlr.v4.runtime.misc.IntervalSet;
import org.antlr.v4.runtime.misc.NotNull; import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.misc.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -100,12 +101,17 @@ public class ATN {
return s.nextTokenWithinRule; return s.nextTokenWithinRule;
} }
public void addState(@NotNull ATNState state) { public void addState(@Nullable ATNState state) {
if ( state==null ) { states.add(null); stateNumber++; return; }
state.atn = this; state.atn = this;
states.add(state); states.add(state);
state.stateNumber = stateNumber++; state.stateNumber = stateNumber++;
} }
public void removeState(@NotNull ATNState state) {
states.set(state.stateNumber, null); // just free mem, don't shift states in list
}
public int defineDecisionState(@NotNull DecisionState s) { public int defineDecisionState(@NotNull DecisionState s) {
decisionToState.add(s); decisionToState.add(s);
s.decision = decisionToState.size()-1; s.decision = decisionToState.size()-1;

View File

@ -1,39 +1,41 @@
/* /*
[The "BSD license"] [The "BSD license"]
Copyright (c) 2011 Terence Parr Copyright (c) 2011 Terence Parr
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
are met: are met:
1. Redistributions of source code must retain the above copyright 1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright 2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products 3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission. derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.antlr.v4.runtime.atn; package org.antlr.v4.runtime.atn;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.dfa.DFAState; import org.antlr.v4.runtime.dfa.DFAState;
import org.antlr.v4.runtime.misc.*; import org.antlr.v4.runtime.misc.IntervalSet;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.misc.OrderedHashSet;
import java.util.*; import java.util.ArrayList;
import java.util.List;
public abstract class ATNSimulator { public abstract class ATNSimulator {
/** Must distinguish between missing edge and edge we know leads nowhere */ /** Must distinguish between missing edge and edge we know leads nowhere */
@ -60,7 +62,12 @@ public abstract class ATNSimulator {
int nstates = toInt(data[p++]); int nstates = toInt(data[p++]);
for (int i=1; i<=nstates; i++) { for (int i=1; i<=nstates; i++) {
int stype = toInt(data[p++]); int stype = toInt(data[p++]);
if ( stype==0 ) continue; // ignore bad type of states // ignore bad type of states, skip it's bad ruleIndex too
if ( stype==ATNState.INVALID_TYPE ) {
p++;
atn.addState(null);
continue;
}
ATNState s = stateFactory(stype, i); ATNState s = stateFactory(stype, i);
s.ruleIndex = toInt(data[p++]); s.ruleIndex = toInt(data[p++]);
atn.addState(s); atn.addState(s);
@ -163,6 +170,7 @@ public abstract class ATNSimulator {
public static ATNState stateFactory(int type, int stateNumber) { public static ATNState stateFactory(int type, int stateNumber) {
ATNState s = null; ATNState s = null;
switch (type) { switch (type) {
case ATNState.INVALID_TYPE: return null;
case ATNState.BASIC : s = new ATNState(); break; case ATNState.BASIC : s = new ATNState(); break;
case ATNState.RULE_START : s = new RuleStartState(); break; case ATNState.RULE_START : s = new RuleStartState(); break;
case ATNState.BLOCK_START : s = new BlockStartState(); break; case ATNState.BLOCK_START : s = new BlockStartState(); break;

View File

@ -1,30 +1,30 @@
/* /*
[The "BSD license"] [The "BSD license"]
Copyright (c) 2011 Terence Parr Copyright (c) 2011 Terence Parr
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
are met: are met:
1. Redistributions of source code must retain the above copyright 1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright 2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products 3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission. derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.antlr.v4.runtime.atn; package org.antlr.v4.runtime.atn;
@ -37,14 +37,7 @@ public class ATNState {
public static final int INITIAL_NUM_TRANSITIONS = 4; public static final int INITIAL_NUM_TRANSITIONS = 4;
// constants for serialization // constants for serialization
// public static enum ATNStateType { public static final int INVALID_TYPE = 0;
// BASIC(1), RULE_START(2), BLOCK_START(3), PLUS_BLOCK_START(4),
// STAR_BLOCK_START(5), TOKEN_START(6), RULE_STOP(7), BLOCK_END(8),
// STAR_LOOP_BACK(9), STAR_LOOP_ENTRY(10), PLUS_LOOP_BACK(11);
// public int type;
// ATNStateType(int type) { this.type = type; }
// public int intValue() { return type; }
// }
public static final int BASIC = 1; public static final int BASIC = 1;
public static final int RULE_START = 2; public static final int RULE_START = 2;
public static final int BLOCK_START = 3; public static final int BLOCK_START = 3;
@ -103,6 +96,7 @@ public class ATNState {
protected final List<Transition> transitions = protected final List<Transition> transitions =
new ArrayList<Transition>(INITIAL_NUM_TRANSITIONS); new ArrayList<Transition>(INITIAL_NUM_TRANSITIONS);
/** Used to cache lookahead during parsing, not used during construction */
public IntervalSet nextTokenWithinRule; public IntervalSet nextTokenWithinRule;
@Override @Override
@ -111,7 +105,7 @@ public class ATNState {
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
// are these states same object? // are these states same object?
if ( o instanceof ATNState) return stateNumber==((ATNState)o).stateNumber; if ( o instanceof ATNState ) return stateNumber==((ATNState)o).stateNumber;
return false; return false;
} }

View File

@ -1,37 +1,37 @@
/* /*
[The "BSD license"] [The "BSD license"]
Copyright (c) 2011 Terence Parr Copyright (c) 2011 Terence Parr
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
are met: are met:
1. Redistributions of source code must retain the above copyright 1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright 2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products 3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission. derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.antlr.v4.runtime.atn; package org.antlr.v4.runtime.atn;
import org.antlr.v4.runtime.misc.IntervalSet;
import org.antlr.v4.runtime.misc.NotNull; import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.misc.Nullable; import org.antlr.v4.runtime.misc.Nullable;
import org.antlr.v4.runtime.misc.IntervalSet;
import java.util.*; import java.util.*;
@ -89,7 +89,7 @@ public abstract class Transition {
/** The target of this transition */ /** The target of this transition */
@NotNull @NotNull
public final ATNState target; public ATNState target;
protected Transition(@NotNull ATNState target) { this.target = target; } protected Transition(@NotNull ATNState target) { this.target = target; }

View File

@ -1,7 +1,10 @@
grammar T; grammar T;
s : e ; s : e # foo;
e : e ('+='<assoc=right>|'-='<assoc=right>) e f : ID # A
| INT | INT # B
;
e : e ('+='<assoc=right>|'-='<assoc=right>) e
| INT
; ;
ID : 'a'..'z'+ ; ID : 'a'..'z'+ ;
INT : '0'..'9'+; INT : '0'..'9'+;

View File

@ -1,30 +1,30 @@
/* /*
[The "BSD license"] [The "BSD license"]
Copyright (c) 2011 Terence Parr Copyright (c) 2011 Terence Parr
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
are met: are met:
1. Redistributions of source code must retain the above copyright 1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright 2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products 3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission. derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.antlr.v4.automata; package org.antlr.v4.automata;
@ -32,10 +32,13 @@ package org.antlr.v4.automata;
import org.antlr.v4.misc.Utils; import org.antlr.v4.misc.Utils;
import org.antlr.v4.parse.ANTLRParser; import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.runtime.atn.*; import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.misc.*; import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.tool.*; import org.antlr.v4.runtime.misc.IntervalSet;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.Rule;
import java.util.*; import java.util.ArrayList;
import java.util.List;
public class ATNSerializer { public class ATNSerializer {
public Grammar g; public Grammar g;
@ -79,6 +82,11 @@ public class ATNSerializer {
int nedges = 0; int nedges = 0;
// dump states, count edges and collect sets while doing so // dump states, count edges and collect sets while doing so
for (ATNState s : atn.states) { for (ATNState s : atn.states) {
if ( s==null ) { // might be optimized away
data.add(ATNState.INVALID_TYPE);
data.add(-1);
continue;
}
data.add(s.getStateType()); data.add(s.getStateType());
data.add(s.ruleIndex); data.add(s.ruleIndex);
nedges += s.getNumberOfTransitions(); nedges += s.getNumberOfTransitions();
@ -126,6 +134,7 @@ public class ATNSerializer {
data.add(nedges); data.add(nedges);
int setIndex = 0; int setIndex = 0;
for (ATNState s : atn.states) { for (ATNState s : atn.states) {
if ( s==null ) continue; // might be optimized away
for (int i=0; i<s.getNumberOfTransitions(); i++) { for (int i=0; i<s.getNumberOfTransitions(); i++) {
Transition t = s.transition(i); Transition t = s.transition(i);
int src = s.stateNumber; int src = s.stateNumber;

View File

@ -0,0 +1,61 @@
/*
[The "BSD license"]
Copyright (c) 2011 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.v4.automata;
import org.antlr.v4.runtime.atn.ATNState;
import org.antlr.v4.runtime.atn.Transition;
import org.antlr.v4.runtime.misc.NotNull;
import java.util.HashSet;
import java.util.Set;
/** A simple visitor that walks everywhere it can go starting from s,
* without going into an infinite cycle. Override and implement
* visitState() to provide functionality.
*/
public class ATNVisitor {
public void visit(@NotNull ATNState s) {
visit_(s, new HashSet<Integer>());
}
public void visit_(@NotNull ATNState s, @NotNull Set<Integer> visited) {
if ( !visited.add(s.stateNumber) ) return;
visited.add(s.stateNumber);
visitState(s);
int n = s.getNumberOfTransitions();
for (int i=0; i<n; i++) {
Transition t = s.transition(i);
visit_(t.target, visited);
}
}
public void visitState(ATNState s) { }
}

View File

@ -1,30 +1,30 @@
/* /*
[The "BSD license"] [The "BSD license"]
Copyright (c) 2011 Terence Parr Copyright (c) 2011 Terence Parr
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
are met: are met:
1. Redistributions of source code must retain the above copyright 1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright 2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products 3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission. derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.antlr.v4.automata; package org.antlr.v4.automata;
@ -58,6 +58,31 @@ import java.util.List;
* No side-effects. It builds an ATN object and returns it. * No side-effects. It builds an ATN object and returns it.
*/ */
public class ParserATNFactory implements ATNFactory { public class ParserATNFactory implements ATNFactory {
class TailEpsilonRemover extends ATNVisitor {
@Override
public void visitState(ATNState p) {
if ( p.getClass() == ATNState.class && p.getNumberOfTransitions()==1 ) {
ATNState q = p.transition(0).target;
if ( q.getClass() == ATNState.class ) {
// we have p-x->q for x in {rule, action, pred, token, ...}
// if edge out of q is single epsilon to block end
// we can strip epsilon p-x->q-eps->r
if ( q.getNumberOfTransitions()==1 && q.transition(0).isEpsilon() ) {
ATNState r = q.transition(0).target;
if ( r instanceof BlockEndState ||
r instanceof PlusLoopbackState ||
r instanceof StarLoopbackState )
{
// skip over q
p.transition(0).target = r;
atn.removeState(q);
}
}
}
}
}
}
@NotNull @NotNull
public final Grammar g; public final Grammar g;
@ -269,23 +294,23 @@ public class ParserATNFactory implements ATNFactory {
blkAST.atnState = h.left; blkAST.atnState = h.left;
return h; return h;
} }
BlockStartState start = (BlockStartState)newState(BlockStartState.class, blkAST); BlockStartState start = newState(BlockStartState.class, blkAST);
if ( alts.size()>1 ) atn.defineDecisionState(start); if ( alts.size()>1 ) atn.defineDecisionState(start);
return makeBlock(start, blkAST, alts); return makeBlock(start, blkAST, alts);
} }
switch ( ebnfRoot.getType() ) { switch ( ebnfRoot.getType() ) {
case ANTLRParser.OPTIONAL : case ANTLRParser.OPTIONAL :
BlockStartState start = (BlockStartState)newState(BlockStartState.class, blkAST); BlockStartState start = newState(BlockStartState.class, blkAST);
atn.defineDecisionState(start); atn.defineDecisionState(start);
Handle h = makeBlock(start, blkAST, alts); Handle h = makeBlock(start, blkAST, alts);
return optional(ebnfRoot, h); return optional(ebnfRoot, h);
case ANTLRParser.CLOSURE : case ANTLRParser.CLOSURE :
BlockStartState star = (StarBlockStartState)newState(StarBlockStartState.class, ebnfRoot); BlockStartState star = newState(StarBlockStartState.class, ebnfRoot);
if ( alts.size()>1 ) atn.defineDecisionState(star); if ( alts.size()>1 ) atn.defineDecisionState(star);
h = makeBlock(star, blkAST, alts); h = makeBlock(star, blkAST, alts);
return star(ebnfRoot, h); return star(ebnfRoot, h);
case ANTLRParser.POSITIVE_CLOSURE : case ANTLRParser.POSITIVE_CLOSURE :
PlusBlockStartState plus = (PlusBlockStartState)newState(PlusBlockStartState.class, ebnfRoot); PlusBlockStartState plus = newState(PlusBlockStartState.class, ebnfRoot);
if ( alts.size()>1 ) atn.defineDecisionState(plus); if ( alts.size()>1 ) atn.defineDecisionState(plus);
h = makeBlock(plus, blkAST, alts); h = makeBlock(plus, blkAST, alts);
return plus(ebnfRoot, h); return plus(ebnfRoot, h);
@ -294,13 +319,17 @@ public class ParserATNFactory implements ATNFactory {
} }
protected Handle makeBlock(BlockStartState start, GrammarAST blkAST, List<Handle> alts) { protected Handle makeBlock(BlockStartState start, GrammarAST blkAST, List<Handle> alts) {
BlockEndState end = (BlockEndState)newState(BlockEndState.class, blkAST); BlockEndState end = newState(BlockEndState.class, blkAST);
start.endState = end; start.endState = end;
for (Handle alt : alts) { for (Handle alt : alts) {
// hook alts up to decision block
epsilon(start, alt.left); epsilon(start, alt.left);
epsilon(alt.right, end); epsilon(alt.right, end);
// no back link in ATN so must walk entire alt to see if we can
// strip out the epsilon to 'end' state
TailEpsilonRemover opt = new TailEpsilonRemover();
opt.visit(alt.left);
} }
// if ( alts.size()>1 ) atn.defineDecisionState(start);
Handle h = new Handle(start, end); Handle h = new Handle(start, end);
// FASerializer ser = new FASerializer(g, h.left); // FASerializer ser = new FASerializer(g, h.left);
// System.out.println(blkAST.toStringTree()+":\n"+ser); // System.out.println(blkAST.toStringTree()+":\n"+ser);
@ -308,13 +337,6 @@ public class ParserATNFactory implements ATNFactory {
return h; return h;
} }
// public Handle notBlock(GrammarAST notAST, Handle set) {
// SetTransition st = (SetTransition)set.left.transition;
// set.left.addTransition(new NotSetTransition(st.label, set.right);
// notAST.atnState = set.left;
// return set;
// }
@NotNull @NotNull
public Handle alt(@NotNull List<Handle> els) { public Handle alt(@NotNull List<Handle> els) {
return elemList(els); return elemList(els);
@ -322,13 +344,26 @@ public class ParserATNFactory implements ATNFactory {
@NotNull @NotNull
public Handle elemList(@NotNull List<Handle> els) { public Handle elemList(@NotNull List<Handle> els) {
Handle prev = null; int n = els.size();
for (Handle el : els) { // hook up elements for (int i = 0; i < n - 1; i++) { // hook up elements (visit all but last)
if ( prev!=null ) epsilon(prev.right, el.left); Handle el = els.get(i);
prev = el; // if el is of form o-x->o for x in {rule, action, pred, token, ...}
// and not last in alt
if ( el.left.getClass() == ATNState.class &&
el.right.getClass() == ATNState.class &&
el.left.getNumberOfTransitions()==1 &&
el.left.transition(0).target == el.right)
{
// we can avoid epsilon edge to next el
el.left.transition(0).target = els.get(i+1).left;
atn.removeState(el.right); // we skipped over this state
}
else { // need epsilon if previous block's right end node is complicated
epsilon(el.right, els.get(i+1).left);
}
} }
Handle first = els.get(0); Handle first = els.get(0);
Handle last = els.get(els.size()-1); Handle last = els.get(n -1);
if ( first==null || last==null ) { if ( first==null || last==null ) {
g.tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, "element list has first|last == null"); g.tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, "element list has first|last == null");
} }
@ -546,4 +581,5 @@ public class ParserATNFactory implements ATNFactory {
} }
return false; return false;
} }
} }

View File

@ -1,3 +1,32 @@
/*
[The "BSD license"]
Copyright (c) 2011 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.v4.test; package org.antlr.v4.test;
import org.antlr.v4.automata.ATNPrinter; import org.antlr.v4.automata.ATNPrinter;
@ -29,8 +58,7 @@ public class TestATNConstruction extends BaseTest {
"a : A B ;"); "a : A B ;");
String expecting = String expecting =
"RuleStart_a_0->s2\n" + "RuleStart_a_0->s2\n" +
"s2-A->s3\n" + "s2-A->s4\n" +
"s3->s4\n" +
"s4-B->s5\n" + "s4-B->s5\n" +
"s5->RuleStop_a_1\n" + "s5->RuleStop_a_1\n" +
"RuleStop_a_1-EOF->s6\n"; "RuleStop_a_1-EOF->s6\n";
@ -45,14 +73,11 @@ public class TestATNConstruction extends BaseTest {
"RuleStart_a_0->BlockStart_8\n" + "RuleStart_a_0->BlockStart_8\n" +
"BlockStart_8->s2\n" + "BlockStart_8->s2\n" +
"BlockStart_8->s4\n" + "BlockStart_8->s4\n" +
"s2-A->s3\n" + "s2-A->BlockEnd_9\n" +
"s4-B->s5\n" + "s4-B->s6\n" +
"s3->BlockEnd_9\n" +
"s5->s6\n" +
"BlockEnd_9->RuleStop_a_1\n" + "BlockEnd_9->RuleStop_a_1\n" +
"s6-action_0:-1->s7\n" + // actionIndex -1 since not forced action "s6-action_0:-1->BlockEnd_9\n" +
"RuleStop_a_1-EOF->s10\n" + "RuleStop_a_1-EOF->s10\n";
"s7->BlockEnd_9\n";
checkRuleATN(g, "a", expecting); checkRuleATN(g, "a", expecting);
} }
@ -64,10 +89,8 @@ public class TestATNConstruction extends BaseTest {
"RuleStart_a_0->BlockStart_6\n" + "RuleStart_a_0->BlockStart_6\n" +
"BlockStart_6->s2\n" + "BlockStart_6->s2\n" +
"BlockStart_6->s4\n" + "BlockStart_6->s4\n" +
"s2-A->s3\n" + "s2-A->BlockEnd_7\n" +
"s4-B->s5\n" + "s4-B->BlockEnd_7\n" +
"s3->BlockEnd_7\n" +
"s5->BlockEnd_7\n" +
"BlockEnd_7->RuleStop_a_1\n" + "BlockEnd_7->RuleStop_a_1\n" +
"RuleStop_a_1-EOF->s8\n"; "RuleStop_a_1-EOF->s8\n";
checkRuleATN(g, "a", expecting); checkRuleATN(g, "a", expecting);
@ -84,10 +107,8 @@ public class TestATNConstruction extends BaseTest {
"BlockStart_9->s6\n" + "BlockStart_9->s6\n" +
"s3-'0'->s4\n" + "s3-'0'->s4\n" +
"s6-'0'->s7\n" + "s6-'0'->s7\n" +
"s4-'x'->s5\n" + "s4-'x'->BlockEnd_10\n" +
"s7-'X'->s8\n" + "s7-'X'->BlockEnd_10\n" +
"s5->BlockEnd_10\n" +
"s8->BlockEnd_10\n" +
"BlockEnd_10->RuleStop_A_2\n"; "BlockEnd_10->RuleStop_A_2\n";
checkTokensRule(g, null, expecting); checkTokensRule(g, null, expecting);
} }
@ -115,14 +136,10 @@ public class TestATNConstruction extends BaseTest {
"RuleStart_A_1->BlockStart_11\n" + "RuleStart_A_1->BlockStart_11\n" +
"BlockStart_11->s3\n" + "BlockStart_11->s3\n" +
"BlockStart_11->s7\n" + "BlockStart_11->s7\n" +
"s3-'a'..'c'->s4\n" + "s3-'a'..'c'->s5\n" +
"s7-'q'->s8\n" + "s7-'q'->s9\n" +
"s4->s5\n" + "s5-'h'->BlockEnd_12\n" +
"s8->s9\n" + "s9-'j'..'l'->BlockEnd_12\n" +
"s5-'h'->s6\n" +
"s9-'j'..'l'->s10\n" +
"s6->BlockEnd_12\n" +
"s10->BlockEnd_12\n" +
"BlockEnd_12->RuleStop_A_2\n"; "BlockEnd_12->RuleStop_A_2\n";
checkTokensRule(g, null, expecting); checkTokensRule(g, null, expecting);
} }
@ -136,10 +153,8 @@ public class TestATNConstruction extends BaseTest {
"RuleStart_a_0->BlockStart_6\n" + "RuleStart_a_0->BlockStart_6\n" +
"BlockStart_6->s2\n" + "BlockStart_6->s2\n" +
"BlockStart_6->s4\n" + "BlockStart_6->s4\n" +
"s2-A->s3\n" + "s2-A->BlockEnd_7\n" +
"s4-'b'->s5\n" + "s4-'b'->BlockEnd_7\n" +
"s3->BlockEnd_7\n" +
"s5->BlockEnd_7\n" +
"BlockEnd_7->RuleStop_a_1\n" + "BlockEnd_7->RuleStop_a_1\n" +
"RuleStop_a_1-EOF->s8\n"; "RuleStop_a_1-EOF->s8\n";
checkRuleATN(g, "a", expecting); checkRuleATN(g, "a", expecting);
@ -153,14 +168,10 @@ public class TestATNConstruction extends BaseTest {
"RuleStart_a_0->BlockStart_10\n" + "RuleStart_a_0->BlockStart_10\n" +
"BlockStart_10->s2\n" + "BlockStart_10->s2\n" +
"BlockStart_10->s6\n" + "BlockStart_10->s6\n" +
"s2-A->s3\n" + "s2-A->s4\n" +
"s6-C->s7\n" + "s6-C->s8\n" +
"s3->s4\n" + "s4-B->BlockEnd_11\n" +
"s7->s8\n" + "s8-D->BlockEnd_11\n" +
"s4-B->s5\n" +
"s8-D->s9\n" +
"s5->BlockEnd_11\n" +
"s9->BlockEnd_11\n" +
"BlockEnd_11->RuleStop_a_1\n" + "BlockEnd_11->RuleStop_a_1\n" +
"RuleStop_a_1-EOF->s12\n"; "RuleStop_a_1-EOF->s12\n";
checkRuleATN(g, "a", expecting); checkRuleATN(g, "a", expecting);
@ -210,10 +221,8 @@ public class TestATNConstruction extends BaseTest {
"RuleStart_a_0->BlockStart_6\n" + "RuleStart_a_0->BlockStart_6\n" +
"BlockStart_6->s2\n" + "BlockStart_6->s2\n" +
"BlockStart_6->s4\n" + "BlockStart_6->s4\n" +
"s2-A->s3\n" + "s2-A->BlockEnd_7\n" +
"s4->s5\n" + "s4->BlockEnd_7\n" +
"s3->BlockEnd_7\n" +
"s5->BlockEnd_7\n" +
"BlockEnd_7->RuleStop_a_1\n" + "BlockEnd_7->RuleStop_a_1\n" +
"RuleStop_a_1-EOF->s8\n"; "RuleStop_a_1-EOF->s8\n";
checkRuleATN(g, "a", expecting); checkRuleATN(g, "a", expecting);
@ -227,9 +236,8 @@ public class TestATNConstruction extends BaseTest {
"RuleStart_a_0->BlockStart_4\n" + "RuleStart_a_0->BlockStart_4\n" +
"BlockStart_4->s2\n" + "BlockStart_4->s2\n" +
"BlockStart_4->BlockEnd_5\n" + "BlockStart_4->BlockEnd_5\n" +
"s2-A->s3\n" + "s2-A->BlockEnd_5\n" +
"BlockEnd_5->RuleStop_a_1\n" + "BlockEnd_5->RuleStop_a_1\n" +
"s3->BlockEnd_5\n" +
"RuleStop_a_1-EOF->s6\n"; "RuleStop_a_1-EOF->s6\n";
checkRuleATN(g, "a", expecting); checkRuleATN(g, "a", expecting);
} }
@ -243,14 +251,11 @@ public class TestATNConstruction extends BaseTest {
"BlockStart_8->s2\n" + "BlockStart_8->s2\n" +
"BlockStart_8->s6\n" + "BlockStart_8->s6\n" +
"BlockStart_8->BlockEnd_9\n" + "BlockStart_8->BlockEnd_9\n" +
"s2-A->s3\n" + "s2-A->s4\n" +
"s6-B->s7\n" + "s6-B->BlockEnd_9\n" +
"BlockEnd_9->RuleStop_a_1\n" + "BlockEnd_9->RuleStop_a_1\n" +
"s3->s4\n" + "s4-action_0:-1->BlockEnd_9\n" +
"s7->BlockEnd_9\n" + "RuleStop_a_1-EOF->s10\n";
"RuleStop_a_1-EOF->s10\n" +
"s4-action_0:-1->s5\n" +
"s5->BlockEnd_9\n";
checkRuleATN(g, "a", expecting); checkRuleATN(g, "a", expecting);
} }
@ -262,9 +267,8 @@ public class TestATNConstruction extends BaseTest {
"RuleStart_a_0->BlockStart_4\n" + "RuleStart_a_0->BlockStart_4\n" +
"BlockStart_4->s2\n" + "BlockStart_4->s2\n" +
"BlockStart_4->BlockEnd_5\n" + "BlockStart_4->BlockEnd_5\n" +
"s2-{A, B}->s3\n" + "s2-{A, B}->BlockEnd_5\n" +
"BlockEnd_5->RuleStop_a_1\n" + "BlockEnd_5->RuleStop_a_1\n" +
"s3->BlockEnd_5\n" +
"RuleStop_a_1-EOF->s6\n"; "RuleStop_a_1-EOF->s6\n";
checkRuleATN(g, "a", expecting); checkRuleATN(g, "a", expecting);
} }
@ -275,8 +279,7 @@ public class TestATNConstruction extends BaseTest {
"a : (A | B) C;"); "a : (A | B) C;");
String expecting = String expecting =
"RuleStart_a_0->s2\n" + "RuleStart_a_0->s2\n" +
"s2-{A, B}->s3\n" + "s2-{A, B}->s4\n" +
"s3->s4\n" +
"s4-C->s5\n" + "s4-C->s5\n" +
"s5->RuleStop_a_1\n" + "s5->RuleStop_a_1\n" +
"RuleStop_a_1-EOF->s6\n"; "RuleStop_a_1-EOF->s6\n";
@ -290,8 +293,7 @@ public class TestATNConstruction extends BaseTest {
String expecting = String expecting =
"RuleStart_a_0->PlusBlockStart_4\n" + "RuleStart_a_0->PlusBlockStart_4\n" +
"PlusBlockStart_4->s2\n" + "PlusBlockStart_4->s2\n" +
"s2-A->s3\n" + "s2-A->BlockEnd_5\n" +
"s3->BlockEnd_5\n" +
"BlockEnd_5->PlusLoopBack_6\n" + "BlockEnd_5->PlusLoopBack_6\n" +
"PlusLoopBack_6->PlusBlockStart_4\n" + "PlusLoopBack_6->PlusBlockStart_4\n" +
"PlusLoopBack_6->s7\n" + "PlusLoopBack_6->s7\n" +
@ -308,15 +310,12 @@ public class TestATNConstruction extends BaseTest {
"RuleStart_a_0->PlusBlockStart_8\n" + "RuleStart_a_0->PlusBlockStart_8\n" +
"PlusBlockStart_8->s2\n" + "PlusBlockStart_8->s2\n" +
"PlusBlockStart_8->s4\n" + "PlusBlockStart_8->s4\n" +
"s2-A->s3\n" + "s2-A->BlockEnd_9\n" +
"s4-B->s5\n" + "s4-B->s6\n" +
"s3->BlockEnd_9\n" +
"s5->s6\n" +
"BlockEnd_9->PlusLoopBack_10\n" + "BlockEnd_9->PlusLoopBack_10\n" +
"s6-action_0:-1->s7\n" + "s6-action_0:-1->BlockEnd_9\n" +
"PlusLoopBack_10->PlusBlockStart_8\n" + "PlusLoopBack_10->PlusBlockStart_8\n" +
"PlusLoopBack_10->s11\n" + "PlusLoopBack_10->s11\n" +
"s7->BlockEnd_9\n" +
"s11->RuleStop_a_1\n" + "s11->RuleStop_a_1\n" +
"RuleStop_a_1-EOF->s12\n"; "RuleStop_a_1-EOF->s12\n";
checkRuleATN(g, "a", expecting); checkRuleATN(g, "a", expecting);
@ -331,12 +330,9 @@ public class TestATNConstruction extends BaseTest {
"PlusBlockStart_8->s2\n" + "PlusBlockStart_8->s2\n" +
"PlusBlockStart_8->s4\n" + "PlusBlockStart_8->s4\n" +
"PlusBlockStart_8->s6\n" + "PlusBlockStart_8->s6\n" +
"s2-A->s3\n" + "s2-A->BlockEnd_9\n" +
"s4-B->s5\n" + "s4-B->BlockEnd_9\n" +
"s6->s7\n" + "s6->BlockEnd_9\n" +
"s3->BlockEnd_9\n" +
"s5->BlockEnd_9\n" +
"s7->BlockEnd_9\n" +
"BlockEnd_9->PlusLoopBack_10\n" + "BlockEnd_9->PlusLoopBack_10\n" +
"PlusLoopBack_10->PlusBlockStart_8\n" + "PlusLoopBack_10->PlusBlockStart_8\n" +
"PlusLoopBack_10->s11\n" + "PlusLoopBack_10->s11\n" +
@ -355,9 +351,8 @@ public class TestATNConstruction extends BaseTest {
"StarLoopEntry_6->s7\n" + "StarLoopEntry_6->s7\n" +
"StarBlockStart_4->s2\n" + "StarBlockStart_4->s2\n" +
"s7->RuleStop_a_1\n" + "s7->RuleStop_a_1\n" +
"s2-A->s3\n" + "s2-A->BlockEnd_5\n" +
"RuleStop_a_1-EOF->s9\n" + "RuleStop_a_1-EOF->s9\n" +
"s3->BlockEnd_5\n" +
"BlockEnd_5->StarLoopBack_8\n" + "BlockEnd_5->StarLoopBack_8\n" +
"StarLoopBack_8->StarLoopEntry_6\n"; "StarLoopBack_8->StarLoopEntry_6\n";
checkRuleATN(g, "a", expecting); checkRuleATN(g, "a", expecting);
@ -373,18 +368,16 @@ public class TestATNConstruction extends BaseTest {
"StarLoopEntry_13->s14\n" + "StarLoopEntry_13->s14\n" +
"StarBlockStart_11->s2\n" + "StarBlockStart_11->s2\n" +
"s14->RuleStop_a_1\n" + "s14->RuleStop_a_1\n" +
"s2-','->s3\n" + "s2-','->StarLoopEntry_8\n" +
"RuleStop_a_1-EOF->s16\n" + "RuleStop_a_1-EOF->s16\n" +
"s3->StarLoopEntry_8\n" +
"StarLoopEntry_8->StarBlockStart_6\n" + "StarLoopEntry_8->StarBlockStart_6\n" +
"StarLoopEntry_8->s9\n" + "StarLoopEntry_8->s9\n" +
"StarBlockStart_6->s4\n" + "StarBlockStart_6->s4\n" +
"s9->BlockEnd_12\n" + "s9->BlockEnd_12\n" +
"s4-ID->s5\n" + "s4-ID->BlockEnd_7\n" +
"BlockEnd_12->StarLoopBack_15\n" + "BlockEnd_12->StarLoopBack_15\n" +
"s5->BlockEnd_7\n" +
"StarLoopBack_15->StarLoopEntry_13\n" +
"BlockEnd_7->StarLoopBack_10\n" + "BlockEnd_7->StarLoopBack_10\n" +
"StarLoopBack_15->StarLoopEntry_13\n" +
"StarLoopBack_10->StarLoopEntry_8\n"; "StarLoopBack_10->StarLoopEntry_8\n";
checkRuleATN(g, "a", expecting); checkRuleATN(g, "a", expecting);
} }
@ -400,15 +393,12 @@ public class TestATNConstruction extends BaseTest {
"StarBlockStart_8->s2\n" + "StarBlockStart_8->s2\n" +
"StarBlockStart_8->s4\n" + "StarBlockStart_8->s4\n" +
"s11->RuleStop_a_1\n" + "s11->RuleStop_a_1\n" +
"s2-A->s3\n" + "s2-A->BlockEnd_9\n" +
"s4-B->s5\n" + "s4-B->s6\n" +
"RuleStop_a_1-EOF->s13\n" + "RuleStop_a_1-EOF->s13\n" +
"s3->BlockEnd_9\n" +
"s5->s6\n" +
"BlockEnd_9->StarLoopBack_12\n" + "BlockEnd_9->StarLoopBack_12\n" +
"s6-action_0:-1->s7\n" + "s6-action_0:-1->BlockEnd_9\n" +
"StarLoopBack_12->StarLoopEntry_10\n" + "StarLoopBack_12->StarLoopEntry_10\n";
"s7->BlockEnd_9\n";
checkRuleATN(g, "a", expecting); checkRuleATN(g, "a", expecting);
} }
@ -420,14 +410,10 @@ public class TestATNConstruction extends BaseTest {
"RuleStart_a_0->BlockStart_10\n" + "RuleStart_a_0->BlockStart_10\n" +
"BlockStart_10->s2\n" + "BlockStart_10->s2\n" +
"BlockStart_10->s6\n" + "BlockStart_10->s6\n" +
"s2-pred_0:0->s3\n" + "s2-pred_0:0->s4\n" +
"s6-pred_0:1->s7\n" + "s6-pred_0:1->s8\n" +
"s3->s4\n" + "s4-A->BlockEnd_11\n" +
"s7->s8\n" + "s8-B->BlockEnd_11\n" +
"s4-A->s5\n" +
"s8-B->s9\n" +
"s5->BlockEnd_11\n" +
"s9->BlockEnd_11\n" +
"BlockEnd_11->RuleStop_a_1\n" + "BlockEnd_11->RuleStop_a_1\n" +
"RuleStop_a_1-EOF->s12\n"; "RuleStop_a_1-EOF->s12\n";
checkRuleATN(g, "a", expecting); checkRuleATN(g, "a", expecting);

View File

@ -46,15 +46,13 @@ public class TestATNSerialization extends BaseTest {
"0:RULE_START 0\n" + "0:RULE_START 0\n" +
"1:RULE_STOP 0\n" + "1:RULE_STOP 0\n" +
"2:BASIC 0\n" + "2:BASIC 0\n" +
"3:BASIC 0\n" +
"4:BASIC 0\n" + "4:BASIC 0\n" +
"5:BASIC 0\n" + "5:BASIC 0\n" +
"6:BASIC 0\n" + "6:BASIC 0\n" +
"rule 0:0 0,0\n" + "rule 0:0 0,0\n" +
"0->2 EPSILON 0,0,0\n" + "0->2 EPSILON 0,0,0\n" +
"1->6 ATOM -1,0,0\n" + "1->6 ATOM -1,0,0\n" +
"2->3 ATOM 3,0,0\n" + "2->4 ATOM 3,0,0\n" +
"3->4 EPSILON 0,0,0\n" +
"4->5 ATOM 4,0,0\n" + "4->5 ATOM 4,0,0\n" +
"5->1 EPSILON 0,0,0\n"; "5->1 EPSILON 0,0,0\n";
ATN atn = createATN(g); ATN atn = createATN(g);
@ -71,15 +69,13 @@ public class TestATNSerialization extends BaseTest {
"0:RULE_START 0\n" + "0:RULE_START 0\n" +
"1:RULE_STOP 0\n" + "1:RULE_STOP 0\n" +
"2:BASIC 0\n" + "2:BASIC 0\n" +
"3:BASIC 0\n" +
"4:BASIC 0\n" + "4:BASIC 0\n" +
"5:BASIC 0\n" + "5:BASIC 0\n" +
"6:BASIC 0\n" + "6:BASIC 0\n" +
"rule 0:0 0,0\n" + "rule 0:0 0,0\n" +
"0->2 EPSILON 0,0,0\n" + "0->2 EPSILON 0,0,0\n" +
"1->6 ATOM -1,0,0\n" + "1->6 ATOM -1,0,0\n" +
"2->3 ATOM 3,0,0\n" + "2->4 ATOM 3,0,0\n" +
"3->4 EPSILON 0,0,0\n" +
"4->5 ATOM -1,0,0\n" + "4->5 ATOM -1,0,0\n" +
"5->1 EPSILON 0,0,0\n"; "5->1 EPSILON 0,0,0\n";
ATN atn = createATN(g); ATN atn = createATN(g);
@ -165,23 +161,17 @@ public class TestATNSerialization extends BaseTest {
"0:RULE_START 0\n" + "0:RULE_START 0\n" +
"1:RULE_STOP 0\n" + "1:RULE_STOP 0\n" +
"2:BASIC 0\n" + "2:BASIC 0\n" +
"3:BASIC 0\n" +
"4:BASIC 0\n" + "4:BASIC 0\n" +
"5:BASIC 0\n" +
"6:BASIC 0\n" + "6:BASIC 0\n" +
"7:BASIC 0\n" +
"8:BLOCK_START 0\n" + "8:BLOCK_START 0\n" +
"9:BLOCK_END 0\n" + "9:BLOCK_END 0\n" +
"10:BASIC 0\n" + "10:BASIC 0\n" +
"rule 0:0 0,0\n" + "rule 0:0 0,0\n" +
"0->8 EPSILON 0,0,0\n" + "0->8 EPSILON 0,0,0\n" +
"1->10 ATOM -1,0,0\n" + "1->10 ATOM -1,0,0\n" +
"2->3 ATOM 3,0,0\n" + "2->9 ATOM 3,0,0\n" +
"3->9 EPSILON 0,0,0\n" + "4->6 ATOM 3,0,0\n" +
"4->5 ATOM 3,0,0\n" + "6->9 ATOM 4,0,0\n" +
"5->6 EPSILON 0,0,0\n" +
"6->7 ATOM 4,0,0\n" +
"7->9 EPSILON 0,0,0\n" +
"8->2 EPSILON 0,0,0\n" + "8->2 EPSILON 0,0,0\n" +
"8->4 EPSILON 0,0,0\n" + "8->4 EPSILON 0,0,0\n" +
"9->1 EPSILON 0,0,0\n" + "9->1 EPSILON 0,0,0\n" +
@ -200,35 +190,23 @@ public class TestATNSerialization extends BaseTest {
"0:RULE_START 0\n" + "0:RULE_START 0\n" +
"1:RULE_STOP 0\n" + "1:RULE_STOP 0\n" +
"2:BASIC 0\n" + "2:BASIC 0\n" +
"3:BASIC 0\n" +
"4:BASIC 0\n" + "4:BASIC 0\n" +
"5:BASIC 0\n" +
"6:BASIC 0\n" + "6:BASIC 0\n" +
"7:BASIC 0\n" +
"8:BASIC 0\n" + "8:BASIC 0\n" +
"9:BASIC 0\n" +
"10:BASIC 0\n" + "10:BASIC 0\n" +
"11:BASIC 0\n" +
"12:BASIC 0\n" + "12:BASIC 0\n" +
"13:BASIC 0\n" +
"14:BLOCK_START 0\n" + "14:BLOCK_START 0\n" +
"15:BLOCK_END 0\n" + "15:BLOCK_END 0\n" +
"16:BASIC 0\n" + "16:BASIC 0\n" +
"rule 0:0 0,0\n" + "rule 0:0 0,0\n" +
"0->14 EPSILON 0,0,0\n" + "0->14 EPSILON 0,0,0\n" +
"1->16 ATOM -1,0,0\n" + "1->16 ATOM -1,0,0\n" +
"2->3 ATOM 3,0,0\n" + "2->15 ATOM 3,0,0\n" +
"3->15 EPSILON 0,0,0\n" + "4->6 ATOM 3,0,0\n" +
"4->5 ATOM 3,0,0\n" + "6->15 ATOM 4,0,0\n" +
"5->6 EPSILON 0,0,0\n" + "8->10 ATOM 3,0,0\n" +
"6->7 ATOM 4,0,0\n" + "10->12 ATOM 4,0,0\n" +
"7->15 EPSILON 0,0,0\n" + "12->15 ATOM 5,0,0\n" +
"8->9 ATOM 3,0,0\n" +
"9->10 EPSILON 0,0,0\n" +
"10->11 ATOM 4,0,0\n" +
"11->12 EPSILON 0,0,0\n" +
"12->13 ATOM 5,0,0\n" +
"13->15 EPSILON 0,0,0\n" +
"14->2 EPSILON 0,0,0\n" + "14->2 EPSILON 0,0,0\n" +
"14->4 EPSILON 0,0,0\n" + "14->4 EPSILON 0,0,0\n" +
"14->8 EPSILON 0,0,0\n" + "14->8 EPSILON 0,0,0\n" +
@ -248,7 +226,6 @@ public class TestATNSerialization extends BaseTest {
"0:RULE_START 0\n" + "0:RULE_START 0\n" +
"1:RULE_STOP 0\n" + "1:RULE_STOP 0\n" +
"2:BASIC 0\n" + "2:BASIC 0\n" +
"3:BASIC 0\n" +
"4:PLUS_BLOCK_START 0\n" + "4:PLUS_BLOCK_START 0\n" +
"5:BLOCK_END 0\n" + "5:BLOCK_END 0\n" +
"6:PLUS_LOOP_BACK 0\n" + "6:PLUS_LOOP_BACK 0\n" +
@ -259,8 +236,7 @@ public class TestATNSerialization extends BaseTest {
"rule 0:0 0,0\n" + "rule 0:0 0,0\n" +
"0->4 EPSILON 0,0,0\n" + "0->4 EPSILON 0,0,0\n" +
"1->10 ATOM -1,0,0\n" + "1->10 ATOM -1,0,0\n" +
"2->3 ATOM 3,0,0\n" + "2->5 ATOM 3,0,0\n" +
"3->5 EPSILON 0,0,0\n" +
"4->2 EPSILON 0,0,0\n" + "4->2 EPSILON 0,0,0\n" +
"5->6 EPSILON 0,0,0\n" + "5->6 EPSILON 0,0,0\n" +
"6->4 EPSILON 0,0,0\n" + "6->4 EPSILON 0,0,0\n" +
@ -371,15 +347,13 @@ public class TestATNSerialization extends BaseTest {
"1:RULE_START 0\n" + "1:RULE_START 0\n" +
"2:RULE_STOP 0\n" + "2:RULE_STOP 0\n" +
"3:BASIC 0\n" + "3:BASIC 0\n" +
"4:BASIC 0\n" +
"5:BASIC 0\n" + "5:BASIC 0\n" +
"6:BASIC 0\n" + "6:BASIC 0\n" +
"rule 0:1 3,-1\n" + "rule 0:1 3,-1\n" +
"mode 0:0\n" + "mode 0:0\n" +
"0->1 EPSILON 0,0,0\n" + "0->1 EPSILON 0,0,0\n" +
"1->3 EPSILON 0,0,0\n" + "1->3 EPSILON 0,0,0\n" +
"3->4 ATOM 97,0,0\n" + "3->5 ATOM 97,0,0\n" +
"4->5 EPSILON 0,0,0\n" +
"5->6 ATOM -1,0,0\n" + "5->6 ATOM -1,0,0\n" +
"6->2 EPSILON 0,0,0\n" + "6->2 EPSILON 0,0,0\n" +
"0:0 1\n"; "0:0 1\n";
@ -398,23 +372,17 @@ public class TestATNSerialization extends BaseTest {
"1:RULE_START 0\n" + "1:RULE_START 0\n" +
"2:RULE_STOP 0\n" + "2:RULE_STOP 0\n" +
"3:BASIC 0\n" + "3:BASIC 0\n" +
"4:BASIC 0\n" +
"5:BASIC 0\n" + "5:BASIC 0\n" +
"6:BASIC 0\n" +
"7:BASIC 0\n" + "7:BASIC 0\n" +
"8:BASIC 0\n" +
"9:BLOCK_START 0\n" + "9:BLOCK_START 0\n" +
"10:BLOCK_END 0\n" + "10:BLOCK_END 0\n" +
"rule 0:1 3,-1\n" + "rule 0:1 3,-1\n" +
"mode 0:0\n" + "mode 0:0\n" +
"0->1 EPSILON 0,0,0\n" + "0->1 EPSILON 0,0,0\n" +
"1->3 EPSILON 0,0,0\n" + "1->3 EPSILON 0,0,0\n" +
"3->4 ATOM 97,0,0\n" + "3->9 ATOM 97,0,0\n" +
"4->9 EPSILON 0,0,0\n" + "5->10 ATOM -1,0,0\n" +
"5->6 ATOM -1,0,0\n" + "7->10 ATOM 10,0,0\n" +
"6->10 EPSILON 0,0,0\n" +
"7->8 ATOM 10,0,0\n" +
"8->10 EPSILON 0,0,0\n" +
"9->5 EPSILON 0,0,0\n" + "9->5 EPSILON 0,0,0\n" +
"9->7 EPSILON 0,0,0\n" + "9->7 EPSILON 0,0,0\n" +
"10->2 EPSILON 0,0,0\n" + "10->2 EPSILON 0,0,0\n" +
@ -435,7 +403,6 @@ public class TestATNSerialization extends BaseTest {
"1:RULE_START 0\n" + "1:RULE_START 0\n" +
"2:RULE_STOP 0\n" + "2:RULE_STOP 0\n" +
"3:BASIC 0\n" + "3:BASIC 0\n" +
"4:BASIC 0\n" +
"5:PLUS_BLOCK_START 0\n" + "5:PLUS_BLOCK_START 0\n" +
"6:BLOCK_END 0\n" + "6:BLOCK_END 0\n" +
"7:PLUS_LOOP_BACK 0\n" + "7:PLUS_LOOP_BACK 0\n" +
@ -444,8 +411,7 @@ public class TestATNSerialization extends BaseTest {
"mode 0:0\n" + "mode 0:0\n" +
"0->1 EPSILON 0,0,0\n" + "0->1 EPSILON 0,0,0\n" +
"1->5 EPSILON 0,0,0\n" + "1->5 EPSILON 0,0,0\n" +
"3->4 RANGE 48,57,0\n" + "3->6 RANGE 48,57,0\n" +
"4->6 EPSILON 0,0,0\n" +
"5->3 EPSILON 0,0,0\n" + "5->3 EPSILON 0,0,0\n" +
"6->7 EPSILON 0,0,0\n" + "6->7 EPSILON 0,0,0\n" +
"7->5 EPSILON 0,0,0\n" + "7->5 EPSILON 0,0,0\n" +
@ -474,12 +440,10 @@ public class TestATNSerialization extends BaseTest {
"5:RULE_START 2\n" + "5:RULE_START 2\n" +
"6:RULE_STOP 2\n" + "6:RULE_STOP 2\n" +
"7:BASIC 0\n" + "7:BASIC 0\n" +
"8:BASIC 0\n" +
"9:BASIC 0\n" + "9:BASIC 0\n" +
"10:BASIC 1\n" + "10:BASIC 1\n" +
"11:BASIC 1\n" + "11:BASIC 1\n" +
"12:BASIC 2\n" + "12:BASIC 2\n" +
"13:BASIC 2\n" +
"14:BASIC 2\n" + "14:BASIC 2\n" +
"rule 0:1 3,0\n" + "rule 0:1 3,0\n" +
"rule 1:3 4,-1\n" + "rule 1:3 4,-1\n" +
@ -491,13 +455,11 @@ public class TestATNSerialization extends BaseTest {
"1->7 EPSILON 0,0,0\n" + "1->7 EPSILON 0,0,0\n" +
"3->10 EPSILON 0,0,0\n" + "3->10 EPSILON 0,0,0\n" +
"5->12 EPSILON 0,0,0\n" + "5->12 EPSILON 0,0,0\n" +
"7->8 ATOM 97,0,0\n" + "7->9 ATOM 97,0,0\n" +
"8->9 EPSILON 0,0,0\n" +
"9->2 EPSILON 0,0,0\n" + "9->2 EPSILON 0,0,0\n" +
"10->11 ATOM 98,0,0\n" + "10->11 ATOM 98,0,0\n" +
"11->4 EPSILON 0,0,0\n" + "11->4 EPSILON 0,0,0\n" +
"12->13 ATOM 99,0,0\n" + "12->14 ATOM 99,0,0\n" +
"13->14 EPSILON 0,0,0\n" +
"14->6 EPSILON 0,0,0\n" + "14->6 EPSILON 0,0,0\n" +
"0:0 1\n"; "0:0 1\n";
ATN atn = createATN(lg); ATN atn = createATN(lg);
@ -595,7 +557,6 @@ public class TestATNSerialization extends BaseTest {
"6:RULE_START 2\n" + "6:RULE_START 2\n" +
"7:RULE_STOP 2\n" + "7:RULE_STOP 2\n" +
"8:BASIC 0\n" + "8:BASIC 0\n" +
"9:BASIC 0\n" +
"10:PLUS_BLOCK_START 0\n" + "10:PLUS_BLOCK_START 0\n" +
"11:BLOCK_END 0\n" + "11:BLOCK_END 0\n" +
"12:PLUS_LOOP_BACK 0\n" + "12:PLUS_LOOP_BACK 0\n" +
@ -605,7 +566,6 @@ public class TestATNSerialization extends BaseTest {
"16:BASIC 1\n" + "16:BASIC 1\n" +
"17:BASIC 1\n" + "17:BASIC 1\n" +
"18:BASIC 2\n" + "18:BASIC 2\n" +
"19:BASIC 2\n" +
"20:BASIC 2\n" + "20:BASIC 2\n" +
"rule 0:2 3,-1\n" + "rule 0:2 3,-1\n" +
"rule 1:4 4,0\n" + "rule 1:4 4,0\n" +
@ -618,8 +578,7 @@ public class TestATNSerialization extends BaseTest {
"2->10 EPSILON 0,0,0\n" + "2->10 EPSILON 0,0,0\n" +
"4->14 EPSILON 0,0,0\n" + "4->14 EPSILON 0,0,0\n" +
"6->18 EPSILON 0,0,0\n" + "6->18 EPSILON 0,0,0\n" +
"8->9 RANGE 97,122,0\n" + "8->11 RANGE 97,122,0\n" +
"9->11 EPSILON 0,0,0\n" +
"10->8 EPSILON 0,0,0\n" + "10->8 EPSILON 0,0,0\n" +
"11->12 EPSILON 0,0,0\n" + "11->12 EPSILON 0,0,0\n" +
"12->10 EPSILON 0,0,0\n" + "12->10 EPSILON 0,0,0\n" +
@ -629,8 +588,7 @@ public class TestATNSerialization extends BaseTest {
"15->16 ATOM 47,0,0\n" + "15->16 ATOM 47,0,0\n" +
"16->17 EPSILON 0,0,0\n" + "16->17 EPSILON 0,0,0\n" +
"17->5 EPSILON 0,0,0\n" + "17->5 EPSILON 0,0,0\n" +
"18->19 WILDCARD 0,0,0\n" + "18->20 WILDCARD 0,0,0\n" +
"19->20 EPSILON 0,0,0\n" +
"20->7 EPSILON 0,0,0\n" + "20->7 EPSILON 0,0,0\n" +
"0:0 1\n" + "0:0 1\n" +
"1:1 1\n" + "1:1 1\n" +
@ -650,7 +608,6 @@ public class TestATNSerialization extends BaseTest {
"1:RULE_START 0\n" + "1:RULE_START 0\n" +
"2:RULE_STOP 0\n" + "2:RULE_STOP 0\n" +
"3:BASIC 0\n" + "3:BASIC 0\n" +
"4:BASIC 0\n" +
"5:BASIC 0\n" + "5:BASIC 0\n" +
"6:BASIC 0\n" + "6:BASIC 0\n" +
"rule 0:1 3,-1\n" + "rule 0:1 3,-1\n" +
@ -659,8 +616,7 @@ public class TestATNSerialization extends BaseTest {
"1:'e'..'e', 'p'..'t'\n" + "1:'e'..'e', 'p'..'t'\n" +
"0->1 EPSILON 0,0,0\n" + "0->1 EPSILON 0,0,0\n" +
"1->3 EPSILON 0,0,0\n" + "1->3 EPSILON 0,0,0\n" +
"3->4 NOT_SET 0,0,0\n" + "3->5 NOT_SET 0,0,0\n" +
"4->5 EPSILON 0,0,0\n" +
"5->6 NOT_SET 1,0,0\n" + "5->6 NOT_SET 1,0,0\n" +
"6->2 EPSILON 0,0,0\n" + "6->2 EPSILON 0,0,0\n" +
"0:0 1\n"; "0:0 1\n";