1个稳定版本

使用旧的Rust 2015

2.1.0 2019年6月15日

#40#peg

MIT/Apache

785KB
13K 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 的贡献者,其中不乏我的朋友。

依赖项

约2.5MB
约57K SLoC