我们有一个为 antlr V2 编写的语法,我想迁移到 antlr v4。有迁移指南吗?我还想知道对现有 V2 语法的修改,以便我们能够很好地利用 v4 功能。
2 回答
很高兴再次见到您!
我们最近将一组大型语法迁移到 ANTLR 4 并在这里写了一些课程:https ://tomassetti.me/migrating-from-antlr2-to-antlr4/
让我在这里总结一下要点。
为什么要迁移?
ANTLR 4 具有使语法更简洁和可维护的功能
ANTLR2 仅支持少数目标平台:Java、C# 和 C++,而 ANTLR4 支持更多
ANTLR4 特性和差异
ANTLR4 接受左递归语法:这是一个很大的语法,因为它导致更简单和“不那么深”的语法
ANTLR4 解析器采用自适应 LL(*) 算法:您无需确定“k”,这绝非易事
ANTLR4 不再构建抽象语法树 (AST)。这对您的迁移影响最大
过程
- 重写语法,一次一条规则,删除所有 AST 构造逻辑(如果存在)。
- 生成解析器和访问者。
- 如果消费代码需要 AST,请编写一个从解析树构建 AST 的访问者。
- 如果 ANTLR2 语法包含语义动作,请编写一个访问者来运行这些动作,无论是从解析树还是从抽象语法树。
在本文中,我们将详细介绍如何翻译单个选项或对令牌的操作。
核心部分是如何处理 ANTLR 4 中不再存在的树重写规则。
在实践中,您将需要一个库来定义 AST,您可以通过简化由 ANTLRv4 生成的分析树来获得该库。现在,在 ANTLR v2 中,您曾经在语法本身中执行此操作,而在使用 ANTLR v4 时,您将在后续步骤中执行此操作。这很好,因为您将有两个更简单的阶段,而不是一个复杂的语法(有利于可维护性和可测试性)。但是,它需要您编写一个小库来表示 AST。
如果您使用 Java 目标,您可能有兴趣使用这个开源库来表示 AST:https ://github.com/Strumenta/kolasu
我通过编写一个新的 Antlr 4 语法文件解决了这个问题。从 Antlr 2 到 Antlr 4 没有很好的转换。