1 个稳定版本
使用旧的 Rust 2015
2.1.0 | 2019年6月15日 |
---|
#285 在 解析工具
1MB
16K SLoC
pest. 精美的解析器
pest 是一个用 Rust 编写的通用解析器,它侧重于可访问性、正确性和性能。它使用解析表达式语法(或 PEG)作为输入,这与正则表达式类似,但提供了所需的增强表达能力来解析复杂语言。
入门
开始使用 pest 进行解析的推荐方法是阅读官方的 书籍。
其他有用的资源
示例
以下是一个用于 alpha-numeric 标识符列表的语法的示例,其中第一个标识符不以数字开头
alpha = { 'a'..'z' | 'A'..'Z' }
digit = { '0'..'9' }
ident = { (alpha | digit)+ }
ident_list = _{ !digit ~ ident ~ (" " ~ ident)+ }
// ^
// ident_list rule is silent which means it produces no tokens
语法保存在单独的 .pest 文件中,这些文件永远不会与过程代码混合。这导致语言的正式化始终保持最新,易于阅读和维护。
有意义的错误报告
基于语法定义,解析器还包括自动错误报告。对于上面的示例,输入 "123"
将产生
thread 'main' panicked at ' --> 1:1
|
1 | 123
| ^---
|
= unexpected digit', src/main.rs:12
而 "ab *"
将产生
thread 'main' panicked at ' --> 1:1
|
1 | ab *
| ^---
|
= expected ident', src/main.rs:12
对 API
可以使用语法自动推导 Parser
实现。解析返回一个嵌套标记对迭代器
extern crate pest;
#[macro_use]
extern crate pest_derive;
use pest::Parser;
#[derive(Parser)]
#[grammar = "ident.pest"]
struct IdentParser;
fn main() {
let pairs = IdentParser::parse(Rule::ident_list, "a1 b2").unwrap_or_else(|e| panic!("{}", e));
// Because ident_list is silent, the iterator will contain idents
for pair in pairs {
// A pair is a combination of the rule which matched and a span of input
println!("Rule: {:?}", pair.as_rule());
println!("Span: {:?}", pair.as_span());
println!("Text: {}", pair.as_str());
// A pair can be converted to an iterator of the tokens which make it up:
for inner_pair in pair.into_inner() {
match inner_pair.as_rule() {
Rule::alpha => println!("Letter: {}", inner_pair.as_str()),
Rule::digit => println!("Digit: {}", inner_pair.as_str()),
_ => unreachable!()
};
}
}
}
这会产生以下输出
Rule: ident
Span: Span { start: 0, end: 2 }
Text: a1
Letter: a
Digit: 1
Rule: ident
Span: Span { start: 3, end: 5 }
Text: b2
Letter: b
Digit: 2
其他功能
- 优先级爬升
- 输入处理
- 自定义错误
- 在稳定 Rust 上运行
使用 pest 的项目
- pest_meta(自举)
- brain
- Chelone
- comrak
- elastic-rs
- graphql-parser
- handlebars-rust
- hexdino
- Huia
- jql
- json5-rs
- mt940
- py_literal
- rouler
- RuSh
- rs_pbrt
- stache
- tera
- ui_gen
- ukhasnet-parser
- prisma
特别感谢
向Marius Minea教授及其所有贡献者,其中一些是我的朋友,致以特别的掌声。
依赖项
约2MB
约54K SLoC