w00*_*w00 9 compiler-construction lexical-analysis code-translation
我想了解一个转换器是如何工作的.最好这样做是写一个课程.
从理论上讲,我一直在研究一些资源,以了解其工作原理.我理解以下内容:
从我的理解,我基本上需要写两个类:
将Lexical Analyzer文件的源代码作为输入(输入流).例如,以下代码:
if (someVar == 20) {
MessageBox("Hello World!");
}
Run Code Online (Sandbox Code Playgroud)
然后Lexical Analyzer从中创建数据块:
[if]
[ ]
[(]
[someVar]
[ ]
[==]
[ ]
[20]
[)]
[ ]
[{]
[\n]
[\t]
[MessageBox]
[(]
["]
[Hello World!]
["]
[)]
[;]
[\n]
[\t]
[}]
Run Code Online (Sandbox Code Playgroud)
然后将其发送给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
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我还没有完全理清究竟哪种类型.但这应该是基本的想法.
现在我要做的下一件事是将源代码转换为另一个源代码,从而进行转换.但是这有什么作用呢?我找不到任何直接的教程,解释.
假设我有以下自定义代码:
def myVar = true;
public function myFunc ( def arg1 )
{
if ( arg1 == true ) {
MessageBox("My Message");
}
}
Run Code Online (Sandbox Code Playgroud)
然后Lexical进程将解析此代码.然后我如何将其转换为类似Javascript的东西?
var myVar = true;
myFunc = function ( arg1 )
{
if ( arg1 == true ) {
alert("My Message");
}
}
Run Code Online (Sandbox Code Playgroud)
从我的自定义cdoe到Javascript之类的代码,映射如何工作?就像,函数声明.我的Lexical解析器有以下几点:public,function,myFunc.它怎么知道它应该映射到:myFunc = function...?
任何关于如何在一个方面做到这一点的任何好的和实用的信息transpiler?或者我是通过lexical为这份工作编写分析仪而弄错了?
所以很明显我的想法是词法分析器/解析器的工作原理并不完全正确.任何有关此过程如何工作的"伪"信息(使用伪示例)都非常受欢迎.
我强烈建议您查看Decaf 编译器项目。
一般来说,转译器或翻译器只是一个未经优化的编译器。
以下是编译器(或本例中的转译器)各个阶段的大致概述。
词法分析:它获取输入流并将其转换为标记。标记是语言中最小的有意义的单位。例如,关键字、大括号、标识符。标记通常可以用正则语言(或等效的正则表达式)来描述,因此词法分析器通常使用正则表达式来扫描输入流以创建分类标记。
解析:一般来说,解析器需要将标记流转换为抽象语法树。这使我们能够从输入中收集更多含义和结构。例如,“(id:x) (operator:=) (id:y)”可能是传入的令牌流,然后解析将输出一棵以 (operator:=) 作为根、 (id:x) 作为左孩子,(id:y) 作为右孩子。AST 的结构取决于语言的语法。一般来说,您的解析器会强制执行语言语法。
语义分析:在这里您可以浏览 AST 并从输入中收集您需要的其他信息。一个典型的例子是类型检查。
优化:语义分析后,编译器通常会执行某种级别的优化。在转译器/翻译器优化的情况下,可能不需要。
代码生成:这是您将一种语言“映射”到另一种语言的部分。生成器将获取每个 AST 并生成它所指示的代码。在普通编译器中,这会生成汇编代码或机器代码。在翻译器/转译器中,您只需要为您想要的特定语言编写生成器。
当然,这个列表非常详尽,但我希望它可以帮助您更好地了解您的项目!