1 个稳定版本

使用旧的 Rust 2015

2.1.1 2019年6月15日

#4 in #optimize


2 个 crate 中使用 (通过 pest_generator_tmp)

MIT/Apache

1MB
15K SLoC

pest. 精致的解析器

Join the chat at https://gitter.im/dragostis/pest Book Docs

Build Status codecov Crates.io Crates.io

pest 是一个用 Rust 编写的通用解析器,注重可访问性、正确性和性能。它使用解析表达式语法(或 PEG)作为输入,这与正则表达式在精神上相似,但提供了解析复杂语言所需的增强表达能力。

入门

开始使用 pest 进行解析的推荐方法是阅读官方的 书籍

其他有用资源

  • docs.rs 上的 API 参考
  • 在我们的 fiddle 上玩语法并分享它们
  • Gitter 上留下反馈、提问或打招呼

示例

以下是一个列表 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 的项目

特别感谢

向Marius Minea教授的指导和所有pest贡献者表示特别的敬意,其中一些人还是我的朋友。

依赖项

~205KB