1、慌模式,能够给出错误提示信息,格式:错误项错误原因行号a)忽略输入中的一些符号, 直到输入中出现选定的同步词法单元集合中的某个词法单元, 同步集合的选取是非终结符的 follow 集;b)如果终结符在栈顶而不能匹配,弹出此终结符。c)输入栈中缺少某些应有的符号,比如只有右括号没有左括号等,会给出相应的提示。(4)系统的输入形式多样:可以通过文件导入文法和测试用例,可以通过用户界面显示并编辑测试用例。测试用例涵盖了第( 1)条中列出的各种类型的语句,并设置了一些语法错误。( 5)系统的输出分为两部分:一部分是打印输出语法分析器的 FIRST 集、 FOLLOW 集、 select集和 LL(1)
2、 分析表。另一部分是打印输出语法分析结果。( 6)本系统还实现了输出语法分析树的功能,让语法分析的过程更清晰。二、文法设计 得分给出如下语言成分的文法描述。本语法分析器主要针对 C 语言进行文法设计,下面给出各语言成分的文法描述。程序入口:Program-PP-D P /支持连续声明SP1) 声明语句:D proc id ; D S| T id;/支持过程声明和变量声明T X X C | record D / 支持结构体声明short|int | long|float|double|char|string /支持多种基本类型的声明C numC |/支持数组的声明2)表达式及赋值语句 :S id
3、 = E ;| L = E ;E E + E | E * E | E | (E) | id | digit | LL idE | LE /支持数组元素的引用和赋值3)控制流语句 :S if B then S1 else S2 | while B do S1B B |B/或语句|B&B| ! B/且语句/非语句| (B)| E relop| true| falseE/使用括号/关系语句/bool 型relop|=/关系符号4)过程调用语句S call id(Elist)ElistElist, E下面给出整个程序的无二义性,无左递归的LL ( 1)文法:D P|S P|emptyD-proc T
4、id ( M ) P |T id A ;|record id P M-X id MM-, X id M|emptyA-= F|empty|, id AF-digit|id|char| G |stringG-H GG, H GH-digit|charT-X CX-short|int|long|float|double|char|void|string|booleanC- digit C|emptyS-L = E ;|if B then S else S|while B do S|call id ( Elist ) ;|return E ; E- E E|( E ) E|digit E|L E|s
5、tring EE+ E E|* E EL-id LL digit LB-! B B|( B ) B|E relop E B|true B|false BBor B B|and B Brelop-Elist-E ElistElist, E Elist注:此处用 empty 代表空三、系统设计 得分分为系统概要设计和系统详细设计。(1) 系统概要设计:给出必要的系统宏观层面设计图,如系统框架图、数据流图、功能模块结构图等以及相应的文字说明。1)系统的数据流图:说明说明:本语法分析器是基于上一个实验词法分析器的基础上,通过在界面写或者是导入源程序,词法分析器将源程序识别的词法单元传递给语法分析器,语
6、法分析器验证这个词法单元组成的串是否可以由源语言的文法生成,能够输出语法分析的结果,文法的 first 集、 follow 集和预测分析表,当然也可以以易于理解的方式报告语法错误。2) 系统框架图本系统框架主要是三部分, 一部分是词法分析, 负责识别源程序的词法单元识别, 并将其存储,以供语法分析时读取;第二部分是文法分析部分,负责将导入的文法进行分析,得出文法的 first 集和 follow 集,以及自动构造出预测分析表,在语法分析时进行查询;第三部分是用户界面,提供源程序输入功能,以及语法分析结果的显示,显示语法分析树,还有集、 follow 集和预测分析表的展示。first(2)系统详
7、细设计:对如下工作进行展开描述核心数据结构的设计核心数据结构主要有两种 :1)Tuple 三元组为了存储预测分析表, 我使用 Tuple 三元组的数据结构, 分别存储产生式的头部,产生式体,输入符号。2)Stack 栈为了能够在语法分析时根据预测分析表来进行分析,我写了一个 CStack 的类用来实现栈的数据结构,在进行语法分析时,一个栈用来存储文法符号,一个栈用来存储输入符号,然后根据预测分析表进行语法分析。主要功能函数说明主要功能函数 :1)IDContent 类:功能:充当符号表的角色,主要是用来保存关键字,运算符,界符,转义字符等各类单词。主要函数: bool isConstCh( s
8、tring str)/ 判断是否转义字符bool isLetter_( char c)/ 判断是否字母或下划线 bool isDigit( char c)/ 判断是否数字bool isBlank( char c)/ 判断是否是空格、制表符、换行、回车 bool isKeyWord( string str)/ 判断是否关键字 bool isBoundary( char c)/ 判断是否是边界符号bool isOperator( string ch)/ 判断是否运算符2) Identifier 类识别单词的核心类 stringisID(stringstr,refinti)/是否是标识符isSixt
9、een(i,outbool right)/是否 16 进制数isEight(bool right)/是否 8 进制数isNumber(ref int是否是常数isOperator(bool right)/是否是运算符isNote(boolright)/是否注释isBoundary( string是否界符isChar(是否字符常数3) FirstAndFollow类得到 first集、 follow集、 select 集、预测分析表publicvoid getFirstCollection()/集合void getFollowCollection()/得到 followvoid getSelec
10、tCollection()/得到预测分析表void getAnalysisTable(str1,string str2,string str3)/ 得到预测分析表void errorHandle()/加入同步词法单元4) CStack 类栈结构public bool isEmpty()/ 判断栈是否为空public void push( object item)/ 往栈中加入一个元素public object pop()/ 从栈中弹出一个元素public object peek()/ 返回栈顶对象5) Form类voidanalysis(string str)/词法单元识别parse()/语法
11、单元识别private导入文法 ToolStripMenuItem_Click( objectsender,EventArgs e)/ 导入文法显示语法分析树 ToolStripMenuItem_Click(objectsender, EventArgs e)/ 输出语法分析树addListview1Item()/输出 first 集和 follow集addListview3Item()/输出预测分析表程序核心部分的程序流程图语法分析核心部分流程图:是输出语法分析树文法栈是否为空否报错结束开始将文法开始符号压入文法栈中从输入栈中读取词法单元是 是否为 $从文法栈中取出栈顶的符号弹出文法栈栈顶对
12、象扫描预测分析表 象和输入栈栈顶对将产生式的右部替 和输入栈的输是否是产生式 是 换文法栈中产生式 栈顶是否为 否 入字符是否匹 否的左部 配是否是同步词是 弹出文法栈顶对象弹出输入栈栈顶对四、系统实现及结果分析 得分对如下内容展开描述。(1) 系统实现过程中遇到的问题;实现过程中主要遇到的问题有:1)如何修改文法使其时 LL ( 1)文法通过对文法的修改,主要是对文法消除左递归,消除二义性,以及提取公因式等,最终对于相同左部的产生式他们的 select 集不相交,得到了 LL ( 1)文法。2)如何得到文法符号的 first 集对于终结符,其 first 集就是本身,但是对非终结符,在遍历的
13、时候依赖于其他的非终结符,于是我采用循环遍历的方法,如果当前某个非终结符的 first 集依赖于其他非终结符,且其他非终结符的 first 集还没有求出来,则跳过当前的非终结符求下一个非终结符的 first集,直到其依赖的非终结符的 first 集求出来后再求解。直到所有的非终结符的 first 集求出来后,循环结束,就得到了所有文法符号的 first 集合。3)如何得到非终结符的 follow 集为了使思路清晰,我采用两遍遍历的方式来求非终结符的 follow 集。第一遍之后,所有非终结符都将得到一个暂时的 follow 集(不是最终的 follow 集),第二遍的目标就是发现其中是否有非终
14、结符的 follow 集发生了改变,如果改变,则继续遍历整个文法,直到没有新的符号加入 follow 集中。求 follow 集的具体思想就是:不断应用下列规则,直到没有新的终结符可以被加入到任何 FOLLOW 集合中为止将 $放入 FOLLOW ( S )中,其中 S 是开始符号, $是输入右端的结束标记如 果存在 一个产 生式 A B,那么 FIRST ( ) 中除 之 外的 所有符号 都在FOLLOW ( B )中如果存在一个产生式A B,或存在产生式A B且FIRST ( )包含 ,那么FOLLOW ( A )中的所有符号都在 FOLLOW ( B )中4)如何根据预测分析表进行语法分
15、析这里主要依赖于栈的结构,将经过词法分析得到的词法单元压入输入栈,将文法起始符号压入文法栈,然后根据预测分析表得到各个产生式进行语法分析。(2) 输出该句法分析器的分析表;因为预测分析表实在是过于庞大,因此本处分段截取预测分析表,下面的表是接在上面表的右侧。(3) 针对一测试程序输出其句法分析结果;测试程序:语法分析结果:语法分析树:(4) 输出针对此测试程序对应的语法错误报告;带错误的测试程序:语法错误报告:(5)对实验结果进行分析。总结:本语法分析器具有强大的语法分析功能允许变量的连续声明,比如int a,b,c;允许声明的同时赋值,比如string c = “你好 ”;允许对数组的声明和
16、引用,同时进行赋值,比如char4 a = a , ;a0b, = cm;, d支持多种类型的声明和赋值,比如 int ,short,long ,flaot ,double,char,string,boolean的声明和赋值;允许声明和使用一个过程函数,比如:/* 过程声明,声明一个求两个整数和的函数 */proc int addSum(int a,int b) int c,d;c = a;/* 变量之间的赋值 */d = b;return c+d;/* 支持返回值以表达式的形式 */call addSum(1,2);/* 函数调用功能 */允许声明一种数据结构,比如:/* 记录声明 */re
17、cord stackint a;/* 表示位置 */char c;/* 表示取值 */强大的错误处理能力:能够识别非法字符,如 :中文,中文的标点符号;能够弹出多于的输入字符,如: int a = 1* ;能够处理词法单元的错误,比如:错误的 16 进制数,错误的字符串,错误的字符常数,错误的常数,错误的注释,错误的 8 进制等;能够判断是否缺少分量,比如 :int a /* 此处缺少分号 */ ,能够给出提示缺少分号;能够进行括号的匹配等,比如:只有左括号无右括号,只有右括号无左括号等,都能进行识别和提醒;在栈顶的输入符号与文法栈中的符号不匹配时能够根据同步词法单元来弹出非终结符等,继续进行语法分析;当连续不匹配出现错误时,比如某一行连续错误,能够在下一行重新开始语法分析,避免因为某一行的连续错误导致语法分析停止。其中的测试样例需先用已编写的词法分析程序进行处理。指导教师评语:日期:
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1