parse function

List parse(
  1. String str, {
  2. String? delimiter,
  3. String prefixes = './',
})

Implementation

List<Token> parse(
  String str, {
  String? delimiter,
  String prefixes = './',
}) {
  final tokens = lexer(str);
  final defaultPattern = "[^${escapeString(delimiter ?? '/#?')}]+?";
  final List<Token> result = [];

  int key = 0;
  int i = 0;
  String? path = '';

  String? tryConsume(LexTokenType type) {
    if (i < tokens.length && tokens[i].type == type) {
      return tokens[i++].value;
    }
  }

  String? mustConsume(LexTokenType type) {
    final a = tokens[i];
    final value = tryConsume(type);
    if (value != null) {
      return value;
    }
    // nextType = tokens[i].type;
    // index = tokens[i].index;
    // 'Unexpected ${nextType} at ${index}, expected ${type}'
    throw TypeError();
  }

  String consumeText() {
    String result = '';
    String? value;
    // tslint:disable-next-line
    while (true) {
      value = tryConsume(LexTokenType.CHAR) ??
          tryConsume(LexTokenType.ESCAPED_CHAR);
      if (value == null) {
        break;
      }
      result += value;
    }
    return result;
  }

  while (i < tokens.length) {
    final char = tryConsume(LexTokenType.CHAR);
    final name = tryConsume(LexTokenType.NAME);
    final pattern = tryConsume(LexTokenType.PATTERN);

    if (name != null || pattern != null) {
      String? prefix = char ?? '';

      if (!prefixes.split('').contains(prefix)) {
        path = '$path$prefix';
        prefix = '';
      }

      if (path != null) {
        result.add(path);
        path = '';
      }

      result.add(Key(
          name: name ?? key++,
          prefix: prefix,
          suffix: '',
          pattern: pattern ?? defaultPattern,
          modifier: tryConsume(LexTokenType.MODIFIER) ?? ''));

      continue;
    }

    final value = char ?? tryConsume(LexTokenType.ESCAPED_CHAR);
    if (value != null) {
      path = '$path$value';
      continue;
    }

    if (path != null) {
      result.add(path);
      path = '';
    }

    final open = tryConsume(LexTokenType.OPEN);
    if (open != null) {
      final prefix = consumeText();
      final name = tryConsume(LexTokenType.NAME);
      final pattern = tryConsume(LexTokenType.PATTERN);
      final suffix = consumeText();

      mustConsume(LexTokenType.CLOSE);

      result.add(Key(
          name: name ?? (pattern != null ? key++ : ''),
          pattern: name != null && pattern == null ? defaultPattern : pattern!,
          prefix: prefix,
          suffix: suffix,
          modifier: tryConsume(LexTokenType.MODIFIER) ?? ''));

      continue;
    }

    mustConsume(LexTokenType.END);
  }

  return result;
}