编译原理实验报告语法分析.docx
《编译原理实验报告语法分析.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告语法分析.docx(16页珍藏版)》请在冰豆网上搜索。
![编译原理实验报告语法分析.docx](https://file1.bdocx.com/fileroot1/2022-12/7/6b3bdf01-cb5d-41d1-a0b6-4744d16f632a/6b3bdf01-cb5d-41d1-a0b6-4744d16f632a1.gif)
编译原理实验报告语法分析
编译原理课程实验报告
实验2:
语法分析
姓名
院系
软件学院
学号
任课教师
指导教师
实验地点
软件学院三楼机房
实验时间
2016/10/30/星期日
实验课表现
出勤、表现得分
实验报告
实验总分
操作结果得分
得分
一、需求分析
要求:
采用至少一种句法分析技术(LL
(1)、SLR
(1)、LR
(1)或
LALR
(1)
得分
)对类高级语言中的基本语句
进行句法分析。
阐述句法分析系统所要完成的功能。
本语法分析器是在词法分析器的基础上实现对类高级语言中的基本语句进行句法分析,基本功能如下:
(1)能识别以下几类语句:
声明语句(包括变量声明、数组声明、记录声明和过程声明)
表达式及赋值语句(包括数组元素的引用和赋值)
分支语句:
if_then_else
循环语句:
do_while
过程调用语句
(2)本语法分析器采用自顶向下的分析技术,能根据导入的文法,自动计算first集和follow集,
能够生成每个产生式的select集,并自动生成预测分析表。
(3)本语法分析器具备语法错误处理能力,可以进行错误检测,如果检测到在出错时,采用恐
慌模式,能够给出错误提示信息,格式:
错误项错误原因行号
a)忽略输入中的一些符号,直到输入中出现选定的同步词法单元集合中的某个词法单元,同
步集合的选取是非终结符的follow集;
b)如果终结符在栈顶而不能匹配,弹出此终结符。
c)输入栈中缺少某些应有的符号,比如只有右括号没有左括号等,会给出相应的提示。
(4)系统的输入形式多样:
可以通过文件导入文法和测试用例,可以通过用户界面显示并编辑测试用例。
测试用例涵盖了第
(1)条中列出的各种类型的语句,并设置了一些语法错误。
(5)系统的输出分为两部分:
一部分是打印输出语法分析器的FIRST集、FOLLOW集、select
集和LL
(1)分析表。
另一部分是打印输出语法分析结果。
(6)本系统还实现了输出语法分析树的功能,让语法分析的过程更清晰。
二、文法设计得分
要求:
给出如下语言成分的文法描述。
声明语句(包括变量声明、数组声明、记录声明和过程声明)
表达式及赋值语句(包括数组元素的引用和赋值)
分支语句:
if_then_else
循环语句:
do_while
过程调用语句
本语法分析器主要针对C语言进行文法设计,下面给出各语言成分的文法描述。
程序入口:
Program->P
P->DP//支持连续声明
P->SP
P->ε
1)声明语句:
Dprocid;DS|Tid;
//支持过程声明和变量声明
T→
X→
XC|recordD//支持结构体声明
short|int|long|float|double|char|string//支持多种基本类型的声明
C→
[num]C|
ε
//支持数组的声明
2)表达式及赋值语句:
Sid=E;|L=E;
EE+E|E*E|E|(E)|id|digit|L
Lid[E]|L[E]//支持数组元素的引用和赋值
3)控制流语句:
SifBthenS1elseS2|whileBdoS1
B→
B||B
//或语句
|B&&B
|!
B
//且语句
//非语句
|(B)
|Erelop
|true
|false
E
//使用括号
//关系语句
//bool型
//bool型
relop
→
<|<=|==|!
=|>|>=
//关系符号
4)过程调用语句
Scallid
(Elist)
Elist
Elist,E
Elist
E
下面给出整个程序的无二义性,无左递归的
LL
(1)文法:
Program->P
P->DP|SP|empty
D->procTid(M){P}|TidA;|recordid{P}
M->XidM'
M'->,XidM'|empty
A->=F|empty|,idA
F->digit|id|char|{G}|string
G->HG'
G'->,HG'|empty
H->digit|char
T->XC
X->short|int|long|float|double|char|void|string|boolean
C->[digit]C|empty
S->L=E;|ifBthenSelseS|whileBdoS|callid(Elist);|returnE;E->-EE'|(E)E'|digitE'|LE'|stringE’
E'->+EE'|*EE'|empty
L->idL'
L'->[digit]L'|empty
B->!
BB'|(B)B'|ErelopEB'|trueB'|falseB'
B'->orBB'|andBB'|empty
relop-><|<=|==|!
=|>|>=
Elist->EElist'
Elist'->,EElist'|empty
注:
此处用empty代表空
三、系统设计得分
要求:
分为系统概要设计和系统详细设计。
(1)系统概要设计:
给出必要的系统宏观层面设计图,如系统框架图、数据流图、功能模块结构图等以及相应的文字说明。
1)系统的数据流图:
说明
说明:
本语法分析器是基于上一个实验词法分析器的基础上,通过在界面写或者是导入源程序,词法分析器将源程序识别的词法单元传递给语法分析器,语法分析器验证这个词法单元
组成的串是否可以由源语言的文法生成,能够输出语法分析的结果,文法的first集、follow集和预测分析表,当然也可以以易于理解的方式报告语法错误。
2)系统框架图
本系统框架主要是三部分,一部分是词法分析,负责识别源程序的词法单元识别,并将其存
储,以供语法分析时读取;第二部分是文法分析部分,负责将导入的文法进行分析,得出文法的first集和follow集,以及自动构造出预测分析表,在语法分析时进行查询;第三部分是用户界面,提供源程序输入功能,以及语法分析结果的显示,显示语法分析树,还有集、follow集和预测分析表的展示。
first
(2)系统详细设计:
对如下工作进行展开描述核心数据结构的设计
核心数据结构主要有两种:
1)Tuple三元组
为了存储预测分析表,我使用Tuple三元组的数据结构,分别存储产生式的头部,产生式体,输入符号。
2)Stack栈
为了能够在语法分析时根据预测分析表来进行分析,我写了一个CStack的类用来实现栈的
数据结构,在进行语法分析时,一个栈用来存储文法符号,一个栈用来存储输入符号,然后根据预测分析表进行语法分析。
主要功能函数说明
主要功能函数:
1)IDContent类:
功能:
充当符号表的角色,主要是用来保存关键字,运算符,界符,转义字符等各类单词。
主要函数:
boolisConstCh(stringstr)//判断是否转义字符
boolisLetter_(charc)//判断是否字母或下划线boolisDigit(charc)//判断是否数字
boolisBlank(charc)//判断是否是空格、制表符、换行、回车boolisKeyWord(stringstr)//判断是否关键字boolisBoundary(charc)//判断是否是边界符号
boolisOperator(stringch)//判断是否运算符
2)Identifier类
功能:
识别单词的核心类
主要函数:
string
isID(
string
str,
ref
int
i)//
是否是标识符
string
isSixteen(
string
str,
ref
int
i,
out
boolright)//
是否16进制数
string
isEight(
string
str,
ref
int
i,
out
boolright)//是否8进制数
string
isNumber(
string
str,
refint
i,
out
boolright)//
是否是常数
string
isOperator(
string
str,
ref
int
i,
out
boolright)//是否是运算符
string
isNote(
string
str,
ref
int
i,
out
bool
right)//
是否注释
string
isBoundary(string
str,
ref
int
i,
out
boolright)//
是否界符
string
isChar(
string
str,
ref
int
i,
out
bool
right)//
是否字符常数
3)FirstAndFollow
类
功能:
得到first
集、follow
集、select集、预测分析表
public
voidgetFirstCollection()//
得到first
集合
public
voidgetFollowCollection()//
得到follow
集合
public
voidgetSelectCollection()//
得到预测分析表
public
voidgetAnalysisTable(
string
str1,
stringstr2,
stringstr3)//得到预测分析表
public
voiderrorHandle()//
加入同步词法单元
4)CStack类
功能:
栈结构
publicboolisEmpty()//判断栈是否为空
publicvoidpush(objectitem)//往栈中加入一个元素
publicobjectpop()//从栈中弹出一个元素
publicobjectpeek()//返回栈顶对象
5)Form类
public
void
analysis(
stringstr)//
词法单元识别
public
void
parse()//
语法单元识别
private
void
导入文法ToolStripMenuItem_Click(object
sender,
EventArgse)//导入文法
private
void
显示语法分析树ToolStripMenuItem_Click(
object
sender,EventArgse)//输出语
法分析树
private
void
addListview1Item()//
输出first集和follow
集
private
void
addListview3Item()//
输出预测分析表
程序核心部分的程序流程图
语法分析核心部分流程图:
是
输出语法分
析树
文法栈是否为
空
否
报错
是
结束
开始
将文法开始符号压
入文法栈中
从输入栈中读取词
法单元
是是否为$
否
从文法栈中取出栈
顶的符号
弹出文法栈栈顶对
象
弹出文法栈栈顶对
扫描预测分析表象和输入栈栈顶对
象
是
是
将产生式的右部替和输入栈的输
是否是产生式是换文法栈中产生式栈顶是否为ε否入字符是否匹否
的左部配
否
是否是同步词
是弹出文法栈顶对象
法单元
弹出输入栈栈顶对
否
象
四、系统实现及结果分析得分
要求:
对如下内容展开描述。
(1)系统实现过程中遇到的问题;实现过程中主要遇到的问题有:
1)如何修改文法使其时LL
(1)文法
通过对文法的修改,主要是对文法消除左递归,消除二义性,以及提取公因式等,最终
对于相同左部的产生式他们的select集不相交,得到了LL
(1)文法。
2)如何得到文法符号的first集
对于终结符,其first集就是本身,但是对非终结符,在遍历的时候依赖于其他的非终结
符,于是我采用循环遍历的方法,如果当前某个非终结符的first集依赖于其他非终结符,
且其他非终结符的first集还没有求出来,则跳过当前的非终结符求下一个非终结符的first
集,直到其依赖的非终结符的first集求出来后再求解。
直到所有的非终结符的first集求出
来后,循环结束,就得到了所有文法符号的first集合。
3)如何得到非终结符的follow集
为了使思路清晰,我采用两遍遍历的方式来求非终结符的follow集。
第一遍之后,所有非终结符都将得到一个暂时的follow集(不是最终的follow集),第二
遍的目标就是发现其中是否有非终结符的follow集发生了改变,如果改变,则继续遍历整
个文法,直到没有新的符号加入follow集中。
求follow集的具体思想就是:
不断应用下列规则,直到没有新的终结符可以被加入到任何FOLLOW集合中为止
将$放入FOLLOW(S)中,其中S是开始符号,$是输入右端的结束标记
如果存在一个产生式A→αBβ,那么FIRST(β)中除ε之外的所有符号都在
FOLLOW(B)中
如果存在一个产生式
A→αB,或存在产生式
A→αBβ且
FIRST(β)
包含ε,那么
FOLLOW(A)中的所有符号都在FOLLOW(B)中
4)如何根据预测分析表进行语法分析
这里主要依赖于栈的结构,将经过词法分析得到的词法单元压入输入栈,将文法起始符号压入文法栈,然后根据预测分析表得到各个产生式进行语法分析。
(2)输出该句法分析器的分析表;
因为预测分析表实在是过于庞大,因此本处分段截取预测分析表,下面的表是接在上面表的右侧。
(3)针对一测试程序输出其句法分析结果;测试程序:
语法分析结果:
语法分析树:
(4)输出针对此测试程序对应的语法错误报告;带错误的测试程序:
语法错误报告:
(5)
对实验结果进行分析。
总结:
本语法分析器具有强大的语法分析功能
允许变量的连续声明,比如
inta,b,c;
允许声明的同时赋值,比如
stringc=“你好”;
允许对数组的声明和引用,同时进行赋值,比如char[4]a={
‘a’,’;a[0]b’,’=c‘’m;,’’d’}
支持多种类型的声明和赋值,
比如int,short,long,flaot,double,char,string,boolean
的声明和赋值;
允许声明和使用一个过程函数,比如:
/*过程声明,声明一个求两个整数和的函数*/
procintaddSum(inta,intb)
{intc,d;
c=a;/*变量之间的赋值*/
d=b;
returnc+d;/*支持返回值以表达式的形式*/
}
calladdSum(1,2);/*函数调用功能*/
允许声明一种数据结构,比如:
/*记录声明*/
recordstack{
inta;/*表示位置*/
charc;/*表示取值*/
}
强大的错误处理能力:
能够识别非法字符,如:
中文,中文的标点符号;
能够弹出多于的输入字符,如:
inta=1*;
能够处理词法单元的错误,比如:
错误的16进制数,错误的字符串,错误的字符常数,
错误的常数,错误的注释,错误的8进制等;
能够判断是否缺少分量,比如:
inta/*此处缺少分号*/,能够给出提示缺少分号;
能够进行括号的匹配等,比如:
只有左括号无右括号,只有右括号无左括号等,都能进行识别和提醒;
在栈顶的输入符号与文法栈中的符号不匹配时能够根据同步词法单元来弹出非终结符等,继续进行语法分析;
当连续不匹配出现错误时,比如某一行连续错误,能够在下一行重新开始语法分析,避免因为某一行的连续错误导致语法分析停止。
注:
其中的测试样例需先用已编写的词法分析程序进行处理。
指导教师评语:
日期: