Parsing 有没有办法不使用语法定向翻译来编写编译器前端?

Parsing 有没有办法不使用语法定向翻译来编写编译器前端?,parsing,compiler-construction,code-translation,intermediate-code,Parsing,Compiler Construction,Code Translation,Intermediate Code,我的问题和题目一样。我只想知道是否有其他翻译技术可以获得不依赖于将动作嵌入解析器的中间代码(也就是说,解析器将严格创建抽象语法树,它不会生成任何代码)。谢谢您的回答。如果您有一个解析器,那么解析器必须做的不仅仅是“识别”输入流作为该语言的有效实例。如果希望编译器生成任何内容,则必须将某种操作附加到匹配langauge片段的活动。从某种意义上说,它只能是“语法导向的”;在解析阶段,您所拥有的只是语法 从根本上说,解析操作必须构建“更可编译”的程序表示。我只知道几个基本方法: 生成一组虚拟机指令

我的问题和题目一样。我只想知道是否有其他翻译技术可以获得不依赖于将动作嵌入解析器的中间代码(也就是说,解析器将严格创建抽象语法树,它不会生成任何代码)。谢谢您的回答。

如果您有一个解析器,那么解析器必须做的不仅仅是“识别”输入流作为该语言的有效实例。如果希望编译器生成任何内容,则必须将某种操作附加到匹配langauge片段的活动。从某种意义上说,它只能是“语法导向的”;在解析阶段,您所拥有的只是语法

从根本上说,解析操作必须构建“更可编译”的程序表示。我只知道几个基本方法:

  • 生成一组虚拟机指令
  • 构建一个抽象语法树以传递给编译器的其余部分
  • 构建代码的某种控制/数据流表示(例如,“三元组”)
这些都是抽象的,实际上几乎相同,因为解析器生成的表示包含链接结构,其元素具有一些直接的语义解释。 这些具有隐含语义的结构位是编译器其余部分的关键所在

现在,文本是程序的表示。如果您决定将编译器实现为一个Post系统,一组字符串重写规则,那么您可以完全避免“解析”过程(某种程度上)。它们的形式是“如果您看到这个字符串,请用另一个字符串替换它”。Post系统具有明显的图灵功能,因此从技术上讲,您可以使用一组足够聪明的字符串重写规则将源代码转换为表示目标程序的字符串。据我所知,没有人能以这种方式构建真正的编译器;我相信如果你足够努力的话,你会发现一篇晦涩难懂的技术论文能够做到这一点

有人可以合理地说,Post系统所要求的匹配字符串是一种解析(例如,识别有趣的结构),让您回到原始问题


值得注意的是,程序转换系统(我在商业上构建了其中一个)通常使用编译器前端来构建AST,然后应用AST树到树的重写来实现其目的。它们之所以以这种方式构建,是因为它们实际上是diguise中的Post系统;您的程序的任何AST都可以三位一体地转换为字符串(例如,S表达式),并且树重写可以转换为等效的字符串重写。所以树重写系统只是一个Post系统,但这使它非常强大。当然,可以将此功能与其他更传统的编译器方法相结合,这就是我们对产品所做的。这使它更方便;您不必像Post系统那样做所有事情。

您描述的实际上是标准的编译器设计。可以编写一个过程编译器,实际上我已经这样做了,在解析过程中生成目标代码,但规范是解析器生成AST,后续遍历AST生成输出,或者在许多情况下生成进一步的中间形式,如三元组、RTL、,等等。

我想你可以构建一个神经网络,并对其进行训练,而不需要任何嵌入的知识-你是否有避免在解析器中嵌入操作的特殊需要?不,我只是想知道是否还有其他选择,我发现很难找到关于这一问题的信息。非常感谢你提供的详细答案。这是否意味着您可以使用AST而不是IR来生成代码?这正是我最初的想法,但我不确定这是否可能……人们可以直接从AST生成简单的代码,只需遍历AST并为遇到的每个运算符/操作数生成代码。如果您直接从解析生成,那么生成的代码将与您得到的代码非常接近。更复杂的方案遍历AST并生成“三元组”,然后将其传递给编译器的其余部分。如果你想真正了解编译器是如何生成代码的,你真的应该参考标准文本;见此答案: