编译原理实验一(6)——一维数组赋值
注:
课程:《编译技术》上机
实验一:词法语法分析器的设计与实现,生成抽象语法树。
建议使用词法语法分析程序生成工具如:LEX/FLEX , YACC/BISON等专业工具完成。
此处完成补充 一维数组赋值 的操作
前期准备
- 已经将整个文件夹都备好份,以供魔改后的回溯
开始实验
第一步
修改parser.y文件(parser.y是C语言文法)
-
第133行修改Exp语法
新增的语法 匹配 一维数组赋值部,即{ 8,2,3 }
-
第135-138行插入Arraylist的文法
通过迭代达到可以匹配多个参数的目的
那个空语句我注释起来了,本来是想要支持的,但是它支持空后会与其他的产生冲突,比如函数体是支持空的,当某个函数体为空,那么文法检测时检测到左大括号{后,都想要移进右大括号},但是采用哪个文法移进呢(他就有了两个选择1.函数体为空2.数组赋值体为空),需要设置优先级解决。emmmmm我懒了
-
第26行补充定义非终结符名
-
第38行补充定义状态名
-
第42、43、50、57行补充优先级
补充定义一下优先级,因为如果不定义的话会出现移进/规约冲突
一会儿我给你们截个图看一看移进归约冲突张啥子样子hhhhh
-
第103行修改DefList优先级
插入%prec ID表明该条语句有着和ID一样的优先级(具体为什么是ID,emmmm只能说是分析加尝试,我的头就是这么秃的hhhhhh
参观开始啦!
移进/归约冲突的报错,然后我们运行bison -d -v parser.y,他会输出一个文件parser.output
打开文件后他告诉我们 状态47发生了12个移进归约冲突
来到状态47,拿INT举例,它既可以移进shift,又可以使用规则29归约reduce
于是就产生了一个冲突。
我们可以再去看规则29时可以发现,是DefList的空语句跟其他语句产生的冲突,所以我们要调整它或者与他产生冲突的语句的优先级(只要优先级不同就不会冲突),但是还是要注意优先级也不是随便调的,比如这个空语句你如果调太高的话,识别时看到左大括号,下一个就想要右大括号,而不想要检测其他语句,也会产生错误。
不过这种错误都是在最后一步parser test.c时爆出来的
好了参观就到此为止了hhhh
第二步
修改ast.c文件(ast.c定义了树的生成与输出)
- 在第148-151行插入ARRAY的输出
感觉大家应该都懂了,就不解释了
- 在第152-154行插入ARRAY_LIST的输出
补:解释一下 printf("% * cCHAR:%c\n",indent,’ ‘,T->type_char);的含义:先打印indent个空格,再打印CHAR:%c
默认低一级的话,往后移3个空格
第三步
修改test.c文件(测试代码)
- 第14行是测试一维数组局部变量声名时赋值
- 第42行是测试一维维数组赋值
结果检验
依次运行
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编码界面
一维数组的赋值输出完成!
一维数组局部变量声明时赋值也可以输出!
一维数组赋值补充完成啦!这里就稍微难一点了,需要权衡优先级之类的,而且优先级也不是很好调节,太高太低都不行,不过难度还行不算大,我当时耗在这里的时间比多维数组赋值少得多得多....加油吧!奥力给!
近期可能不会更新了,我要去gun去复习了~
写在结尾
希望以上可以帮到你!
如有错误,或不同想法,欢迎指出,互相学习共同进步!
Share this content:
目前为止有一条评论