将 ANTLR v2 语法迁移到 ANTLR v4

Migrating ANTLR v2 grammar to ANTLR v4

我们有一个为 antlr V2 编写的语法,我想迁移到 antlr v4。有没有迁移指南?我还想知道对现有 V2 语法的修改,以便我们更好地利用 v4 功能。

我通过编写一个新的 Antlr 4 语法文件解决了这个问题。从 Antlr 2 到 Antlr 4 没有很好的转换。

很高兴再次见到你!

我们最近将一组大型语法迁移到 ANTLR 4 并在这里写了一些课程:https://tomassetti.me/migrating-from-antlr2-to-antlr4/

这里我总结一下要点。

为什么要迁移?

  • ANTLR 4 具有使语法更加简洁和可维护的特性

  • ANTLR2 仅支持几个目标平台:Java、C# 和 C++,而 ANTLR4 支持更多

ANTLR4 的特点和差异

  • ANTLR4 接受 left-recursive 语法:这是一个很大的语法,因为它导致更简单和“不那么深入”的语法

  • ANTLR4 解析器采用自适应 LL(*) 算法:您无需确定“k”,这绝非易事

  • ANTLR4 不再构建抽象语法树 (AST)。这对您的迁移影响最大

过程

  1. 重写语法,一次一个规则,删除所有 AST 构造逻辑(如果存在)。
  2. 生成解析器和访问者。
  3. 如果消费代码需要 AST,请编写一个从解析树构建 AST 的访问者。
  4. 如果 ANTLR2 语法包含语义操作,则编写一个运行操作的访问者,可以从解析树或抽象语法树中获取。

在本文中,我们将详细介绍翻译单个选项或标记上的操作。

核心部分是如何处理 tree-rewriting 规则,这些规则不再出现在 ANTLR 4 中。

在实践中,您将需要一个库来定义 AST,您可以通过简化 ANTLRv4 生成的 parse-tree 来获得它。现在,在 ANTLR v2 中,您过去常常在语法本身中执行此操作,而在使用 ANTLR v4 时,您将作为 follow-up 步骤执行此操作。这很好,因为您将有两个更简单的阶段,而不是一个复杂的语法(有利于可维护性和可测试性)。但是,它需要您编写一个小库来表示 AST。

如果您使用 Java 目标,您可能有兴趣使用这个 open-source 库来表示 AST:https://github.com/Strumenta/kolasu