语法分析器实验报告院系:专业:小组成员:学号:日期:一、实验目的根据给出的文法编制LR(1)分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对LR(1)分析法的理解。二、实验内容对已给语言文法,构造LR(1)分析表,编制语法分析程序,要求将错误信息输出到语法错误文件中,并输出分析句子的过程(显示栈的内容)LR(1)分析法的功能:LR(1)分析法的功能是利用LR(1)分析表,对输入符号串自下而上的分析过程。LR(1)分析表的构造及分析过程。三.实验文法program::=block.block::=const-declvar-declproc-declstatementconst-decl::=constconst-assignment-list;|εconst-assignment-list::=ident=number|const-assignment-list,ident=numbervar-decl::=varident-list;|εident-list::=ident|ident-list,identproc-decl::=proc-declprocedureident;block;|εstatement::=ident:=expression|callident|beginstatement-listend|ifconditionthenstatement|whileconditiondostatement|εstatement-list::=statement|statement-list;statementcondition::=oddexpression|expressionrelationexpressionrelation::==||||=|=expression::=term|adding-operatorterm|expressionadding-operatortermadding-operator::=+|-term::=factor|termmultiplying-operatorfactormultiplying-operator::=*|/factor::=ident|number|(expression)注意:(1)ε表示空串。.(2)ident和number分别表示标识符和数。简化的文法:实验环境:MicrosoftWindows7MicrosoftVisualStudio2010实验原理:构造LR(1)项集族的方法SetofltemsCLOSURE(I){repeatfor(I中的每个项[A—α·Bβ,a]for(G中的每个产生式B—γ)for(FIRST(βa)中的每个终结符号b)将[B—·γ,b]加入到集合I中;Until不能向I中加入更多的项;returnI}SetofltemsGOTO(I,X){将J初始化为空集;for(I中的每一个项[A—α·Xβ,a])将项[A—α·Xβ,a]加入到集合J中;returnCLOSURE(J):P—programB—blockV—var-declS—statementE—expressionLident-listT—stateme-nt-listD—conditionR—relationa—varb—begine—end_—:=I—identF—ifT—thenW—whiled—don—number空串—@0P'—P1P—B2B—VS3V—aL;4V—@5L—i6L—L,i7S—i_E8S—bTe9S—fDtS10S—wDdS11S—@12T—S13T—T;S14D—ERE15R—16E—i17E—n18E—(E)}Voiditems(G){将C初始化为{CLOSURE}({[S’—·S,$]});repeatfor(C中的每一个项集I)for(每一个文法符号X)if(GOTO(I,X)非空且不在C中)将GOTO(I,X)加入C中;until不再有新的项集加入到C中;}语法分析表:实验流程图:开始I中A→α.Bβ,aG'中每个产生式B→r,first(βα)中每个终结符将B→.r,b加入I中;得到GOTO(I,X)C初始化{closure},{S→S',$}得到LR(1)项集族I中A→α.Bβ,αG‘中B→r;把B→.r,first(βα)加入I得到closure(I)是否有新的项?是否有新的项?YNYN[A-α.aβ,b]在Ii中,且goto(Ii,a)=Ij将action[I,a]设置为“移入就”[A-α.,a]在Ii中,且Ii中A不等于S’将action[I,a]设置为“规约A→α”将action[I,$]设置为“接受”[S’-S.,$]在Ii中,且Ii中A不等于S’Action[s,a]=移入将t压入栈a为下一个输入符Action[s,a]=规约A→α弹出|β|符号,将t为栈顶状态,将goto[t,,A]压入栈中,输出A→αAction[s,a]=接受结束,分析正确分析完?输出error,结束YNNYNYNNYYYNLR语法分析程序a1……..ai……anSmSm-1……$$ACTIONGOTO输入:栈输出实验结果:输入:beginwhileabdob:=cend.输出:输入:beginwhileabdob:=cend.输出:心得体会:完成本次实验,我们首先要根据题目中给出的文法,构造LR(1)项集族,之后构造LR(1)语法分析表。题目中给出的是pascal语言版的文法,实验开始时我们也稍微学习了一下pascal语言的风格和定义方法。开发的C程序,把构造好的LR(1)语法分析表存入,用数组模拟栈的功能。对词法分析输出的语句,语法分析中,模拟字符的入栈,之后匹配语法分析表匹配出相应的ACTION动作,分析是移入操作还是归约操作。当为移入操作时需要更新栈中栈顶符号和栈顶状态号;当为归约操作时,要根据相应的产生式,把产生式右边的字符弹出栈,出栈字符的个数要根据产生式的长度来判断,状态号的出栈个数也要匹配出栈字符的个数。同时归约之后,要把产生式左边的终结符入栈,终结符入栈之后还要进行GOTO跳转。所谓的入栈操作就是数组的个数增加操作,出栈操作就是数组的减法操作。当时栈操作是从栈顶开始的,所以每一个数组的最后一位(栈顶)要十分明确的处理好,以免发生模拟入栈、出栈错误。关键代码:classactions{public:charaction;//记录s或r等intnum;//记录下标}act[80][30];voidfenxibiao(){inti=0,j;//先全部赋值为e,代表错误for(i=0;i=78;i++){for(j=0;j=24;j++)act[i][j].action='e';}act[0][0].action='s',act[0][0].num=4;act[0][1].action='r',act[0][1].num=4;act[0][4].action='r',act[0][4].num=4;act[0][5].action='r',act[0][5].num=4;act[0][7].action='r',act[0][7].num=4;act[0][15].action='r',act[0][15].num=4;act[0][16].action='',act[0][16].num=1;act[0][17].action='',act[0][17].num=2;act[0][18].action='',act[0][18].num=3;act[1][15].action='a',act[1][15].num=100;//'a'代表接收状态act[2][15].action='r',act[2][15].num=1;act[3][1].action='s',act[3][1].num=7;act[3][4].action='s',act[3][4].num=6;act[3][5].action='s',act[3][5].num=8;act[3][7].action='s',act[3][7].num=9;act[3][15].action='r',act[3][15].num=11;act[3][19].action='',act[3][19].num=5;act[4][4].action='s',act[4][4].num=11;act[4][21].action='',act[4][21].num=10;act[5][15].action='r',act[5][15].num=2;act[6][3].action='s',act[6][3].num=12;act[7][1].action='s',act[7][1].num=16;act[7][2].action='r',act[7][2].num=11;act[7][4].action='s',act[7][4].num=15;act[7][5].action='s',act[7][5].num=17;act[7][7].action='s',act[7][7].num=18;act[7][10].action='r',act[7][0].num=11;act[7][19].action='',act[7][19].num=14;act[7][22].action='',act[7][22].num=13;act[8][4].action='s',act[8][4].num=21;act[8][12].action='s',act[8][12].num=23;act[8][14].action='s',act[8][14].num=22;act[8][20].action='',act[8][20].num=20;act[8][23].action='',act[8][23].num=19;act[9][4].action='s',act[9][4].num=21;act[9][12].action='s',act[9][12].num=23;act[9][14].action='s',act[9][14].num=22;act[9][20].action='',act[9][20].num=25;act[9][23].action='',act[9][23].num=24;act[10][9].action='s',act[10][9].num=27;act[10][10].action='s',act[10][10].num=26;act[11][9].action='r',act[11][9].num=5;act[11][10].action='r',act[11][10].num=5;act[12][4].action='s',act[12][4].num=29;act[12][12].action='s',act[12][12].num=31;act[12][14].action='s',act[12][14].num=30;act[12][20].action='',act[12][20].num=28;act[13][2].action='s',act[13][2].num=32;act[13][10].action='s',act[13][10].num=33;act[14][2].action='r',act[14][2].num=12;act[14][10].action='r',act[14][10].n