visitOrderedChoice<E> method

  1. @override
Parser visitOrderedChoice<E>(
  1. OrderedChoiceExpression<E> node
)
override

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