1个稳定版本
使用旧的Rust 2015
2.1.0 | 2019年6月15日 |
---|
#40 在 #peg
785KB
13K 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教授致以特别的掌声,感谢他的指导,以及所有 Pest 的贡献者,其中不乏我的朋友。
依赖项
约2.5MB
约57K SLoC