编译原理课程实验报告实验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-PP-DP//支持连续声明P-SPP-ε1)声明语句:Dprocid;DS|Tid;//支持过程声明和变量声明T→XC|recordD//支持结构体声明X→short|int|long|float|double|char|string//支持多种基本类型的声明C→[num]C|ε//支持数组的声明2)表达式及赋值语句:Sid=E;|L=E;EE+E|E*E|E|(E)|id|digit|LLid[E]|L[E]//支持数组元素的引用和赋值3)控制流语句:SifBthenS1elseS2|whileBdoS1B→B||B//或语句|B&&B//且语句|!B//非语句|(B)//使用括号|ErelopE//关系语句|true//bool型|false//bool型relop→|=|==|!=||=//关系符号4)过程调用语句Scallid(Elist)ElistElist,EElistE下面给出整个程序的无二义性,无左递归的LL(1)文法:Program-PP-DP|SP|emptyD-procTid(M){P}|TidA;|recordid{P}M-XidM'M'-,XidM'|emptyA-=F|empty|,idAF-digit|id|char|{G}|stringG-HG'G'-,HG'|emptyH-digit|charT-XCX-short|int|long|float|double|char|void|string|booleanC-[digit]C|emptyS-L=E;|ifBthenSelseS|whileBdoS|callid(Elist);|returnE;E--EE'|(E)E'|digitE'|LE'|stringE’E'-+EE'|*EE'|emptyL-idL'L'-[digit]L'|emptyB-!BB'|(B)B'|ErelopEB'|trueB'|falseB'B'-orBB'|andBB'|emptyrelop-|=|==|!=||=Elist-EElist'Elist'-,EElist'|empty注:此处用empty代表空三、系统设计得分要求:分为系统概要设计和系统详细设计。(1)系统概要设计:给出必要的系统宏观层面设计图,如系统框架图、数据流图、功能模块结构图等以及相应的文字说明。1)系统的数据流图:说明说明:本语法分析器是基于上一个实验词法分析器的基础上,通过在界面写或者是导入源程序,词法分析器将源程序识别的词法单元传递给语法分析器,语法分析器验证这个词法单元组成的串是否可以由源语言的文法生成,能够输出语法分析的结果,文法的first集、follow集和预测分析表,当然也可以以易于理解的方式报告语法错误。2)系统框架图本系统框架主要是三部分,一部分是词法分析,负责识别源程序的词法单元识别,并将其存储,以供语法分析时读取;第二部分是文法分析部分,负责将导入的文法进行分析,得出文法的first集和follow集,以及自动构造出预测分析表,在语法分析时进行查询;第三部分是用户界面,提供源程序输入功能,以及语法分析结果的显示,显示语法分析树,还有first集、follow集和预测分析表的展示。(2)系统详细设计:对如下工作进行展开描述核心数据结构的设计核心数据结构主要有两种:1)Tuple三元组为了存储预测分析表,我使用Tuplestring,string,string三元组的数据结构,分别存储产生式的头部,产生式体,输入符号。2)Stack栈为了能够在语法分析时根据预测分析表来进行分析,我写了一个CStack的类用来实现栈的数据结构,在进行语法分析时,一个栈用来存储文法符号,一个栈用来存储输入符号,然后根据预测分析表进行语法分析。主要功能函数说明主要功能函数:1)IDContent类:功能:充当符号表的角色,主要是用来保存关键字,运算符,界符,转义字符等各类单词。主要函数:boolisConstCh(stringstr)//判断是否转义字符boolisLetter_(charc)//判断是否字母或下划线boolisDigit(charc)//判断是否数字boolisBlank(charc)//判断是否是空格、制表符、换行、回车boolisKeyWord(stringstr)//判断是否关键字boolisBoundary(charc)//判断是否是边界符号boolisOperator(stringch)//判断是否运算符2)Identifier类功能:识别单词的核心类主要函数:stringisID(stringstr,refinti)//是否是标识符stringisSixteen(stringstr,refinti,outboolright)//是否16进制数stringisEight(stringstr,refinti,outboolright)//是否8进制数stringisNumber(stringstr,refinti,outboolright)//是否是常数stringisOperator(stringstr,refinti,outboolright)//是否是运算符stringisNote(stringstr,refinti,outboolright)//是否注释stringisBoundary(stringstr,refinti,outboolright)//是否界符stringisChar(stringstr,refinti,outboolright)//是否字符常数3)FirstAndFollow类功能:得到first集、follow集、select集、预测分析表publicvoidgetFirstCollection()//得到first集合publicvoidgetFollowCollection()//得到follow集合publicvoidgetSelectCollection()//得到预测分析表publicvoidgetAnalysisTable(stringstr1,stringstr2,stringstr3)//得到预测分析表publicvoiderrorHandle()//加入同步词法单元4)CStack类功能:栈结构publicboolisEmpty()//判断栈是否为空publicvoidpush(objectitem)//往栈中加入一个元素publicobjectpop()//从栈中弹出一个元素publicobjectpeek()//返回栈顶对象5)Form类publicvoidanalysis(stringstr)//词法单元识别publicvoidparse()//语法单元识别privatevoid导入文法ToolStripMenuItem_Click(objectsender,EventArgse)//导入文法privatevoid显示语法分析树ToolStripMenuItem_Click(objectsender,EventArgse)//输出语法分析树privatevoidaddListview1Item()//输出first集和follow集privatevoidaddListview3Item()//输出预测分析表程序核心部分的程序流程图语法分析核心部分流程图:开始从输入栈中读取词法单元是否为$从文法栈中取出栈顶的符号将文法开始符号压入文法栈中扫描预测分析表是否是产生式是否是同步词法单元将产生式的右部替换文法栈中产生式的左部栈顶是否为ε和输入栈的输入字符是否匹配否是否否是弹出文法栈顶对象弹出文法栈栈顶对象和输入栈栈顶对象是文法栈是否为空是弹出输入栈栈顶对象否弹出文法栈栈顶对象是否结束报错否是输出语法分析树是四、系统实现及结果分析得分要求:对如下内容展开描述。(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)如何根据预测分析表进行语法分析这里主要依赖于栈的结构,将经过词法分析得到的词法单元压入输入栈,将文法起始符号