2 个不稳定版本
使用旧的 Rust 2015
| 0.2.0 | 2018年12月4日 |
|---|---|
| 0.1.0 | 2018年5月31日 |
#2372 in 解析器实现
用于 polonius
8KB
250 行
Polonius 解析器
Polonius 解析器是一个小型、手动编写的解析器,用于解析来自 rustc 的 非 测试用例
// program description
placeholders { 'a, 'b, 'c }
// block description
block B0 {
// 0:
loan_invalidated_at(L0);
// 1:
loan_killed_at(L2);
loan_invalidated_at(L1) / use('a, 'b);
// CFG
goto B1, B2;
}
block B1 {
use('a), outlives('a: 'b), loan_issued_at('b, L1);
}
用法
polonius_parser 链接库提供了一个名为 parse_input 的单函数,它将程序描述作为输入字符串。输入将被成功解析为 ir::Input,或者返回一个 ParseError。ir 结构体是一个小型、公开的数据模型。
架构
polonius_parser 被实现为一个 Lexer,它是一个 Iterator,从源文本中提取 Token,以及一个 Parser,它对这些 Tokens 进行操作。解析器是一个简单的递归下降解析器,具有 1 个令牌的预览(使用 Peekable)。我们使用 T! 宏在整个实现中快速且清晰地引用令牌类型。
添加事实
为了将解析器扩展为新的 loan_bazzles_var_at 事实,执行以下更改
- 向
TokenKind添加一个新的变体KwLoanBazzlesVarAt,用于loan_bazzles_var_at关键字(token.rs)。 - 将关键字的缩写添加到
T!宏中,并将新的关键字类型添加到TokenKind的Display实现。 - 为任何引入的新语法添加额外的令牌,例如,如果关系表示为
L1 $ V1,添加$。 - 在
Lexer::valid_token(lexer.rs)中添加一个情况kw if kw.starts_with("loan_bazzles_var_at".as_bytes()) => { ("loan_bazzles_var_at".len() as u32, T![loan_bazzles_var_at]) } - 对于额外的令牌类型,根据需要添加情况。在我们的示例中,添加以下内容:
[b'$', ..] => (1, T![$]), - 在
ir数据模型中将Fact枚举添加一个变体来表示新的事实。对我们来说,是这样:LoanBazzlesVarAt { loan: String, variable: String }, - 在
Parser::parse_fact(parser.rs)中为新的事实添加一个情况
如果成功,则返回T![loan_bazzles_var_at] => { /* New parsing logic here */ }Ok(Fact::LoanBazzlesVarAt { .. })。对于我们的示例T![loan_bazzles_var_at] => { self.consume(T![loan_bazzles_var_at])?; self.consume(T!['('])?; let loan = self.parse_parameter(T![loan])?; self.consume(T![$])?; let variable = self.parse_parameter(T![variable])?; self.consume(T![')'])?; Ok(Fact::LoanBazzlesVarAt { loan, variable }) }
自定义关系
当然,也可以通过遵循相同的步骤向词法分析器添加令牌、编写自己的解析方法并将它们添加到parse_input中来添加自定义关系。在这种情况下,应将相应的ir表示添加到数据模型中。
依赖关系
~2.2–4.5MB
~80K SLoC