lexer function
Implementation
List<LexToken> lexer(String str) {
final List<LexToken> tokens = [];
int i = 0;
while (i < str.length) {
final char = str[i];
if (char == '*' || char == '+' || char == '?') {
tokens.add(
LexToken(type: LexTokenType.MODIFIER, index: i, value: str[i++]));
continue;
}
if (char == '\\') {
tokens.add(
LexToken(type: LexTokenType.ESCAPED_CHAR, index: i, value: str[i++]));
continue;
}
if (char == '{') {
tokens.add(LexToken(type: LexTokenType.OPEN, index: i, value: str[i++]));
continue;
}
if (char == '}') {
tokens.add(LexToken(type: LexTokenType.CLOSE, index: i, value: str[i++]));
continue;
}
if (char == ':') {
String name = '';
int j = i + 1;
while (j < str.length) {
final code = str.codeUnitAt(j);
if (
// '0-9'
(code >= 48 && code <= 57) ||
// 'A-Z'
(code >= 65 && code <= 90) ||
// 'a-z'
(code >= 97 && code <= 122) ||
// '_'
code == 95) {
name += str[j++];
continue;
}
break;
}
if (['', null].contains(name)) {
// 'Missing parameter name at $i')
throw TypeError();
}
tokens.add(LexToken(type: LexTokenType.NAME, index: i, value: name));
i = j;
continue;
}
if (char == '(') {
int count = 1;
String pattern = '';
int j = i + 1;
if (str[j] == '?') {
// 'Pattern cannot start with "?" at ${j}'
throw TypeError();
}
while (j < str.length) {
if (str[j] == '\\') {
pattern += str[j++] + str[j++];
continue;
}
if (str[j] == ')') {
count--;
if (count == 0) {
j++;
break;
}
} else if (str[j] == '(') {
count++;
if (str[j + 1] != '?') {
// 'Capturing groups are not allowed at ${j}'
throw TypeError();
}
}
pattern += str[j++];
}
if (count != 0) {
// 'Unbalanced pattern at ${i}'
throw TypeError();
}
// 'Missing pattern at ${i}'
if ([null, ''].contains(pattern)) {
throw TypeError();
}
tokens
.add(LexToken(type: LexTokenType.PATTERN, index: i, value: pattern));
i = j;
continue;
}
tokens.add(LexToken(type: LexTokenType.CHAR, index: i, value: str[i++]));
}
tokens.add(LexToken(type: LexTokenType.END, index: i, value: ''));
return tokens;
}