use of org.antlr.v4.codegen.model.MatchSet in project antlr4 by antlr.
the class ATNOptimizer method optimizeSets.
private static void optimizeSets(Grammar g, ATN atn) {
if (g.isParser()) {
// parser codegen doesn't currently support SetTransition
return;
}
int removedStates = 0;
List<DecisionState> decisions = atn.decisionToState;
for (DecisionState decision : decisions) {
if (decision.ruleIndex >= 0) {
Rule rule = g.getRule(decision.ruleIndex);
if (Character.isLowerCase(rule.name.charAt(0))) {
// parser codegen doesn't currently support SetTransition
continue;
}
}
IntervalSet setTransitions = new IntervalSet();
for (int i = 0; i < decision.getNumberOfTransitions(); i++) {
Transition epsTransition = decision.transition(i);
if (!(epsTransition instanceof EpsilonTransition)) {
continue;
}
if (epsTransition.target.getNumberOfTransitions() != 1) {
continue;
}
Transition transition = epsTransition.target.transition(0);
if (!(transition.target instanceof BlockEndState)) {
continue;
}
if (transition instanceof NotSetTransition) {
// TODO: not yet implemented
continue;
}
if (transition instanceof AtomTransition || transition instanceof RangeTransition || transition instanceof SetTransition) {
setTransitions.add(i);
}
}
// due to min alt resolution policies, can only collapse sequential alts
for (int i = setTransitions.getIntervals().size() - 1; i >= 0; i--) {
Interval interval = setTransitions.getIntervals().get(i);
if (interval.length() <= 1) {
continue;
}
ATNState blockEndState = decision.transition(interval.a).target.transition(0).target;
IntervalSet matchSet = new IntervalSet();
for (int j = interval.a; j <= interval.b; j++) {
Transition matchTransition = decision.transition(j).target.transition(0);
if (matchTransition instanceof NotSetTransition) {
throw new UnsupportedOperationException("Not yet implemented.");
}
IntervalSet set = matchTransition.label();
List<Interval> intervals = set.getIntervals();
int n = intervals.size();
for (int k = 0; k < n; k++) {
Interval setInterval = intervals.get(k);
int a = setInterval.a;
int b = setInterval.b;
if (a != -1 && b != -1) {
for (int v = a; v <= b; v++) {
if (matchSet.contains(v)) {
// TODO: Token is missing (i.e. position in source will not be displayed).
g.tool.errMgr.grammarError(ErrorType.CHARACTERS_COLLISION_IN_SET, g.fileName, null, CharSupport.getANTLRCharLiteralForChar(v), CharSupport.getIntervalSetEscapedString(matchSet));
break;
}
}
}
}
matchSet.addAll(set);
}
Transition newTransition;
if (matchSet.getIntervals().size() == 1) {
if (matchSet.size() == 1) {
newTransition = CodePointTransitions.createWithCodePoint(blockEndState, matchSet.getMinElement());
} else {
Interval matchInterval = matchSet.getIntervals().get(0);
newTransition = CodePointTransitions.createWithCodePointRange(blockEndState, matchInterval.a, matchInterval.b);
}
} else {
newTransition = new SetTransition(blockEndState, matchSet);
}
decision.transition(interval.a).target.setTransition(0, newTransition);
for (int j = interval.a + 1; j <= interval.b; j++) {
Transition removed = decision.removeTransition(interval.a + 1);
atn.removeState(removed.target);
removedStates++;
}
}
}
// System.out.println("ATN optimizer removed " + removedStates + " states by collapsing sets.");
}
use of org.antlr.v4.codegen.model.MatchSet in project antlr4 by antlr.
the class ParserFactory method set.
@Override
public List<SrcOp> set(GrammarAST setAST, GrammarAST labelAST, boolean invert) {
MatchSet matchOp;
if (invert)
matchOp = new MatchNotSet(this, setAST);
else
matchOp = new MatchSet(this, setAST);
if (labelAST != null) {
String label = labelAST.getText();
RuleFunction rf = getCurrentRuleFunction();
if (labelAST.parent.getType() == ANTLRParser.PLUS_ASSIGN) {
defineImplicitLabel(setAST, matchOp);
TokenListDecl l = getTokenListLabelDecl(label);
rf.addContextDecl(setAST.getAltLabel(), l);
} else {
Decl d = getTokenLabelDecl(label);
matchOp.labels.add(d);
rf.addContextDecl(setAST.getAltLabel(), d);
}
}
if (controller.needsImplicitLabel(setAST, matchOp))
defineImplicitLabel(setAST, matchOp);
AddToLabelList listLabelOp = getAddToListOpIfListLabelPresent(matchOp, labelAST);
return list(matchOp, listLabelOp);
}
Aggregations