Token Parser
一个直观的 Token Parser,包含语法/文法定义、词法分析和语法分析。
特点
- 词法分析
- 解析
- 语法/文法定义
入门
dart pub add token_parser
并导入该包
import 'package:token_parser/token_parser.dart';
用法
词法分析过程分为三个步骤
- 语法/文法定义
- 词法分析
- 解析
下面将简要介绍每个步骤。
语法/文法定义
语法/文法定义是通过定义每个 token 必须具有的属性来完成的。
token 代表一个表达式,然后可以在其他 token 中使用它来构成一个文法。
final abc = 'a' | 'b' | 'c';
final def = 'd' | 'e' | 'f';
final expression = abc & def;
使用 & 运算符将 token 组合为“与”关系,使用 | 运算符将 token 组合为“或”关系,我们可以定义一个可以接受 token abc 和 def 的任意组合的表达式。
token 可以扩展以具有略微不同的属性
final abc = ('a' | 'b' | 'c').multiple;
final expression = abc & 'd'.optional;
为了方便起见,可以使用正则表达式定义 token
final digit = '[0-9]'.regex;
final number = digit.multiple & ('.' & digit.multiple).optional;
final letter = '[a-zA-Z]'.regex;
final word = letter.multiple;
final phrase = word & ((' ' & word).multiple).optional;
词法分析
任何 token
解析
final abc = 'a' | 'b' | 'c' | Token.reference('def');
final def = ('d' | 'e' | 'f') & Token.self();
final parser = TokenParser(
main: phrase | number,
token: {
'digit': digit,
'number': number,
'letter': letter,
'word': word,
'phrase': phrase,
'abc': 'a' | 'b' | 'c',
'def': 'd' | 'e' | 'f',
},
);
final parser = TokenParser();
parser.add('digit', digit);
parser.add( ... );
parser.addMain(phrase | number);
parser.parse('123');
parser.parse('123.456');
parser.parse('word');
parser.parse('two words');
final match = parser.parse('two words');
final words = match?.get(word);
final letters = match?.get(letter);
print('Words: ${ words?.map((match) => match.value) }');
print('Letters: ${ letters?.get(letter).map((match) => match.value) }');
match.childrenmatch.get(token)match.getNamed('name')
示例
词法分析 (example/main.dart)
import 'package:token_parser/token_parser.dart';
void main() {
final whitespace = ' ' | '\t';
final lineBreak = '\n' | '\r';
final space = (whitespace | lineBreak).multiple;
final letter = '[a-zA-Z]'.regex;
final digit = '[0-9]'.regex;
final identifier = letter & (letter | digit).multiple.optional;
final number = digit.multiple & ('.' & digit.multiple).optional;
final string = '"' & '[^"]*'.regex & '"'
| "'" & "[^']*".regex & "'";
final variableDeclaration =
'var' & space & identifier & space.optional & '=' & space.optional & (number | string) & space.optional & (';' | space);
final parser = TokenParser(
main: (variableDeclaration | space).multiple,
tokens: {
'whitespace': whitespace,
'lineBreak': lineBreak,
'space': space,
'letter': letter,
'digit': digit,
'identifier': identifier,
'number': number,
'string': string,
'variableDeclaration': variableDeclaration,
},
);
final match = parser.parse('''
var hello = "world";
var foo = 123;
var bar = 123.456;
''');
final numbers = match?.get(number).map((match) => match.group(0));
final identifiers = match?.get(identifier).map((match) => '"${ match.group(0) }"');
print('Numbers: $numbers');
print('Identifiers: $identifiers');
}
引用 (example/reference.dart)
import 'package:token_parser/token_parser.dart';
void main() {
final expression = 'a' & Token.reference('characterB').optional;
final characterB = 'b'.token();
final recursive = 'a' & Token.self().optional;
final parser = TokenParser(
main: expression,
tokens: {
'expression': expression,
'characterB': characterB,
'recursive': recursive,
}
);
print(parser.parse('ab')?.get(characterB));
print(parser.parse('aaa', recursive)?.get(recursive));
}