【问题标题】:What other tools can help me create a small language targeting JVM, besides ANTLR? [closed]除了 ANTLR 之外,还有哪些工具可以帮助我创建针对 JVM 的小型语言? [关闭]
【发布时间】:2017-05-17 07:19:02
【问题描述】:

(我几天前开始使用 ANTLR 进行语言冒险。我对语言理论和编译器构造的了解非常有限。如果这不是一个有效的问题,请见谅。)

ANTLR 是一个解析器 生成器,特别是ALL(*) 解析器。根据here,解析器是:

编译器中试图使句法意义的部分 源代码。

AFAIK 一个编译器应该由 5 个阶段组成:

  1. 词法分析
  2. 语法分析
  3. 语义分析
  4. IL 表示和优化
  5. 代码生成

所以 ANTLR 似乎只涵盖了 1 和 2。

因此,如果我想为一种针对 JVM 上的 Java 字节码的教育语言编写编译器。对于第 3-5 阶段,我还可以利用哪些其他工具?

添加 1

为什么 ANTLR 只覆盖 1 和 2?我猜 4 和 5 被跳过了,因为它们对目标平台来说太具体了。但是为什么ANTLR会跳过3呢?

【问题讨论】:

  • 对于代码生成,您可能会发现asm.ow2.org 库很有用
  • 这个问题应该在Software Recommendations SE问。
  • 我倾向于同意您的问题更多地是主观的而不是客观的,值得一票。但是,如果您在十多年前就开始学习解析器、编译器等,如果不在这里,那么您应该去哪里,从而得到答案。

标签: compiler-construction antlr formal-languages ll


【解决方案1】:

关于 ADD1:

ANTLR 执行 1) 和 2),因为这是为它定义的目标。作者认为您很乐意从头开始编写任何编译器的“其余部分”。

我同意,我们需要走得更远。有一个巨大的Life After Parsing

如果您想要一个不仅仅处理解析的工具,您需要 目标相应更大。

更通用的一类工具是Program Transformation Systems (PTS)。这些工具允许您定义语法,就像 ANTLR 一样,并且会生成解析器,会自动从源代码为该语言构建抽象语法树,提供修改这些 AST 的方法(通常是“源到源”重写规则),最后漂亮地打印修改后的 AST 以产生等效的源代码输出。

许多 PTS 一次仅限于“一种”语言;您可以转换该语言,这不适用于代码生成。它们通常允许进行黑客攻击,您可以在其中构建两种语言(源语言和目标语言)的联合语法,然后您可以修改源语言中的 AST 以制作目标语言中的 AST。这确实允许代码生成,但联合语言的噱头造成了很多混乱。例如,如果您有一个“+”节点,它是源语言还是目标语言中的“+”节点?你肯定不想翻译两次。

我们的DMS Software Reengineering Toolkit 将同时处理多种(包括“两种”)语言。您可以从源语言转换为目标语言,并漂亮地打印结果。因为源“+”节点与目标“+”节点不同,所以没有混淆。

通常 PST 只进行 AST 操作。您可以通过滥用重写规则将 AST“重写”为表示语义谓词结果的布尔值来实现任意语义分析。这很尴尬。

DMS 通过属性文法提供语义分析,这是使用文法规则作为指南根据 AST 计算定义任意分析的方法。您可以通过这种方式轻松构建符号表、控制流图并进行典型类型检查。 DMS 还提供了跨控制流图进行数据流分析的方法。

使用各种语义分析,可以验证源程序是否有效,运行依赖于在源程序中“遥远”找到的信息的复杂转换,并针对“目标”语言提供优化转换。

如果您将目标语言定义为 IL,则可以进行源到 IL 的转换和优化。

