forked from jasder/antlr
Add ATN representation for non-greedy decisions
This commit is contained in:
parent
9ea072aee0
commit
0d30a7a60b
|
@ -262,9 +262,11 @@ public abstract class ATNSimulator {
|
||||||
int ndecisions = toInt(data[p++]);
|
int ndecisions = toInt(data[p++]);
|
||||||
for (int i=1; i<=ndecisions; i++) {
|
for (int i=1; i<=ndecisions; i++) {
|
||||||
int s = toInt(data[p++]);
|
int s = toInt(data[p++]);
|
||||||
|
int nonGreedy = toInt(data[p++]);
|
||||||
DecisionState decState = (DecisionState)atn.states.get(s);
|
DecisionState decState = (DecisionState)atn.states.get(s);
|
||||||
atn.decisionToState.add(decState);
|
atn.decisionToState.add(decState);
|
||||||
decState.decision = i-1;
|
decState.decision = i-1;
|
||||||
|
decState.nonGreedy = nonGreedy != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
verifyATN(atn);
|
verifyATN(atn);
|
||||||
|
|
|
@ -31,4 +31,5 @@ package org.antlr.v4.runtime.atn;
|
||||||
|
|
||||||
public class DecisionState extends ATNState {
|
public class DecisionState extends ATNState {
|
||||||
public int decision = -1;
|
public int decision = -1;
|
||||||
|
public boolean nonGreedy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,6 +226,7 @@ public class ATNSerializer {
|
||||||
data.add(ndecisions);
|
data.add(ndecisions);
|
||||||
for (DecisionState decStartState : atn.decisionToState) {
|
for (DecisionState decStartState : atn.decisionToState) {
|
||||||
data.add(decStartState.stateNumber);
|
data.add(decStartState.stateNumber);
|
||||||
|
data.add(decStartState.nonGreedy ? 1 : 0);
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -299,6 +300,7 @@ public class ATNSerializer {
|
||||||
int ndecisions = ATNSimulator.toInt(data[p++]);
|
int ndecisions = ATNSimulator.toInt(data[p++]);
|
||||||
for (int i=1; i<=ndecisions; i++) {
|
for (int i=1; i<=ndecisions; i++) {
|
||||||
int s = ATNSimulator.toInt(data[p++]);
|
int s = ATNSimulator.toInt(data[p++]);
|
||||||
|
boolean nonGreedy = ATNSimulator.toInt(data[p++]) != 0;
|
||||||
buf.append(i-1).append(":").append(s).append("\n");
|
buf.append(i-1).append(":").append(s).append("\n");
|
||||||
}
|
}
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
|
|
|
@ -425,10 +425,11 @@ public class ParserATNFactory implements ATNFactory {
|
||||||
BlockStartState blkStart = (BlockStartState)blk.left;
|
BlockStartState blkStart = (BlockStartState)blk.left;
|
||||||
|
|
||||||
BlockAST blkAST = (BlockAST)optAST.getChild(0);
|
BlockAST blkAST = (BlockAST)optAST.getChild(0);
|
||||||
if (isGreedy(blkAST)) {
|
blkStart.nonGreedy = !isGreedy(blkAST);
|
||||||
|
|
||||||
|
if (!blkStart.nonGreedy) {
|
||||||
epsilon(blkStart, blk.right);
|
epsilon(blkStart, blk.right);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Transition existing = blkStart.removeTransition(0);
|
Transition existing = blkStart.removeTransition(0);
|
||||||
epsilon(blkStart, blk.right);
|
epsilon(blkStart, blk.right);
|
||||||
blkStart.addTransition(existing);
|
blkStart.addTransition(existing);
|
||||||
|
@ -463,7 +464,8 @@ public class ParserATNFactory implements ATNFactory {
|
||||||
epsilon(blkEnd, loop); // blk can see loop back
|
epsilon(blkEnd, loop); // blk can see loop back
|
||||||
|
|
||||||
BlockAST blkAST = (BlockAST)plusAST.getChild(0);
|
BlockAST blkAST = (BlockAST)plusAST.getChild(0);
|
||||||
if ( isGreedy(blkAST) ) {
|
loop.nonGreedy = !isGreedy(blkAST);
|
||||||
|
if ( !loop.nonGreedy ) {
|
||||||
epsilon(loop, blkStart); // loop back to start
|
epsilon(loop, blkStart); // loop back to start
|
||||||
epsilon(loop, end); // or exit
|
epsilon(loop, end); // or exit
|
||||||
}
|
}
|
||||||
|
@ -502,7 +504,8 @@ public class ParserATNFactory implements ATNFactory {
|
||||||
end.loopBackState = loop;
|
end.loopBackState = loop;
|
||||||
|
|
||||||
BlockAST blkAST = (BlockAST)starAST.getChild(0);
|
BlockAST blkAST = (BlockAST)starAST.getChild(0);
|
||||||
if ( isGreedy(blkAST) ) {
|
entry.nonGreedy = !isGreedy(blkAST);
|
||||||
|
if ( !entry.nonGreedy ) {
|
||||||
epsilon(entry, blkStart); // loop enter edge (alt 1)
|
epsilon(entry, blkStart); // loop enter edge (alt 1)
|
||||||
epsilon(entry, end); // bypass loop edge (alt 2)
|
epsilon(entry, end); // bypass loop edge (alt 2)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue