注:
课程:《编译技术》上机
实验一:词法语法分析器的设计与实现,生成抽象语法树。
建议使用词法语法分析程序生成工具如:LEX/FLEX , YACC/BISON等专业工具完成。
此处完成补充 char类型变量 的操作
另外:希望大噶支持下我滴个人博客网站:www.xyzsh.cn
文章有更新的话,个人网站会优先发出来的(CSDN有审核)
希望童鞋们可以去踩一踩~!
前期准备
- 已完成上一篇文章中的填坑操作,即输入parser test.c可以正常输出文法树结果
- 已经将整个文件夹都备好份,以供魔改后的回溯
开始实验
这是我们第一次修改源语言定义文件,因此主要还是效仿类似的定义来修改,比如int、float类型的定义。
第一步
修改lex.l文件(lex描述文件给出了每一类词法单元的规则)
- 第11行插入char type_char;
这里是效仿int、float,我们也在组合体里加入type_char的变量。 - 第23行插入char类型的识别规则
这个正则表达式含义是识别 被单引号包裹的 一个 除换行符之外 的任意字符 - 第28行插入识别到char类型变量后的操作
效仿int、float,其中不同的是int、float所使用的函数atoi、atof,其作用是将字符串转化为整数、浮点数。
那是识别出来的字符串‘a’又怎么转为char类型呢?我这里取了个巧,yytext+1是将指针向后移一位,即将指向第一个单引号的指针,移到了指向a,再用 * 取值,于是就有了图片上的type_char= * (yytext+1)。 - 第32行插入对char字符串的识别(变量声明时的char)
第二步
修改parser.y文件(parser.y是C语言文法)
- 第20行插入char type_char
同样是效仿int、float - 第33行插入%token < type_char > CHAR
- 修改第64行:Specifier的定义
Specifier指示的是声名变量时的变量类型,它对类型的赋值,一开始是从INT、FLOAT二选一
现在增加了char类型后,我们需要修改判断赋值语句,使用了朴实无华的3个if语句。
4.修改Exp定义,在第123行插入
为什么修改Exp?
Exp定义的是一系列语句/复合语句(不含;)
在变量赋值定义中第104行Dec: VarDec ASSIGNOP Exp中VarDec指代变量名,ASSIGNOP指代=,Exp指代要赋给的值,那么char类型变量当然也算Exp的一种,否则怎么给char类型变量赋值。
第三步
修改def.h文件(def.h定义了结构体)
- 在第36行插入char type_char;
补充ASTNode结构体
第四步
修改ast.c文件(ast.c定义了树的生成与输出)
- 在第117行插入
定义了遇到char类型常量时的输出 - 修改第54行case PARAM_DEC的操作
之前仅有int、float两种情况,现在补充上char
另:解释一下 printf(“% * cCHAR:%c\n”,indent,’ ',T->type_char);的含义:先打印indent个空格,再打印CHAR:%c
默认低一级的话,往后移3个空格
第四步
修改test.c文件(测试代码)
- 第3行是测试外部变量定义
- 第11行是内部变量定义
- 第12-13是char类型赋值
结果检验
依次运行
flex lex.l
bison -d parser.y
gcc -o parser lex.yy.c parser.tab.c ast.c
parser test.c
发现有乱码,使用chcp 65001切换到UTF-8编码界面
char类型外部变量定义完成!
char类型局部变量定义完成!
char类型赋值完成!
这个补充char算是比较难的一步骤,需要改的地方很多,尤其是那个def.h稍微不小心就会漏掉,大家继续加油呀!接下来的比较简单(除了多维数组)
写在结尾
希望以上可以帮到你!
如有错误,或不同想法,欢迎指出,互相学习共同进步!
源码资源下载:点赞关注后即可免费下载,下载戳我!
如果不可以的话,戳这里百度网盘 提取码:hust