Mslxl

Integrate Life

编译原理:绪论 —— 词法分析

Posted at # Compiler

词法分析 (Scanning)

词法分析是编译的第一个阶段。词法分析器的主要任务是从左向右逐行扫描 (Scanning) 源程序的字符,识别出各个单词,确定单词的类型。将识别出的单词转换成统一的机内表示——词法单元 (token) 形式。

token: <种别码,属性值>

token 是一个二元组,其中第一个分量种别码用来表示单词的种别,就比如人说的自然语言中都有词性,程序设计语言也有这些东西,他们大体可分为五类:

单词类型种别种别码
1关键字program、if、else、then、…一词一码
2标识符变量名、数组名、记录名、过程名、…多词一码
3常量整型、浮点型、字符型、布尔型、…一型一码
4运算符算术 (+ - * / ++ —)
关系 ( > < == != >= <= )
逻辑 (&
~ )
5界限符; ( ) = { } …一词一码

1 中,因为我们每个关键字都是确定的,所以我们为每一个关键字分配一个种别码,也就是一词一码。

2 是标识符,他是程序员在编程中为对象等起的名字,由于标识符是一个开放的集合,我们在事先并不能确认到底有那些标识符,因此我们将所有的标识符都作为一个单词并分配同一个种别码,也就是多词一码,为了区分每个标识符,我们使用 token 的第二个分量属性值来储存不同标识符具体的字面值

3 是常量,常量与标识符类似,也是一个开放型集合,但是不同类型的常量他们的构成类型是不同的,因此我们可以给每个不同类型的常量分配一个种别码,也就是也就是一型一码,为了区分不同的常量,我们也是使用 token 的第二个分量来存放每个常量具体的值

451 类似,他们都是可以事先可以确定的,所以我们可以为每一个运算符和界限符分配一个种别码,也就是一词一码,当然我们也可以为每一个运算符分配一个种别码,为了区分他们具体的区别,同样我们也要使用 token 的第二个分量

Example

根据以上的分配原则,我们可以看一个例子

while (value != 100){
num++;
}

对以上代码进行分析,我们可以得到这样的一个 token 序列

CodeToken
1whileWHILE,-
2(SLP,-
3valueIDN,value
4!=NE,-
5100CONST,100
6)SPR,-
7{LP,-
8numIDN,num
9++INC,-
10;SEMI,-
11}RP,-

种别码本身应该是一个整数,在这里为了直观起见,我们采取了宏定义的形式。

我们先来看 1while 是一个关键字,因此我们采取一词一码,我们可以直接将他区分开,因此他的第二个分量是空的

1 同样的道理 (!=){++}; 我们都可以直接将他们区分,因此他们的属性值都是空的

38 中,valuenum 都是标识符,因此他们的种别码都是 IDN (IDentifier),他们的第二个分量用来存放他们的字面值。

5 100 是一个常量,那么属性值就是 100 本身。

THE END


graph TD
	Start-- 字符流 -->词法分析器
	词法分析器-- 词法字节流 -->语法分析器
	语法分析器-- 语法树 -->语义分析器
	语义分析器-- 语法树 -->中间代码生成器
	中间代码生成器-- 中间表示形式 -->机器无关代码优化器
	机器无关代码优化器-- 中间表示形式 -->目标代码生成器
	目标代码生成器-- 目标机器语言 -->机器相关代码优化器
	机器相关代码优化器-- 目标机器语言 -->Fin
moe-counter

统计自 2024 年 9 月