diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/ATNState.java b/runtime/Java/src/org/antlr/v4/runtime/atn/ATNState.java index aaf5dbd31..412c3321b 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/ATNState.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/ATNState.java @@ -179,6 +179,10 @@ public abstract class ATNState { } public void addTransition(Transition e) { + addTransition(transitions.size(), e); + } + + public void addTransition(int index, Transition e) { if (transitions.isEmpty()) { epsilonOnlyTransitions = e.isEpsilon(); } @@ -187,7 +191,7 @@ public abstract class ATNState { epsilonOnlyTransitions = false; } - transitions.add(e); + transitions.add(index, e); } public Transition transition(int i) { return transitions.get(i); } diff --git a/tool/src/org/antlr/v4/automata/ParserATNFactory.java b/tool/src/org/antlr/v4/automata/ParserATNFactory.java index c9196b897..b1589d6da 100644 --- a/tool/src/org/antlr/v4/automata/ParserATNFactory.java +++ b/tool/src/org/antlr/v4/automata/ParserATNFactory.java @@ -467,14 +467,9 @@ public class ParserATNFactory implements ATNFactory { public Handle optional(@NotNull GrammarAST optAST, @NotNull Handle blk) { BlockStartState blkStart = (BlockStartState)blk.left; - blkStart.nonGreedy = !((QuantifierAST)optAST).isGreedy(); - if (((QuantifierAST)optAST).isGreedy()) { - epsilon(blkStart, blk.right); - } else { - Transition existing = blkStart.removeTransition(0); - epsilon(blkStart, blk.right); - blkStart.addTransition(existing); - } + boolean greedy = ((QuantifierAST)optAST).isGreedy(); + blkStart.nonGreedy = !greedy; + epsilon(blkStart, blk.right, !greedy); optAST.atnState = blk.left; return blk; @@ -587,8 +582,15 @@ public class ParserATNFactory implements ATNFactory { return new Handle(left, right); } - void epsilon(ATNState a, @NotNull ATNState b) { - if ( a!=null ) a.addTransition(new EpsilonTransition(b)); + protected void epsilon(ATNState a, @NotNull ATNState b) { + epsilon(a, b, false); + } + + protected void epsilon(ATNState a, @NotNull ATNState b, boolean prepend) { + if ( a!=null ) { + int index = prepend ? 0 : a.getNumberOfTransitions(); + a.addTransition(index, new EpsilonTransition(b)); + } } /** Define all the rule begin/end ATNStates to solve forward reference