Merge pull request #285 from sharwell/non-greedy-optional

Fix ATN created for non-greedy optional block with multiple alternatives
This commit is contained in:
Sam Harwell 2013-06-24 10:01:40 -07:00
commit e575dc40e3
2 changed files with 17 additions and 11 deletions

View File

@ -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); }

View File

@ -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