9

我想了解转译器的工作原理。最好的办法是写一篇ofcourse。

从理论上讲,我一直在研究一些资源以了解其工作原理。我了解以下内容:

据我了解,我基本上需要编写两个类:

  1. 词法分析器
  2. 解析器

词法分析器

Lexical Analyzer文件的源代码作为输入(输入流)。例如下面的代码:

if (someVar == 20) {
    MessageBox("Hello World!");
}

然后Lexical Analyzer创建数据块:

[if]
[ ]
[(]
[someVar]
[ ]
[==]
[ ]
[20]
[)]
[ ]
[{]
[\n]
[\t]
[MessageBox]
[(]
["]
[Hello World!]
["]
[)]
[;]
[\n]
[\t]
[}]

然后将其发送给Parser班级。

解析器

然后Parser该类将读取所有标记块(?)并指定每个标记(?)的含义。它将为其分配某种类型。因此,上述字符串的结果将被标识为:

[if]      // Keyword
[ ]       // Whitespace
[(]       // L_Parenthesis
[someVar] // Identifier
[ ]       // Whitespace
[==]      // Operator
[ ]       // Whitespace
[20]      // Number (or Integer)
[)]       // R_Parenthesis
[ ]       // Whitespace
[{]       // L_Bracket
[\n]      // Whitespace
[\t]      // Whitespace
[MessageBox] // Keyword
[(]       // L_Parenthesis
["]       // Not yet sure where this would go
[Hello World!] // Same..
["]       // Same...
[)]       // R_Parenthesis
[;]       // Semicolon
[\n]      // Whitespace
[\t]      // Whitespace
[}]       // R_Bracket

正如你所看到的,我还没有完全弄清楚哪些类型到底在哪里。但这应该是基本思想。

现在我想做的下一件事就是将该源代码转换为另一个源代码,从而对其进行转译。但这是如何工作的?我找不到任何直接的教程和解释。

假设我有以下自定义代码:

def myVar = true;

public function myFunc ( def arg1 )
{
    if ( arg1 == true ) {
        MessageBox("My Message");
    }
}

然后 Lexical 进程将解析这段代码。那么我如何将其转换为 Javascript 之类的东西?

var myVar = true;

myFunc = function ( arg1 )
{
    if ( arg1 == true ) {
        alert("My Message");
    }
}

从我的自定义 cdoe 到像 Javascript 这样的代码,映射是如何工作的?比如函数声明。我的Lexical解析器具有以下内容:public, function, myFunc. 它怎么知道它应该映射到:myFunc = function...?

任何人都可以提供有关如何在其中完成此操作的任何有用且实用的信息transpiler?或者我lexical为这份工作编写分析器是不是错了?

编辑

所以很明显我的词法分析器/解析器如何工作的想法并不完全正确。任何有关此过程如何工作的“伪”信息(带有伪示例)都非常受欢迎。

4

2 回答 2

0

你已经做了一些实验。我建议你选择 ANTLR。您指定的两种语言的语法都存在于 ANTLR v4 的 Github 存储库中。下一步是映射两个 Grammars 。变量到变量,函数到函数等...意味着所有语言结构:关键字、符号等。任何额外的功能都需要硬编码,否则转译、编译或解释将无法 100% 工作。

于 2019-11-05T12:59:34.033 回答
0

我强烈推荐看看Decaf 编译器项目

一般来说,转译器或翻译器只是一个没有优化的编译器。

以下是编译器(或本例中的转译器)各个阶段的概述。

  1. 词法分析:这需要输入流并将其转换为标记。标记是语言中最小的有意义的单位。例如,关键字、大括号、标识符。标记通常可以用正则语言(或等效的正则表达式)来描述,因此词法分析器通常使用正则表达式来扫描输入流以创建分类标记。

  2. Parsing:解析器,一般来说,需要将标记流转换为Abstract Syntax Trees。这使我们能够从输入中收集更多的含义和结构。例如 "(id:x) (operator:=) (id:y)" 可以是传入的令牌流,然后解析将输出以 (operator:=) 为根的树, (id:x) 为左孩子,和 (id:y) 作为右孩子。AST 的结构取决于语言的语法。一般来说,您的解析器会强制执行语言语法。

  3. 语义分析:这是您通过 AST 并从输入中收集您需要的其他信息的地方。一个典型的例子是类型检查。

  4. 优化:在语义分析之后,编译器通常会执行某种程度的优化。在转译器/翻译器的情况下,可能不需要优化。

  5. 代码生成:这是您将一种语言“映射”到另一种语言的部分。生成器将获取每个 AST 并生成它指定的代码。在普通编译器中,这会生成程序集或机器代码。在翻译器/转译器中,您只需要为您想要的特定语言编写生成器。

当然,这份清单非常详尽,但我希望它可以帮助您更好地了解您的项目!

于 2019-09-23T19:06:19.603 回答