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) { public void addTransition(Transition e) {
addTransition(transitions.size(), e);
}
public void addTransition(int index, Transition e) {
if (transitions.isEmpty()) { if (transitions.isEmpty()) {
epsilonOnlyTransitions = e.isEpsilon(); epsilonOnlyTransitions = e.isEpsilon();
} }
@ -187,7 +191,7 @@ public abstract class ATNState {
epsilonOnlyTransitions = false; epsilonOnlyTransitions = false;
} }
transitions.add(e); transitions.add(index, e);
} }
public Transition transition(int i) { return transitions.get(i); } 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) { public Handle optional(@NotNull GrammarAST optAST, @NotNull Handle blk) {
BlockStartState blkStart = (BlockStartState)blk.left; BlockStartState blkStart = (BlockStartState)blk.left;
blkStart.nonGreedy = !((QuantifierAST)optAST).isGreedy(); boolean greedy = ((QuantifierAST)optAST).isGreedy();
if (((QuantifierAST)optAST).isGreedy()) { blkStart.nonGreedy = !greedy;
epsilon(blkStart, blk.right); epsilon(blkStart, blk.right, !greedy);
} else {
Transition existing = blkStart.removeTransition(0);
epsilon(blkStart, blk.right);
blkStart.addTransition(existing);
}
optAST.atnState = blk.left; optAST.atnState = blk.left;
return blk; return blk;
@ -587,8 +582,15 @@ public class ParserATNFactory implements ATNFactory {
return new Handle(left, right); return new Handle(left, right);
} }
void epsilon(ATNState a, @NotNull ATNState b) { protected void epsilon(ATNState a, @NotNull ATNState b) {
if ( a!=null ) a.addTransition(new EpsilonTransition(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 /** Define all the rule begin/end ATNStates to solve forward reference