🌈个人主页:Sarapines Programmer
🔥 系列专栏:《编译原理奇遇记》
🔖墨香寄清辞:空谷幽篁风动,梦中仙鹤月明。 辗转千秋豪情在,乘风翱翔志不移。
目录结构
1. 编译原理之词法分析概念
1.1 编译原理
1.2 词法分析
2. 词法分析
2.1 实验目的
2.2 实验要求
2.3 实验理论依据
2.3.1 识别各种单词符号
2.3.2 超前搜索方法
2.3.3 预处理
2.3.4 参考代码
2.4 实验内容
2.4.1 解决代码
2.4.2 运行结果
2.5 功能扩展
2.5.1 第1处
2.5.2 第2-4处
2.5.3 第5处
2.5.4 第6-8处
2.5.5 第9-10处
2.5.6 第11处
2.6 实验心得
3.致各位
编译原理是计算机科学领域的一个重要分支,它研究如何将高级编程语言的源代码转化成计算机能够执行的机器代码或中间代码的过程。编译原理涵盖了编译器的设计和实现,其中编译器是一种将源代码翻译成目标代码的软件工具。编译器的主要任务包括语法分析、词法分析、语义分析、优化和代码生成等环节。
词法分析是编译过程中的第一个阶段,其主要目标是将源代码分割成称为“词法单元”的基本单元,例如标识符、关键字、操作符、常量等。词法分析器(也称为词法扫描器)负责识别源代码中的这些词法单元,并将它们转化为一系列标记(tokens),通常以数据结构的形式存储,供后续阶段的语法分析器使用
🔥【免费】编译原理-词法分析:C/C++实现资源-CSDN文库
🔥 相关博文:编译原理之LL(1)分析法:C/C++实现(附源码+详解!)
(1)编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类;
(2)依次输出各个单词的内部编码及单词符号自身值。
源程序为C语言,输入如下一段:
main()
{
int a=-5,b=4,j;
if(a>=b)
j=a-b;
else j=b-a;
}
要求输出结果如下:
("main",1,1)
("(",5)
(")",5)
("{",5)
("int",1,2)
("a",2)
("=",4)
("-5",3)
(",",5)
("b",2)
("=",4)
("4",3)
(",",5)
("j",2)
(";",5)
("if",1,3)
("(",5)
("a",2)
(">=",4)
("b",2)
(")",5)
("j",2)
("=",4)
("a",2)
("-",4)
("b",2)
(";",5)
("else",1,4)
("j",2)
("=",4)
("b",2)
("-",4)
("a",2)
(";",5)
("}",5)
1、 程序语言的单词符号一般分为五种:
(1) 关键字(保留字/ 基本字)if 、while 、begin…
(2) 标识符:常量名、变量名…
(3) 常数:34 、56.78 、true 、‘a’ 、…
(4) 运算符:+ 、- 、* 、/ 、〈 、and 、or 、….
(5) 界限符:, ; ( ) { } /*…
2、 识别单词:掌握单词的构成规则很重要
(1) 标识符的识别:字母| 下划线+( 字母/ 数字/ 下划线)
(2) 关键字的识别:与标识符相同,最后查表
(3) 常数的识别
(4) 界符和算符的识别
3、 大多数程序设计语言的单词符号都可以用转换图来识别,如下:
4、 词法分析器输出的单词符号常常表示为二元式:(单词种别,单词符号的属性值)
(1) 单词种别通常用整数编码,如1 代表关键字,2 代表标识符等
(2) 关键字可视其全体为一种,也可以一字一种。采用一字一种得分法实际处理起来较为方便。
(3) 标识符一般统归为一种
(4) 常数按类型(整、实、布尔等)分种
(5) 运算符可采用一符一种的方法。
(6) 界符一般一符一种的分法。
词法分析时,常常会用到超前搜索方法:
如当前待分析字符串为“a>+” ,当前字符为“>” ,此时,分析器倒底是将其分析为大于关系运算符还是大于等于关系运算符呢?
显然,只有知道下一个字符是什么才能下结论。于是分析器读入下一个字符’+’ ,这时可知应将’>’ 解释为大于运算符。但此时,超前读了一个字符’+’ ,所以要回退一个字符,词法分析器才能正常运行。又比如:‘+’ 分析为正号还是加法符号
预处理工作包括对空白符、跳格符、回车符和换行符等编辑性字符的处理,及删除注解等。由一个预处理子程序来完成。
词法分析器的设计
1、 设计方法:
(1) 写出该语言的词法规则。
(2) 把词法规则转换为相应的状态转换图。
(3) 把各转换图的初态连在一起,构成识别该语言的自动机
(4) 设计扫描器
2、 把扫描器作为语法分析的一个过程,当语法分析需要一个单词时,就调用扫描器。
扫描器从初态出发,当识别一个单词后便进入终态,送出二元式。
参考代码(不完整):
void main()
{if ((fp=fopen("example.c", "r")) == NULL) /* 只读方式打开一个文件 */printf("error");else{cbuffer = fgetc(fp); /* fgetc( )函数:从磁盘文件读取一个字符 */while (cbuffer != EOF){if (cbuffer == ' ' || cbuffer == 'n') /* 掠过空格和回车符 */cbuffer = fgetc(fp);else{if (isalpha(cbuffer))cbuffer = alphaprocess(cbuffer);else if (isdigit(cbuffer))cbuffer = digitprocess(cbuffer);elsecbuffer = otherprocess(cbuffer);}}}
}char alphaprocess(char buffer)
{int atype; /* 保留字数组中的位置 */int i = -1;char alphatp[20];while (isalpha(buffer) || isdigit(buffer) || buffer == '_'){alphatp[++i] = buffer;}alphatp[i + 1] = '