编译器的运行流程主要分为前端处理,中间表示和后端处理,而在前端处理中又可分为词法分析、语法分析、语义分析和中间代码生成。现在我们首先开始了解词法分析的运行原理、分析任务,以及其分析结果的表示形式。
1、词法分析的目标和数据结构
文章图片
词法分析主要是将源码字符流转换成token记号流,对源码字符进行分析,我们可以先将这些字符进行分类,如下一个简单的C程序:
#include <
stdio.h>
int main(){
char *message = "hello ubuntu!";
printf("message: %s\n", message);
return 0;
}
对于以上的源码字符,我们可以简单地将这些字符分为关键字(int),限定符(大括号),标识符(message)等,每种类型的字符有它相应的值,使用一个结构体表示如下:
enum type{INT, LT, GT, ID};
struct token{
enum type type;
char *value;
};
Type表示字符的类型,value表示字符对应的值,token称为一个词法单元,每个字符都使用这样的token表示,这样我们就完整地表示了源码中的所有字符。
2、Token词法单元的表示形式Token的主要表示形式如下:
文章图片
可以简要表示为token{type,value},类别码就是字符单元的类型,属性值是对应字符的值,那么什么是类别码呢?类别码在一般的编程语言中主要分为5种:
- 关键字:例如if、break,而这些字符一般唯一而且没有值,所以它们的type是唯一的,如对应if我们可以表示为:token{IF,0}。
- 标识符:其实关键字也是标识符,不过这里说的标识符主要是自定义的标识符,如变量名,函数名等,自定义标识符不唯一,统一使用ID表示标识符的类型,而value是标识符的字面值,如number=90;number表示为:token{ID,number}。
- 常量:如number=90,90就是常量,表示为token{CONST,90}。
- 运算符:字符唯一和关键字的表示一样,如< 可表示为token{LT,0}。
- 界限符:如大括号{}就是界限符,和运算符表示形式一样。
新建Clex.l文件为Flex的源代码,具体写法暂不介绍,使用Flex编译:flex clex.l,Flex默认会生成文件lex.yy.c,使用gcc编译该文件:gcc –o analyzer lex.yy.c,得到的analyzer即为词法分析器。
【深入浅出编译原理简明教程(三)(语法分析的运行处理机制)】新建hello.c文件,简单写一几行C代码,使用analyzer分析该文件,得到如下结果:
文章图片
推荐阅读
- 深入浅出编译原理简明教程(四)(词法分析的编码实现、词法分析生成器和正则表达式)
- 深入浅出编译原理简明教程(二)(编译器的逻辑结构、编译过程和编译实例)
- 深入浅出编译原理简明教程(一)(什么是编译(编译原理的学习介绍和好处))
- 如何更容易地快速学会网格布局(CSS Grid Layout内容补充(四))
- 如何更容易地快速学会网格布局(响应式网格布局高阶实战(模仿SegmentFault首页(三)))
- 如何更容易地快速学会网格布局(CSS Grid Layout进阶设计实战(模仿京东女装首页(二)))
- 如何更容易地快速学会网格布局(CSS Grid Layout基本设置入门教程详解(一))
- 最好用的轮播插件框架都在这里了,Github流行轮播框架
- 前端进阶开发实战教程,使用Flexbox模仿Github项目详情页实现响应式布局详解(二)