定义一个 JVM代码的IL并不是那么容易;毕竟,这是虚拟指令集的二进制表示。使用像 DMS 这样的 PTS,您将定义一种目标语言,它是 JVM 指令的表面语法(例如,JVM 转储会产生什么),生成它,然后运行一个相当简单的后处理步骤将其转换为实际的 JVM 二进制代码。使用 DMS,您可以将该后处理步骤实现为针对 JVM 表面语法目标语言的 AST 上的属性语法计算。

[附注:DMS 可以通过 Java 前端获得。这包括额外的支持机制来解析和处理 JVM 二进制代码。这可用于实现后处理到 JVM 二进制步骤。或者,您可以自己滚动]。

DMS 作为工具的设计目标是涵盖语言翻译(“编译”是一种特殊情况)和程序分析等广泛的应用程序。它对应的野心更大,比ANTLR更大,也对应更强大。

【讨论】:

  • 哈哈It is astonishing how often people think that the key to building a tool to process a computer (or domain-specific) language is to get a parser. Its true... in the same sense that playing poker is all about putting the ante into the pot. If you believe this, the other poker players are going to eat you alive. Yes, you have to ante. No, that's not where the game is played.
  • added Binary Decision Diagram support :)
  • @IraBaxter 从这里阅读您关于使用语言转换系统的代码覆盖率的论文:semdesigns.com/Company/Publications/TestCoverage.pdf。这是非常有用的。也许我可以使用 ANTLR 来构建一个实验性的语言转换系统。谢谢。 (此评论与此问题无关。)
  • @smwikipedia:在您尝试使用 ANTLR 构建 PTS 之前,建议您阅读我的“解析后的生活”链接。我认为你严重低估了 ANTLR 作为 PTS 的坚实基础的完整性。
  • @IraBaxter 感谢您的提醒。我会看看你的链接。说实话,我对 ANTLR 的经验只是一点点。
【解决方案2】:

由于您似乎正在磨练 ANTLR,我建议您购买一份
Language Implementation Patterns - Create Your Own Domain-Specific and General Programming Languages”和
"The Definitive ANTLR 4 Reference" by Terrence Parr

对于第 3-5 阶段,我还可以利用哪些其他工具?

Terrence Parr ANTLR 的创建者还创建了String Template,可用于 AST 转换,但还有其他工具可以填补这一空白。见:List of program transformation systems。请注意,Ira 在他的回答中已经提到了 DMS。

对于第 3 阶段,语义分析,您可以使用 ANTLR。请参阅:ANTLR: How to replace specific nodes in a subtree using a Tree grammar? 作为示例。本书还讨论了其他进行语义分析的方法。

对于第 4-5 阶段,请阅读第 10 章,Building Bytecode Interpreters
对于初学者来说,这是一个很好的起点,但它只会让你开始。

对于第 4-5 阶段的快速搜索,我发现这一点在快速阅读后是有意义的,所以我会提到它,但不能保证。简而言之,将Javac 用于阶段 4-5。由于该博客托管在 Oracle 上,因此我认为只有 Oracle Javac 可以工作。

一个非常有趣的方法是构造 AST 节点来表示 java代码的结构,然后从中生成字节码。 实际上,这就是 javac 所做的。

Generating java byte code by building AST trees

为什么 ANTLR 只覆盖 1 和 2?

来自Tree rewriting in ANTLR v4

引用Terrence Parr

因为大多数 ANTLR 用户不构建编译器,所以我决定专注于 ANTLR v4 的其他应用程序:解析和提取 信息,然后翻译。

所以 对于阶段 1,2 和 3,您将使用 ANTLR,
对于 AST 转换,如有必要,您可以使用字符串模板和
对于第 4 阶段和第 5 阶段,您可以使用 Javac。

这只是一个开始,您还有很长的路要走,还有很多研究要做。我建议您在此过程中记大量笔记。

【讨论】:

  • 呃,第 3 阶段如何使用字符串模板 == “语义分析”???
  • 请修正您的答案。许多人不阅读 cmets。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-05
  • 1970-01-01
  • 2021-12-14
相关资源
最近更新 更多