1 个稳定版本

使用旧的 Rust 2015

2.1.0 2019年6月15日

#285解析工具


用于 pest_derive_tmp

MIT/Apache

1MB
16K 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教授及其所有贡献者,其中一些是我的朋友,致以特别的掌声。

依赖项

约2MB
约54K SLoC