编译原理实验报告
实验5:用Yacc设计语法分析器1
实验6:用Yacc设计语法分析器2
中国海洋大学编译原理实验2023春
仅供同学参考思路 请勿直接抄袭 否则可能喜提0分
目录
文章目录
- 编译原理实验报告
- 目录
- 一.实验目的
- 二.实验内容
- 实验5
- 实验6
- 三.实验要求
- 实验5
- 实验6
- 四.实验过程及重点内容
- 实验5:
- 实验6:
- 五.实验结果
- 实验5:
- 实验6:
一.实验目的
学习如何使用Yacc设计一个语法分析器,并与用lex写的词法分析器链接起来。
学习如何使用Lex和Yacc设计一个语法分析器,并学习如何在语法分析的同时生成分析树。
二.实验内容
实验5
使用yacc为实验2所给的语言写一个语法分析器(你可以重新设计该语言的文法,但不能改变语言)。其中,词法分析使用实验3中已完成的词法分析器(即,你需要将本实验的语法分析器和实验3的词法分析器链接起来)。
实验6
修改实验5,给产生式加上动作,动作为生成一棵语法分析树。这棵分析树的结构可以使用或参照例子parser1中ast.h文件中定义的分析树结构。
三.实验要求
实验5
输入为实验2所给语言写的源程序文件;输出为屏幕显示语法分析是否成功。
在语法分析中不能出现任何的冲突(移进-归约或归约-归约冲突),或者虽然有冲突,但是你能够说清楚冲突是如何解决的。
在实验环境下用flex,bison和gcc工具将实验调试通过,并且你写的语法分析器至少应该能通过例子parser0中testcases目录下的test0.p和test1.p两个测试例的测试。
实验6
输入为实验2所给语言写的源程序文件;输出为一棵语法分析树,这棵语法分析树的表示方法可以是这样两种:1.将分析树的数据结构打印出来;2.按分析树的结构输出一个C语言源程序文件(即输入是所给语言的源程序文件,输出为语义相同的C语言源程序文件)。
在cygwin下用flex,bison和gcc工具将实验调试通过,并且你写的语法分析器至少应该能通过例子parser1中testcases目录下的test0.p和test1.p两个测试例。
四.实验过程及重点内容
实验5:
首先复制一份实验2的LEX词法分析.l文件
根据实验2的语言文法 删去不需要的词法终结符与正规式
并添加 := ASSIGN : COLON等等新增的终结符
去掉为每个记号手动编写的define编号 因为yacc会自动生成头文件 其中包含了每个记号的编号
由于需要储存多种类型的值 则需要定义联合体
声明所有的终结符:
改写实验2的文法为代码:
挨个为每个语法规则编写yacc代码:
如果直接按照实验文档的文法 将出现移进-归约冲突 故对变量解释及变量解释表产生式进行了更改
使用yacc与flex进行编译链接
运行测试用例test0/1.p
实验6:
首先需要修改.l文件
对于in int float需要进行赋值操作
复制一份parser1已提供的文件
主要需要修改ast.c parser.y
ast.h提供了很多的数据结构 需要慢慢细看 先直接修改ast.c文件中的函数
观察Int赋值格式 先去查询a_exp数据结构 发现需要固定赋值一个kind和用于报错的pos
其他函数类似 根据函数的名称以及返回值类型 前去ast.h查询数据结构
然后根据功能对结构体中的每个变量来进行赋值
修改完毕ast.c中的各函数后 回到.y文件中
将实验5中已经定义的语言复制一份过来
现在需要在分析文法的同时,加上函数动作
预先定义三个主要结构的指针 程序/变量说明表/语句表
为大部分产生式添加动作
其中$$代表非终结符本身 $i代表第i个记号的值
根据每个子函数所需要的参数进行填写 以及对返回值进行赋值
在添加动作时 发现非终结符出现报错 原因是没有对非终结符进行类型的指定
更改union集合体的类型
并为每个非终结符进行类型指定
动作指定完毕后,即可通过make指令进行链接编译
五.实验结果
实验5:
实验6:
test0.p
test1.p