visitCharacterClass method

  1. @override
Parser visitCharacterClass(
  1. CharacterClassExpression node
)
override

Implementation

@override
Parser visitCharacterClass(CharacterClassExpression node) {
  final source = '$node';
  final ranges = node.ranges;
  final groups = ranges.groups;
  if (groups.length == 1) {
    final group = groups.first;
    final start = group.start;
    final end = group.end;
    if (start == end) {
      if (heads.contains(node)) {
        return CheckedCharacterParser(start, source: source);
      } else {
        return CharacterParser(start, source: source);
      }
    }

    final list = Uint32List(2);
    list[0] = start;
    list[1] = end;
    if (heads.contains(node)) {
      return CheckedRangesParser(list, source: source);
    } else {
      return RangesParser(list, source: source);
    }
  } else {
    var count = 0;
    for (final group in groups) {
      final start = group.start;
      final end = group.end;
      count += end - start;
    }

    if (count <= 8) {
      final chars = <int>[];
      for (final group in groups) {
        final start = group.start;
        final end = group.end;
        if (start == end) {
          chars.add(start);
        } else {
          for (var i = start; i <= end; i++) {
            chars.add(i);
          }
        }
      }

      final list = Uint32List(chars.length);
      for (var i = 0; i < chars.length; i++) {
        list[i] = chars[i];
      }

      if (heads.contains(node)) {
        return CheckedCharactersParser(list, source: source);
      } else {
        return CharactersParser(list, source: source);
      }
    }

    final ranges = <int>[];
    for (final group in groups) {
      final start = group.start;
      final end = group.end;
      ranges.add(start);
      ranges.add(end);
    }

    final list = Uint32List(ranges.length);
    for (var i = 0; i < ranges.length; i++) {
      list[i] = ranges[i];
    }

    if (heads.contains(node)) {
      return CheckedRangesParser(list, source: source);
    } else {
      return RangesParser(list, source: source);
    }
  }
}