#peg-parser #peg #grammar #parser-generator #ast #parser #syntax-tree

peginator

Peginator 是用于在 Rust 中创建 AST(抽象语法树)的 PEG(解析表达式语法)解析生成器。

14 个版本

0.7.0 2024 年 2 月 11 日
0.6.0 2022 年 11 月 28 日
0.5.1 2022 年 11 月 28 日
0.2.0 2022 年 7 月 17 日

解析工具 中排名第 19

Download history 66/week @ 2024-03-11 70/week @ 2024-03-18 68/week @ 2024-03-25 110/week @ 2024-04-01 45/week @ 2024-04-08 56/week @ 2024-04-15 61/week @ 2024-04-22 51/week @ 2024-04-29 54/week @ 2024-05-06 59/week @ 2024-05-13 65/week @ 2024-05-20 46/week @ 2024-05-27 39/week @ 2024-06-03 48/week @ 2024-06-10 51/week @ 2024-06-17 49/week @ 2024-06-24

每月下载 188
25 个 crate(直接使用 18 个)中使用

MIT 许可证

43KB
654

Peginator

Crates.io Docs.rs

Peginator 是用 Rust 编写的 PEG(解析表达式语法)解析生成器。它专门用于将数据解析为 AST(抽象语法树),这与大多数流式解析器不同。

它生成树结构和从字符串创建该树的解析代码。生成的解析代码是故意非常简单的 Rust 代码,通常编译器会很好地优化它。

有一个可选的缓存功能,使其成为适当的 Packrat 解析器,可以在线性时间和空间内解析任何输入。

还支持使用该缓存功能(也是可选的)进行左递归。

文档

本文档描述了 peginator 如何实现 PEG。假设您对 PEG 有基本了解。您可以在维基百科其他解析生成器的文档中找到良好的介绍。

Peginator 使用其自己的语法和语法文件进行自举,该文件相对易于阅读。

请参阅语法参考API 文档

测试 也可用作示例。

快速入门

Peginator 的语法与 EBNF(扩展巴科斯-诺尔形式)的语法类似

@export
FunctionDef = 'fn' name:Ident '(' param_list:ParamList ')' [ '->' return_value:Type ];

ParamList = self_param:SelfParam {',' params:Param} | params:Param  {',' params:Param} | ;

Param = name:Ident ':' typ: Type;

SelfParam = [ref_type:ReferenceMarker] 'self';

Type = [ref_type:ReferenceMarker] typename:Ident;

ReferenceMarker = @:MutableReference | @:ImmutableReference;

ImmutableReference = '&';
MutableReference = '&' 'mut';

@string
@no_skip_ws
Ident = {'a'..'z' | 'A'..'Z' | '_' | '0'..'9'};

基于上述语法,peginator 将生成以下类型

pub struct FunctionDef {
    pub name: Ident,
    pub param_list: ParamList,
    pub return_value: Option<Type>,
}
pub struct ParamList {
    pub self_param: Option<SelfParam>,
    pub params: Vec<Param>,
}
pub struct Param {
    pub name: Ident,
    pub typ: Type,
}
pub struct SelfParam {
    pub ref_type: Option<ReferenceMarker>,
}
pub struct Type {
    pub ref_type: Option<ReferenceMarker>,
    pub typename: Ident,
}
pub enum ReferenceMarker {
    ImmutableReference(ImmutableReference),
    MutableReference(MutableReference),
}
pub struct ImmutableReference;
pub struct MutableReference;
pub type Ident = String;

impl PegParser for FunctionDef { /* omitted */ }

解析看起来像这样

FunctionDef::parse("fn example(&self, input:&str, rectified:&mut Rect) -> ExampleResult;")

这将产生以下结构

FunctionDef {
    name: "example",
    param_list: ParamList {
        self_param: Some(SelfParam {
            ref_type: Some(ImmutableReference(ImmutableReference)),
        }),
        params: [
            Param {
                name: "input",
                typ: Type {
                    ref_type: Some(ImmutableReference(ImmutableReference)),
                    typename: "str",
                },
            },
            Param {
                name: "rectified",
                typ: Type {
                    ref_type: Some(MutableReference(MutableReference)),
                    typename: "Rect",
                },
            },
        ],
    },
    return_value: Some(Type {
        ref_type: None,
        typename: "ExampleResult",
    }),
}

调试

我们有基于最长匹配失败(类似于 Python 解析器)的漂亮错误

Colors and stuff on a console

还有解析跟踪(可选的,如果不使用则无成本)

More colors and indentation

集成

有几种方法可以将 Peginator 语法集成到您的项目中

  • 直接使用 peginator-cli 二进制文件编译您的语法
  • 使用来自 peginator_macro 包的 peginate! 宏内联您的语法
  • 或者您可以使用 构建脚本助手

铁路图

Peginator CLI 还可以创建您语法的优美铁路图

Railroad graph

贡献

此时,如果更多的人使用这段代码,我将感到非常高兴。如果您需要任何帮助,请随时联系。

另请参阅

该项目旨在几乎无缝替代 Tatsu 和其出色的模型构建器。这也是语法看起来是这个样子的原因。

在 Rust 中还有许多其他 PEG 解析器实现,请查看它们。以下是非详尽的列表,无特定顺序

特别提一下: lalrpop

许可

根据 MIT 许可证授权

依赖项

~0–9.5MB
~53K SLoC