visitOrderedChoice<E> method
Implementation
@override
Parser visitOrderedChoice<E>(OrderedChoiceExpression<E> node) {
final expressions = node.expressions;
if (expressions.length == 1) {
final child = expressions.first;
return child.accept(this);
}
if (!options.predict) {
final parsers = <Parser<E>>[];
for (var i = 0; i < expressions.length; i++) {
final child = expressions[i];
final parser = child.accept(this) as Parser<E>;
parsers.add(parser);
}
return OrderedChoiceParser<E>(parsers);
}
final states = <List<int>>[];
final stateCharacters = <SparseBoolList>[];
_computeTransitions(expressions, states, stateCharacters);
final temp = SparseList<List<int>>();
for (var i = 0; i < states.length; i++) {
final foo = states[i];
for (final src in stateCharacters[i].groups) {
final allSpace = temp.getAllSpace(src);
for (final dest in allSpace) {
var key = dest.key;
key ??= [];
for (var j = 0; j < foo.length; j++) {
final state = foo[j];
if (!key.contains(state)) {
key.add(state);
}
}
final group = GroupedRangeList<List<int>>(dest.start, dest.end, key);
temp.addGroup(group);
}
}
}
final ranges = Uint32List(temp.groupCount * 2);
final transitions = <List<int>>[];
var index = 0;
for (final group in temp.groups) {
ranges[index++] = group.start;
ranges[index++] = group.end;
transitions.add(group.key);
}
Expression getHead(Expression expression) {
if (expression is SequenceExpression) {
final expressions = expression.expressions;
final first = expressions.first;
return getHead(first);
} else if (expression is OrderedChoiceExpression) {
final expressions = expression.expressions;
if (expressions.length == 1) {
final first = expressions.first;
return getHead(first);
}
} else if (expression is TransformerExpression) {
final child = expression.expression;
return getHead(child);
} else if (expression is LocationalTransformerExpression) {
final child = expression.expression;
return getHead(child);
} else if (expression is SymbolExpression) {
final child = expression.expression;
return getHead(child);
} else if (expression is CaptureExpression) {
final child = expression.expression;
return getHead(child);
}
return expression;
}
final parsers = <Parser<E>>[];
for (var i = 0; i < expressions.length; i++) {
final child = expressions[i];
final head = getHead(child);
final rule = head.rule!;
if (rule.directCallers.length == 1) {
heads.add(head);
}
final parser = child.accept(this) as Parser<E>;
parsers.add(parser);
}
return PredictiveOrderedChoiceParser<E>(parsers, ranges, transitions,
source: '$node');
}