83 个版本 (30 个破坏性版本)

0.31.0 2024 年 6 月 21 日
0.29.0 2024 年 5 月 16 日
0.26.1 2024 年 2 月 13 日
0.25.0 2023 年 10 月 22 日
0.2.3 2021 年 11 月 30 日

#1 in #lalr-parser

Download history 125/week @ 2024-05-03 206/week @ 2024-05-10 160/week @ 2024-05-17 100/week @ 2024-05-24 114/week @ 2024-05-31 272/week @ 2024-06-07 75/week @ 2024-06-14 302/week @ 2024-06-21 80/week @ 2024-06-28 51/week @ 2024-07-05 74/week @ 2024-07-12 82/week @ 2024-07-19 70/week @ 2024-07-26 89/week @ 2024-08-02 93/week @ 2024-08-09 107/week @ 2024-08-16

每月 393 次下载
用于 11 个 crate (4 个直接使用)

MIT/Apache

1MB
23K SLoC

Rust Docs.rs Crates.io

关于 parol


Logo


parol 是一个 LL(k) 和 LALR(1) 解析器生成器,用于 Rust。

它是一个可安装的命令行工具,可以从单个语法描述文件生成完整的解析器,包括所有您通常需要自己设计的 AST 数据类型。 parol 通过分析您的语言语法来完成此操作。 parol 还是一个库,您可以在自己的 crate 中使用。

您可以控制 AST 类型生成过程。首先,您可以在您的 AST 中标记要省略的元素。您还可以指定语言元素的自己的类型。

parol 严格区分语言描述和语言实现。因此,您可以设计您语言的语法,而无需处理任何内容,因为生成的解析器默认作为接受者。这使得您能够真正地进行语法 快速原型设计

parol 生成一个特质作为您语言处理和生成的解析器之间的接口。该特质包含您语法每个非终结符的函数,您可以为需要处理的非终结符实现这些函数。在最简单的情况下,您只需为您的语法的起始符号实现特质函数,该函数在解析整个输入字符串之后被调用。然后,该函数使用包含解析文档完整结构的参数被调用。

解析器在解析过程中自动通过单独生成的适配器调用接口特质的函数。

有了这样的生成的接口特质,理论上您永远不需要让 parol 为您生成新代码,您可以专注于语言处理的发展。尽管如此,通常采取更迭式的方法。

生成的解析器

  • 是使用下压自动机 (PDAs) 实现的真正的 LL(k) 解析器。
  • 是预测性的,即它们实现了 非回溯 解析技术。这通常会导致解析器更快。
  • 干净且易于阅读。
  • 仅使用所需用于特定非终结符的最小前瞻(从0到k)。
  • 由单个语法描述文件生成。
  • 可以自动生成类似于您语法抽象语法树(AST)的类型。然后使用这些类型调用语义动作。这极大地提高了开发过程,并减少了错误率。
  • 从版本0.24.0开始,生成的解析器可以自动从语法错误中恢复。
  • 从版本0.28.0开始,parol 开始支持LR风格的语法,具体来说是LALR(1)语法。请参阅变更日志

parol的其他特性

  • 每个非终结符的选择是通过确定性有限前瞻自动机完成的。
  • 具有空默认实现的语义动作作为特质生成。您可以为您的语法处理项实现此特质,并仅实现所需动作。这为您的外部定义和语言处理之间提供了松散耦合。
  • 与Bison相比,语义动作严格与语法定义分离。当您仅更改语义动作的实现时,不需要解析器生成步骤。
  • 语法描述以Yacc/Bison风格提供,并包含来自EBNF的附加功能,如分组、可选元素和重复。
  • 您可以为多个扫描状态(即起始条件)定义多个,并直接在语法的生产中定义它们之间的切换。
  • 您可以选择为每个扫描状态单独排除空白和换行符的默认处理。
  • 语法描述支持通过为每个扫描状态提供%line_comment%block_comment声明来定义语言注释。
  • 该软件包提供了一些用于语法分析转换解析树可视化的工具,以支持您的语法实现。
  • 解析器生成器会在您的语法描述中检测直接和间接的左递归。
  • parol的解析器是由parol本身生成的。
  • 使用parol new创建您自己的使用parol的软件包。

为什么您应该在语言实现中使用LL(k)解析器?

LL解析技术是一种自顶向下的解析策略,它始终从您语法的起始符号开始。此符号成为解析树的根节点。然后它首先尝试推导最左边的符号。然后以先序遍历的方式处理所有此类符号。在此过程中,解析树从根向下创建。

处理输入和以“自然”方向生成解析树确保在解析过程中的每个点上,您都可以看到您来自何处以及您想要推导什么。parol的解析栈包含“生产结束”标记,这些标记反映了生产的“调用层次”。

这极大地有助于将您的语言处理投入运行。相比之下,任何曾经调试过LR解析器的人都会记得“突然出现”的效果。

尽管LL语法在能力上不如LR语法,但许多情况下LL语法是足够的。通过支持多个前瞻标记,传统LR(1)语法和LL(k)语法的功能越来越不明显。

为什么您应该使用parol

parol很简单。您实际上可以理解它的所有部分,而无需广泛的解析理论知识。

parol很快。确定性自动机的使用确保了解析过程中的最小开销,无需回溯。

parol是一个真正的LL(k)解析器。您不会在别处找到许多正在运行的LL(k)解析器。

parol生成易于阅读的漂亮代码,这有助于调试。

parol是一个年轻的工具。尽管有时可能会出现问题,尤其是关于API的稳定性,但最好的还在后面。

parol正在积极开发。因此,根据需要可能会添加新功能。

文档

示例

本项目包含从入门级到更复杂的类似C的表达式语言Oberon-0语法的接受者的一些入门语法示例。

parol生成的完整Oberon-2接受者可以在本存储库的示例中找到。

一个基本的解释器试图模仿C64 Basic的一小部分。

可以在这里找到一个TOML解析器。

我还提供了一个JSON解析器

parol的输入语言处理是一个额外的非常实用的示例。

书籍

一本书详细解释了parol的一些内部结构和实际应用。它仍在进行中,但应被视为核心文档。

视频

这个视频解释了安装parol和语言服务器以设置您的开发环境的过程。然后,它通过一个示例项目展示了使用parol设计语法的流程。

项目状态

parol在其开发过程中通过许多示例和测试证明了其能力。早期采用者可以相当安全地使用它。

parol尚未准备好用于生产。功能仍在开发中,crate的接口可能会随时更改。还有很多工作要做,任何帮助都受欢迎。

依赖关系

请注意,如果您使用parol new子命令创建新的crate,则所有必要的依赖项都将自动添加到您的新的parol项目中。以下部分仅提供信息。

运行时库

parol生成的解析器必须添加对parol_runtime crate的依赖。它提供了所需的扫描仪和解析器实现。parol_runtime crate非常轻量。

从版本0.13.0开始,如果您使用parol自动生成模式,则必须将parol-macros crate添加到您的依赖项中。

许可证

parol及其伴随工具是免费的、开源的,并具有许可权!除非另有说明(以下和/或单独的文件中),本存储库中所有代码均以以下两种方式双许可:

您可以选择您喜欢的许可证!

您的贡献

除非您明确声明,否则您提交给包括在本作品中,根据Apache-2.0许可证定义的所有有意贡献,将按上述方式双许可,没有额外的条款或条件。

进一步阅读

贡献者

感谢所有贡献者改进这个项目!

依赖关系

~12–23MB
~330K SLoC