编译原理之编译器的前端技术

文章目录

学习编译原理能让你从前端的语法维度、代码优化的维度、与硬件结合的维度几个方面,加深对计算机技术的理解,提升自己的竞争力。

编译器的前端技术

“前端”指的是编译器对程序代码的分析和理解过程。它通常只跟语言的语法有关,跟目标机器无关。“后端”则是生成目标代码的过程,跟目标机器有关。

图片[1]-编译原理之编译器的前端技术-JieYingAI捷鹰AI

词法分析

词法分析是把程序分割成一个个 Token 的过程,可以通过构造有限自动机来实现。

下面这段代码,如果我们要读懂它,首先要怎么做呢?

#include 
int main(int argc, char* argv[]){
    int age = 45;
    if (age >= 17+8+20) {
        printf("Hello old man!\n");
    }
    else{
        printf("Hello young man!\n");
    }
    return 0;
}

如何写一个程序来识别 Token 呢?

这些规则可以通过手写程序来实现,也可以用词法分析器的生成工具来生成,比如 Lex(或其 GNU 版本,Flex)。这些生成工具是基于一些规则来工作的,这些规则用“正则文法”表达,符合正则文法的表达式称为“正则表达式”。生成工具可以读入正则表达式,生成一种叫“有限自动机”的算法,来完成具体的词法分析工作。

词法分析器也是一样,它分析整个程序的字符串,当遇到不同的字符时,会驱使它迁移到不同的状态。例如,词法分析程序在扫描 age 的时候,处于“标识符”状态,等它遇到一个 > 符号,就切换到“比较操作符”的状态。词法分析过程,就是这样一个个状态迁移的过程。

图片[2]-编译原理之编译器的前端技术-JieYingAI捷鹰AI

语法分析

语法分析是把程序的结构识别出来,并形成一棵便于由计算机处理的抽象语法树。可以用递归下降的算法来实现。

程序也有定义良好的语法结构,它的语法分析过程,就是构造这么一棵树。一个程序就是一棵树,这棵树叫做抽象语法树(Abstract Syntax Tree,AST)。树的每个节点(子树)是一个语法单元,这个单元的构成规则就叫“语法”。每个节点还可以有下级节点。

var a = 42;
var b = 5;
function addA(d) {
    return a + d;
}
var c = addA(2) + b;
        

下图是这段JavaScript 语言编写的代码的 AST

图片[3]-编译原理之编译器的前端技术-JieYingAI捷鹰AI

怎样写程序构造AST呢?

递归下降算法是一种自顶向下的算法,与之对应的,还有自底向上的算法。这个算法会先将最下面的叶子节点识别出来,然后再组装上一级节点。有点儿像搭积木,我们总是先构造出小的单元,然后再组装成更大的单元。

语义分析

语义分析是消除语义模糊,生成一些属性信息,让计算机能够依据这些信息生成目标代码。

语义分析基本上就是做这样的事情,也就是根据语义规则进行分析判断。语义分析工作的某些成果,会作为属性标注在抽象语法树上,比如在 age 这个标识符节点和 45 这个字面量节点上,都会标识它的数据类型是 int 型的。在这个树上还可以标记很多属性,有些属性是在之前的两个阶段就被标注上了,比如所处的源代码行号,这一行的第几个字符。这样,在编译程序报错的时候,就可以比较清楚地了解出错的位置。

DSL 其实是 Domain Specific Language 的缩写,中文翻译为领域特定语言;

你知道的越多,你不知道的越多。

有道无术,术尚可求,有术无道,止于术。

如有其它问题,欢迎大家留言,我们一起讨论,一起学习,一起进步

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
来说点什么吧!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容