编译原理预测分析表方法实验报告

合集下载

编译原理实验报告

编译原理实验报告

编译原理实验报告一、实验目的和要求本次实验旨在对PL_0语言进行功能扩充,添加新的语法特性,进一步提高编译器的功能和实用性。

具体要求如下:1.扩展PL_0语言的语法规则,添加新的语法特性;2.实现对新语法的词法分析和语法分析功能;3.对扩展语法规则进行语义分析,并生成中间代码;4.验证扩展功能的正确性。

二、实验内容1.扩展语法规则本次实验选择扩展PL_0语言的语句部分,添加新的控制语句,switch语句。

其语法规则如下:<switch_stmt> -> SWITCH <expression> CASE <case_list><default_stmt> ENDSWITCH<case_list> -> <case_stmt> , <case_stmt> <case_list><case_stmt> -> CASE <constant> : <statement><default_stmt> -> DEFAULT : <statement> ,ε2.词法分析和语法分析根据扩展的语法规则,需要对新的关键字和符号进行词法分析,识别出符号类型和记号类型。

然后进行语法分析,建立语法树。

3.语义分析在语义分析阶段,首先对switch语句的表达式进行求值,判断其类型是否为整型。

然后对case语句和default语句中的常量进行求值,判断是否与表达式的值相等。

最后将语句部分生成中间代码。

4.中间代码生成根据语法树和语义分析的结果,生成对应的中间代码。

例如,生成switch语句的跳转表,根据表达式的值选择相应的跳转目标。

5.验证功能的正确性设计一些测试用例,验证新语法的正确性和扩展功能的实用性。

三、实验步骤与结果1.扩展语法规则,更新PL_0语法分析器的词法规则和语法规则。

编译原理实验报告材料LL(1)分析报告法84481

编译原理实验报告材料LL(1)分析报告法84481

课程编译原理实验名称实验二 LL(1)分析法实验目的1.掌握LL(1)分析法的基本原理;2.掌握LL(1)分析表的构造方法;3.掌握LL(1)驱动程序的构造方法。

一.实验内容及要求根据某一文法编制调试LL(1)分析程序,以便对任意输入的符号串进行分析。

本次实验的目的主要是加深对预测分析LL(1)分析法的理解。

对下列文法,用LL(1)分析法对任意输入的符号串进行分析:(1)E->TG(2)G->+TG(3)G->ε(4)T->FS(5)S->*FS(6)S->ε(7)F->(E)(8)F->i程序输入一以#结束的符号串(包括+*()i#),如:i+i*i#。

输出过程如下:步骤分析栈剩余输入串所用产生式1 E i+i*i# E->TG... ... ... ...二.实验过程及结果代码如下:#include<iostream>#include "edge.h"using namespace std;edge::edge(){cin>>left>>right;rlen=right.length();if(NODE.find(left)>NODE.length())NODE+=left;}string edge::getlf(){return left;}string edge::getrg(){return right;}string edge::getfirst(){return first;}string edge::getfollow(){return follow;}string edge::getselect(){return select;}string edge::getro(){string str;str+=right[0];return str;}int edge::getrlen(){return right.length();}void edge::newfirst(string w){int i;for(i=0;i<w.length();i++)if(first.find(w[i])>first.length())first+=w[i];}void edge::newfollow(string w){int i;for(i=0;i<w.length();i++)if(follow.find(w[i])>follow.length()&&w[i]!='@')follow+=w[i];}void edge::newselect(string w){int i;for(i=0;i<w.length();i++)if(select.find(w[i])>select.length()&&w[i]!='@') select+=w[i];}void edge::delfirst(){int i=first.find('@');first.erase(i,1);}int SUM;string NODE,ENODE;//计算firstvoid first(edge ni,edge *n,int x){int i,j;for(j=0;j<SUM;j++){if(ni.getlf()==n[j].getlf()){if(NODE.find(n[j].getro())<NODE.length()){for(i=0;i<SUM;i++)if(n[i].getlf()==n[j].getro())first(n[i],n,x);}elsen[x].newfirst(n[j].getro());}}}//计算followvoid follow(edge ni,edge *n,int x){int i,j,k,s;string str;for(i=0;i<ni.getrlen();i++){s=NODE.find(ni.getrg()[i]);if(s<NODE.length()&&s>-1) //是非终结符if(i<ni.getrlen()-1) //不在最右for(j=0;j<SUM;j++)if(n[j].getlf().find(ni.getrg()[i])==0){if(NODE.find(ni.getrg()[i+1])<NODE.length()){for(k=0;k<SUM;k++)if(n[k].getlf().find(ni.getrg()[i+1])==0){n[j].newfollow(n[k].getfirst());if(n[k].getfirst().find("@")<n[k].getfirst().length())n[j].newfollow(ni.getfollow());}}else{str.erase();str+=ni.getrg()[i+1];n[j].newfollow(str);}}}}//计算selectvoid select(edge &ni,edge *n){int i,j;if(ENODE.find(ni.getro())<ENODE.length()){ni.newselect(ni.getro());if(ni.getro()=="@")ni.newselect(ni.getfollow());}elsefor(i=0;i<ni.getrlen();i++){for(j=0;j<SUM;j++)if(ni.getrg()[i]==n[j].getlf()[0]){ni.newselect(n[j].getfirst());if(n[j].getfirst().find('@')>n[j].getfirst().length())return;}}}//输出集合void out(string p){int i;if(p.length()==0)return;cout<<"{";for(i=0;i<p.length()-1;i++){cout<<p[i]<<",";}cout<<p[i]<<"}";}//连续输出符号void outfu(int a,string c){int i;for(i=0;i<a;i++)cout<<c;}//输出预测分析表void outgraph(edge *n,string (*yc)[50]){int i,j,k;bool flag;for(i=0;i<ENODE.length();i++){if(ENODE[i]!='@'){outfu(10," ");cout<<ENODE[i];}}outfu(10," ");cout<<"#"<<endl;int x;for(i=0;i<NODE.length();i++){outfu(4," ");cout<<NODE[i];outfu(5," ");for(k=0;k<ENODE.length();k++){flag=1;for(j=0;j<SUM;j++){if(NODE[i]==n[j].getlf()[0]){x=n[j].getselect().find(ENODE[k]);if(x<n[j].getselect().length()&&x>-1){cout<<"->"<<n[j].getrg();yc[i][k]=n[j].getrg();outfu(9-n[j].getrlen()," ");flag=0;}x=n[j].getselect().find('#');if(k==ENODE.length()-1&&x<n[j].getselect().length()&&x>-1){cout<<"->"<<n[j].getrg();yc[i][j]=n[j].getrg();}}}if(flag&&ENODE[k]!='@')outfu(11," ");}cout<<endl;}}//分析符号串int pipei(string &chuan,string &fenxi,string (*yc)[50],int &b) {char ch,a;int x,i,j,k;b++;cout<<endl<<" "<<b;if(b>9)outfu(8," ");elseoutfu(9," ");cout<<fenxi;outfu(26-chuan.length()-fenxi.length()," "); cout<<chuan;outfu(10," ");a=chuan[0];ch=fenxi[fenxi.length()-1];x=ENODE.find(ch);if(x<ENODE.length()&&x>-1){if(ch==a){fenxi.erase(fenxi.length()-1,1);chuan.erase(0,1);cout<<"'"<<a<<"'匹配";if(pipei(chuan,fenxi,yc,b))return 1;elsereturn 0;}elsereturn 0;}else{if(ch=='#'){if(ch==a){cout<<"分析成功"<<endl;return 1;}elsereturn 0;}elseif(ch=='@'){fenxi.erase(fenxi.length()-1,1);if(pipei(chuan,fenxi,yc,b))return 1;elsereturn 0;}else{i=NODE.find(ch);if(a=='#'){x=ENODE.find('@');if(x<ENODE.length()&&x>-1)j=ENODE.length()-1;elsej=ENODE.length();}elsej=ENODE.find(a);if(yc[i][j].length()){cout<<NODE[i]<<"->"<<yc[i][j];fenxi.erase(fenxi.length()-1,1);for(k=yc[i][j].length()-1;k>-1;k--)if(yc[i][j][k]!='@')fenxi+=yc[i][j][k];if(pipei(chuan,fenxi,yc,b))return 1;elsereturn 0;}elsereturn 0;}}}void main(){edge *n;string str,(*yc)[50];int i,j,k;bool flag=0;cout<<"请输入上下文无关文法的总规则数:"<<endl;cin>>SUM;cout<<"请输入具体规则(格式:左部右部,@为空):"<<endl;n=new edge[SUM];for(i=0;i<SUM;i++)for(j=0;j<n[i].getrlen();j++){str=n[i].getrg();if(NODE.find(str[j])>NODE.length()&&ENODE.find(str[j])>ENODE.length()) ENODE+=str[j];}//计算first集合for(i=0;i<SUM;i++){first(n[i],n,i);}//outfu(10,"~*~");cout<<endl;for(i=0;i<SUM;i++)if(n[i].getfirst().find("@")<n[i].getfirst().length()){if(NODE.find(n[i].getro())<NODE.length()){for(k=1;k<n[i].getrlen();k++){if(NODE.find(n[i].getrg()[k])<NODE.length()){for(j=0;j<SUM;j++){if(n[i].getrg()[k]==n[j].getlf()[0]){n[i].newfirst(n[j].getfirst());break;}}if(n[j].getfirst().find("@")>n[j].getfirst().length()){n[i].delfirst();break;}}}}}//计算follow集合for(k=0;k<SUM;k++){for(i=0;i<SUM;i++){if(n[i].getlf()==n[0].getlf())n[i].newfollow("#");follow(n[i],n,i);}for(i=0;i<SUM;i++){for(j=0;j<SUM;j++)if(n[j].getrg().find(n[i].getlf())==n[j].getrlen()-1)n[i].newfollow(n[j].getfollow());}}//计算select集合for(i=0;i<SUM;i++){select(n[i],n);}for(i=0;i<NODE.length();i++){str.erase();for(j=0;j<SUM;j++)if(n[j].getlf()[0]==NODE[i]){if(!str.length())str=n[j].getselect();else{for(k=0;k<n[j].getselect().length();k++)if(str.find(n[j].getselect()[k])<str.length()){flag=1;break;}}}}//输出cout<<endl<<"非终结符";outfu(SUM," ");cout<<"First";outfu(SUM," ");cout<<"Follow"<<endl;outfu(5+SUM,"-*-");cout<<endl;for(i=0;i<NODE.length();i++){for(j=0;j<SUM;j++)if(NODE[i]==n[j].getlf()[0]){outfu(3," ");cout<<NODE[i];outfu(SUM+4," ");out(n[j].getfirst());outfu(SUM+4-2*n[j].getfirst().length()," ");out(n[j].getfollow());cout<<endl;break;}}outfu(5+SUM,"-*-");cout<<endl<<"判定结论: ";if(flag){cout<<"该文法不是LL(1)文法!"<<endl;return;}else{cout<<"该文法是LL(1)文法!"<<endl;}//输出预测分析表cout<<endl<<"预测分析表如下:"<<endl;yc=new string[NODE.length()][50];outgraph(n,yc);string chuan,fenxi,fchuan;cout<<endl<<"请输入符号串:";cin>>chuan;fchuan=chuan;fenxi="#";fenxi+=NODE[0];i=0;cout<<endl<<"预测分析过程如下:"<<endl;cout<<"步骤";outfu(7," ");cout<<"分析栈";outfu(10," ");cout<<"剩余输入串";outfu(8," ");cout<<"推导所用产生式或匹配";if(pipei(chuan,fenxi,yc,i))cout<<endl<<"输入串"<<fchuan<<"是该文法的句子!"<<endl;elsecout<<endl<<"输入串"<<fchuan<<"不是该文法的句子!"<<endl;}截屏如下:三.实验中的问题及心得这次实验让我更加熟悉了LL(1)的工作流程以及LL(1)分析表的构造方法。

编译原理预测分析法实验报告

编译原理预测分析法实验报告

编译原理实验预测分析法姓名**学号**班级**完成日期**1.实验目的加深对语法分析器工作过程的理解;加强对预测分析法实现语法分析程序的掌握;能够采用一种编程语言实现简单的语法分析程序;能够使用自己编写的分析程序对简单的程序段进行语法翻译。

2.实验要求1.对语法规则有明确的定义;2.编写的分析程序能够对实验一的结果进行正确的语法分析;3. 3.对于遇到的语法错误, 能够做出简单的错误处理, 给出简单的错误提示, 保证顺利完成语法分析过程;4. 4.实验报告要求用文法的形式对语法定义做出详细说明, 说明语法分析程序的工作过程, 说明错误处理的实现。

5.实验原理对文法G进行语法分析, 文法G如下所示:*0. S→a */*1. S→.*2. S→(T)*3. T→SW **4..W→,S.*5. W→ε;6.软件设计与编程#include <stdio.h>#include <stdlib.h>#include <string.h>char str[100]; //存储待分析的句子const char T[ ] = "a^(),#"; //终结符, 分析表的列符const char NT[ ] = "STW"; //非终结符, 分析表的行符/*指向产生式右部符号串*/const char *p[] = {/*0. S→a */ "a",/*1.. S→. *. "^",/*2. S→(T) */ "(T)",/*3. T→SW */ "SW",/*4.. W→,S. */ ",SW",/*5. W→ε; */ ""};//设M[i][j]=x, 通过p[M[i][j]]=p[x]获取右部符号串。

const int M[][6] = {/* a ^ ( ) , # *//*S*/ { 0, 1, 2, -1, -1, -1 },/*T*/ { 3, 3, 3, -1, -1, -1 },/*W*/ { -1, -1,-1, 5, 4, -1 }};void init()//输入待分析的句子{printf("请输入待分析的句子(以$结束): \n");scanf("%s",str);}int lin(char c);//非终结符转换为行号int col(char c);//终结转换为列号bool isNT(char c);//isNT判断是否是非终结符bool isT(char c);//isT判断是否是终结符。

编译原理预测分析实验报告

编译原理预测分析实验报告

编译原理实验报告实验题目:预测分析法学院:计算机与通信工程学院专业班级:计算机科学与技术08—2班姓名:学号:预测分析法一、实验目的二、实验要求1、通过该课程设计要学会用消除左递归的方法来使文法满足进行确定自顶向下分析的条件。

2、学会用C/C++高级程序设计语言来设计一个LL(1)分析法的语法分析器;3、通过该课程设计,加深对语法分析理论的理解,培养动手实践的能力。

三、实验代码:#include <stdio.h>#include <tchar.h>#include <string.h>int main(int argc, char* argv[]){char syn[15]; //语法栈int top; //栈顶指针char lookahead; //当前单词char exp[50]; //表达式区int m =0; //表达式指针char s[4][5]={"d","+","*","("}; //表中有空白的符号char string[3]={'E','T','F'}; //表中有同步记号的的非终结符int ll1[7][6]={{1,0,0,1,9,9}, //LL(1)分析表,9表示同步记号,第6行是#,第7行是){0,2,0,0,3,3},{4,9,0,4,9,9},{0,6,5,0,6,6},{8,9,9,7,9,9},{12,12,12,12,12,10},{13,13,13,13,11,13}};int i,j; //表行和列int code; //表项printf("************************语法分析器**********************\n");printf("请输入合法字符串:\n");scanf("%s",exp);top=1;lookahead=exp[m++];syn[0]='#';syn[1]='E';printf("***********************预测分析表*********************\n"); printf("\ti\t *\t +\t (\t )\t #\n");printf(" E\tE—>TE'\t\t\tE—>TE'\n");printf(" E'\t\t\tE'—>+TE'\t E'—>ε\n");printf(" T\tT—>FT'\t\t\tT—>FT'\t\n");printf(" T'\t\tT'—>*FT'\t\t T'—>ε\t\n");printf(" F\tF—>d\t\t\tF—>(E)\n\n");printf("调用规则顺序:\n");while(1){switch(syn[top]) //行{case 'E':i=0;break;case 'e':i=1;break;case 'T':i=2;break;case 't':i=3;break;case 'F':i=4;break;case '#':i=5;break;case ')':i=6;break;}switch(lookahead) //列{case 'd':j=0;break;case '+':j=1;break;case '*':j=2;break;case '(':j=3;break;case ')':j=4;break;case '#':j=5;break;}code=ll1[i][j];if(code==10){ printf("语法分析结束\n");// break;}else{switch(code){case 0:{// printf("出错,用户多输入了%s,跳过%s\n",s[j],s[j]);if(j==0){//lookahead=exp[m++];lookahead=exp[m++];}elselookahead=exp[m++];break;}case 1:{printf("E →TE′\n");syn[top]='e';syn[top+1]='T';top++;break;}case 2:{printf("E′→+TE`\n");syn[top+1]='T';top++;lookahead=exp[m++];break;}case 3:{printf("E′→ε\n");syn[top]='\0';top--;break;}case 4:{printf("T →FT′\n");syn[top]='t';syn[top+1]='F';top++;break;}case 5:{printf("T′→* FT′\n");syn[top+1]='F';top++;lookahead=exp[m++];break;}case 6:{printf("T′→ε\n");syn[top]='\0';top--;break;}case 7:{printf("F →(E)\n");syn[top]=')';syn[top+1]='E';top++;lookahead=exp[m++];break;}case 8:{printf("F →d\n");syn[top]='\0';top--;lookahead=exp[m++];lookahead=exp[m++];break;}case 9:{printf("弹栈,弹出非终结符%c,用户少输入了一个d\n",string[i/2]);syn[top]='\0';top--;break;}case 11:{syn[top]='\0';top--;lookahead=exp[m++];break;}case 13:{printf("弹栈,弹出终结符) ,用户少输入了一个右括号\n");syn[top]='\0';top--;break;}}}}return 0;}实验运行结果:三、总结预测分析法主要是对预测分析表的输出,关键是要理解语法内容和结构。

编译原理课程设计报告-预测分析程序的设计

编译原理课程设计报告-预测分析程序的设计

1课程设计任务书学生姓名: 专业班级:指导教师: 工作单位:题目: 预测分析程序的设计初始条件:1.程序设计语言:主要使用C语言的开发工具, 或者采用LEX、YACC等工具, 也可利用其他熟悉的开发工具。

算法: 可以根据《编译原理》课程所讲授的算法进行设计。

2.要求完成的主要任务: (包括课程设计工作量及其技术要求,说明书撰写等具体要求)3.明确课程设计的目的和重要性, 认真领会课程设计的题目, 读懂课程设计指导书的要求, 学会设计的基本方法与步骤, 学会如何运用前修知识与收集、归纳相关资料解决具体问题的方法。

严格要求自己, 要独立思考, 按时、独立完成课程设计任务。

4.课设任务: 对教材P94中的上下文无关文法, 实现它的预测分析程序, 给出符号串i+i*i的分析过程。

(参考教材P93~96)5.主要功能:对于这个给的LL(1)文法, 假设所有非终结符号P的FIRST集合和FOLLOW集合都是已知的, 构造其预测分析表, 程序显示输出预测分析表, 同时用这个预测分析程序对输入串进行分析, 并给出了栈的变化过程。

进行总体设计, 详细设计:包括算法的设计和数据结构设计。

系统实施、调试, 合理使用出错处理程序。

设计报告: 要求层次清楚、整洁规范、不得相互抄袭。

正文字数不少于0.3万字。

包含内容:①课程设计的题目。

②目录。

③正文: 包括引言、需求分析、总体设计及开发工具的选择, 设计原则(给出语法分析方法及中间代码形式的描述、文法和属性文法的设计), 数据结构与模块说明(功能与流程图)、详细的算法设计、软件调试、软件的测试方法和结果、有关技术的讨论、收获与体会等。

④结束语。

⑤参考文献。

⑥附录: 软件清单(或者附盘)。

时间安排:消化资料、系统调查、形式描述1天系统分析、总体设计、实施计划3天撰写课程设计报告书1天指导教师签名: 2010年 6月 11日系主任(或责任教师)签名: 2010年6月11日目录1引言 (5)2需求分析 (6)2.1问题的提出 (6)2.2问题的解决 (6)2.3解决步骤 (6)3总体设计 (7)3.1概要设计 (7)3.1.1设计原理 (7)3.1.2构造LL(1)分析表 (8)3.2详细设计 (12)3.2.1程序流程图 (12)3.2.2设计要求 (14)3.2.3设计原理 (14)3.2.3.1FIRST(X)(X∈VN VT)的构造 (14)3.2.3.2函数getFIRST(α) (α=X1X2X3…Xn)的构造. 143.2.3.3FOLLOW(A) (A∈VN)的构造 (15)3.2.3.4分析表M【A,a】的构造 (15)3.2.3.5匹配过程的实现 (15)3.3程序设计 (16)3.3.1总体方案设计 (16)3.3.2各模块的实现 (16)4开发工具的选择 (25)5程序测试 (25)6有关技术的讨论 (27)7收获与体会 (28)8参考文献 (29)1引言一个编译程序在对某个源程序完成了词法分析工作之后, 就进入了语法分析阶段, 分析检查源程序是否语法上正确的程序, 并生成相应的内部中间表供下一阶段使用。

编译原理课程实验报告

编译原理课程实验报告
思考题3:如果在语法分析中遇到了语法错误,是应该中断语法分析呢,还是应该进行适当处理后继续语法分析,你是怎么处理的?
五、实验体会
指导教师评语:
日期:
编译原理课程实验报告实验2语法分析院系姓名任课教师实验地点实验课表现学号出勤表现得分操作结果得分指导教师实验时间实验报告得分实验总分一实验目的要求需分析本次实验的基本目的并综述你是如何实现这些目的的二实验内容要求对如下工作进行展开描述1给出如下语言成分的文法描述函数定义或过程定义变量说明赋值表达式循环分支2语法分析程序的总体结构及物理实现3语法分析表及其数据结构和查找算法4语法分析表的生成算法5错误处理错误的位置及类型等三实验结果要求将实验获得的结果进行描述基本内容包括1针对一测试程序输出其语法分析结果2输出针对此测试程序对应的语法错误报告注其中的测试样例需先用已编写的词法分析程序进行处理
变量说明
赋值
表达式
循环
分支
(2)语法分析程序的总体结构及物理实现
(3)语法分析表及其数据结构和查找算法
(4)语法分析表的生成算法
(5)错误处理
错误的位置及类型等
三、实验结果
要求:将实验获得的结果进行描述,基本内容包括:
(1)针对一测试程序输出其语法分析结果;
(2)输出针对此测试程序对应的语法错误报告;
编译原理课程实验报告
实验2:语法分析
姓名
院系
学号
任课教师
指导教师
实验地点
实验时间
实验课表现
出勤、表现得分
实验报告
得分
实验总分
操作结果得分
一、实验目的
要求:需分析本次实验的基本目的,并综述你是如何实现这些目的的?
二、实验内容
要求:对如下工作进行展开描述

编译原理实验报告分析法

编译原理实验报告分析法

工业大学实验报告课程编译原理实验名称实验二LL(1)分析法实验目的1.掌握LL(1)分析法的基本原理;2.掌握LL(1)分析表的构造法;3.掌握LL(1)驱动程序的构造法。

一.实验容及要求根据某一文法编制调试LL(1)分析程序,以便对任意输入的符号串进行分析。

本次实验的目的主要是加深对预测分析LL(1)分析法的理解。

对下列文法,用LL(1)分析法对任意输入的符号串进行分析:(1)E->TG(2)G->+TG(3)G->ε(4)T->FS(5)S->*FS(6)S->ε(7)F->(E)(8)F->i程序输入一以#结束的符号串(包括+*()i#),如:i+i*i#。

输出过程如下:步骤分析栈剩余输入串所用产生式1 E i+i*i# E->TG... ... ... ...二.实验过程及结果代码如下:#include<iostream>#include "edge.h"using namespace std;edge::edge(){cin>>left>>right;rlen=right.length();if(NODE.find(left)>NODE.length())NODE+=left;}string edge::getlf(){return left;}string edge::getrg(){return right;}string edge::getfirst(){return first;}string edge::getfollow(){return follow;}string edge::getselect(){return select;}string edge::getro(){string str;str+=right[0];return str;}int edge::getrlen(){return right.length();}void edge::newfirst(string w){int i;for(i=0;i<w.length();i++)if(first.find(w[i])>first.length())first+=w[i];void edge::newfollow(string w){int i;for(i=0;i<w.length();i++)if(follow.find(w[i])>follow.length()&&w[i]!='@')follow+=w[i];}void edge::newselect(string w){int i;for(i=0;i<w.length();i++)if(select.find(w[i])>select.length()&&w[i]!='@')select+=w[i];}void edge::delfirst(){int i=first.find('@');first.erase(i,1);}int SUM;string NODE,ENODE;//计算firstvoid first(edge ni,edge *n,int x){int i,j;for(j=0;j<SUM;j++){if(ni.getlf()==n[j].getlf()){if(NODE.find(n[j].getro())<NODE.length()){for(i=0;i<SUM;i++)if(n[i].getlf()==n[j].getro())first(n[i],n,x);}elsen[x].newfirst(n[j].getro());}}//计算followvoid follow(edge ni,edge *n,int x){int i,j,k,s;string str;for(i=0;i<ni.getrlen();i++){s=NODE.find(ni.getrg()[i]);if(s<NODE.length()&&s>-1) //是非终结符if(i<ni.getrlen()-1) //不在最右for(j=0;j<SUM;j++)if(n[j].getlf().find(ni.getrg()[i])==0){if(NODE.find(ni.getrg()[i+1])<NODE.length()){for(k=0;k<SUM;k++)if(n[k].getlf().find(ni.getrg()[i+1])==0){n[j].newfollow(n[k].getfirst());if(n[k].getfirst().find("@")<n[k].getfirst().length())n[j].newfollow(ni.getfollow());}}else{str.erase();str+=ni.getrg()[i+1];n[j].newfollow(str);}}}}//计算selectvoid select(edge &ni,edge *n){int i,j;if(ENODE.find(ni.getro())<ENODE.length()){ni.newselect(ni.getro());if(ni.getro()=="@")ni.newselect(ni.getfollow());}elsefor(i=0;i<ni.getrlen();i++){for(j=0;j<SUM;j++)if(ni.getrg()[i]==n[j].getlf()[0]){ni.newselect(n[j].getfirst());if(n[j].getfirst().find('@')>n[j].getfirst().length())return;}}}//输出集合void out(string p){int i;if(p.length()==0)return;cout<<"{";for(i=0;i<p.length()-1;i++){cout<<p[i]<<",";}cout<<p[i]<<"}";}//连续输出符号void outfu(int a,string c){int i;for(i=0;i<a;i++)cout<<c;}//输出预测分析表void outgraph(edge *n,string (*yc)[50]){int i,j,k;bool flag;for(i=0;i<ENODE.length();i++){if(ENODE[i]!='@'){outfu(10," ");cout<<ENODE[i];}}outfu(10," ");cout<<"#"<<endl;int x;for(i=0;i<NODE.length();i++){outfu(4," ");cout<<NODE[i];outfu(5," ");for(k=0;k<ENODE.length();k++){flag=1;for(j=0;j<SUM;j++){if(NODE[i]==n[j].getlf()[0]){x=n[j].getselect().find(ENODE[k]);if(x<n[j].getselect().length()&&x>-1){cout<<"->"<<n[j].getrg();yc[i][k]=n[j].getrg();outfu(9-n[j].getrlen()," ");flag=0;}x=n[j].getselect().find('#');if(k==ENODE.length()-1&&x<n[j].getselect().length()&&x>-1){cout<<"->"<<n[j].getrg();yc[i][j]=n[j].getrg();}}}if(flag&&ENODE[k]!='@')outfu(11," ");}cout<<endl;}}//分析符号串int pipei(string &chuan,string &fenxi,string (*yc)[50],int &b) {char ch,a;int x,i,j,k;b++;cout<<endl<<" "<<b;if(b>9)outfu(8," ");elseoutfu(9," ");cout<<fenxi;outfu(26-chuan.length()-fenxi.length()," ");cout<<chuan;outfu(10," ");a=chuan[0];ch=fenxi[fenxi.length()-1];x=ENODE.find(ch);if(x<ENODE.length()&&x>-1){if(ch==a){fenxi.erase(fenxi.length()-1,1);chuan.erase(0,1);cout<<"'"<<a<<"'匹配";if(pipei(chuan,fenxi,yc,b))return 1;elsereturn 0;}elsereturn 0;}else{if(ch=='#'){if(ch==a){cout<<"分析成功"<<endl;return 1;}elsereturn 0;}elseif(ch=='@'){fenxi.erase(fenxi.length()-1,1);if(pipei(chuan,fenxi,yc,b))return 1;elsereturn 0;}else{i=NODE.find(ch);if(a=='#'){x=ENODE.find('@');if(x<ENODE.length()&&x>-1)j=ENODE.length()-1;elsej=ENODE.length();}elsej=ENODE.find(a);if(yc[i][j].length()){cout<<NODE[i]<<"->"<<yc[i][j];fenxi.erase(fenxi.length()-1,1);for(k=yc[i][j].length()-1;k>-1;k--)if(yc[i][j][k]!='@')fenxi+=yc[i][j][k];if(pipei(chuan,fenxi,yc,b))return 1;elsereturn 0;}elsereturn 0;}}}void main(){edge *n;string str,(*yc)[50];int i,j,k;bool flag=0;cout<<"请输入上下文无关文法的总规则数:"<<endl;cin>>SUM;cout<<"请输入具体规则(格式:左部右部,@为空):"<<endl;n=new edge[SUM];for(i=0;i<SUM;i++)for(j=0;j<n[i].getrlen();j++){str=n[i].getrg();if(NODE.find(str[j])>NODE.length()&&ENODE.find(str[j])>ENODE.length()) ENODE+=str[j];}//计算first集合for(i=0;i<SUM;i++){first(n[i],n,i);}//outfu(10,"~*~");cout<<endl;for(i=0;i<SUM;i++)if(n[i].getfirst().find("@")<n[i].getfirst().length()){if(NODE.find(n[i].getro())<NODE.length()){for(k=1;k<n[i].getrlen();k++){if(NODE.find(n[i].getrg()[k])<NODE.length()){for(j=0;j<SUM;j++){if(n[i].getrg()[k]==n[j].getlf()[0]){n[i].newfirst(n[j].getfirst());break;}}if(n[j].getfirst().find("@")>n[j].getfirst().length()){n[i].delfirst();break;}}}}}//计算follow集合for(k=0;k<SUM;k++){for(i=0;i<SUM;i++){if(n[i].getlf()==n[0].getlf())n[i].newfollow("#");follow(n[i],n,i);}for(i=0;i<SUM;i++){for(j=0;j<SUM;j++)if(n[j].getrg().find(n[i].getlf())==n[j].getrlen()-1)n[i].newfollow(n[j].getfollow());}}//计算select集合for(i=0;i<SUM;i++){select(n[i],n);}for(i=0;i<NODE.length();i++){str.erase();for(j=0;j<SUM;j++)if(n[j].getlf()[0]==NODE[i]){if(!str.length())str=n[j].getselect();else{for(k=0;k<n[j].getselect().length();k++)if(str.find(n[j].getselect()[k])<str.length()){flag=1;break;}}}}//输出cout<<endl<<"非终结符";outfu(SUM," ");cout<<"First";outfu(SUM," ");cout<<"Follow"<<endl;outfu(5+SUM,"-*-");cout<<endl;for(i=0;i<NODE.length();i++){for(j=0;j<SUM;j++)if(NODE[i]==n[j].getlf()[0]){outfu(3," ");cout<<NODE[i];outfu(SUM+4," ");out(n[j].getfirst());outfu(SUM+4-2*n[j].getfirst().length()," ");out(n[j].getfollow());cout<<endl;break;}}outfu(5+SUM,"-*-");cout<<endl<<"判定结论:";if(flag){cout<<"该文法不是LL(1)文法!"<<endl;return;}else{cout<<"该文法是LL(1)文法!"<<endl;}//输出预测分析表cout<<endl<<"预测分析表如下:"<<endl;yc=new string[NODE.length()][50];outgraph(n,yc);string chuan,fenxi,fchuan;cout<<endl<<"请输入符号串:";cin>>chuan;fchuan=chuan;fenxi="#";fenxi+=NODE[0];i=0;cout<<endl<<"预测分析过程如下:"<<endl;cout<<"步骤";outfu(7," ");cout<<"分析栈";outfu(10," ");cout<<"剩余输入串";outfu(8," ");cout<<"推导所用产生式或匹配";if(pipei(chuan,fenxi,yc,i))cout<<endl<<"输入串"<<fchuan<<"是该文法的句子!"<<endl;elsecout<<endl<<"输入串"<<fchuan<<"不是该文法的句子!"<<endl;}截屏如下:三.实验中的问题及心得这次实验让我更加熟悉了LL(1)的工作流程以及LL(1)分析表的构造法。

实验 编译原理预测分析表方法试验报告

实验 编译原理预测分析表方法试验报告

实验7-8 预测分析表方法一、实验目的理解预测分析表方法的实现原理。

二、实验内容:编写一通用的预测法分析程序,要求有一定的错误处理能力,出错后能够使程序继续运行下去,直到分析过程结束。

可通过不同的文法(通过数据表现)进行测试。

三.实验要求:给定算术表达式文法,编写程序,测试数据。

算术表达式文法E→TE’E’→ +TE’|- TE’|εT→FT’T’→*FT’ |/ FT’ |%FT’|εF→(E) |id|num四.实验过程:1.实验代码:import java.io.*;import javax.swing.JOptionPane;public class predict {int length_vn=5,length_vt=10;static int i,j,i1=0,e_flag=0;public predict() {}static String VN[]={"E","e","T","t","F"};static String VT[]={"+","-","*","/","%","(",")","d","n","#";static String CS[]={"Te","+Te","-Te","$","Ft","*Ft","/Ft"," %Ft","","(E)","d","n"};static String follow[][]={{"#",")"},{"#",")"},{"#",")","+","-"},{"#",")","+","-"},{"#",")","+","-","*","/","% "}};static int analysis_table[][]={{-1,-1,-1,-1,-1,0,-1,0,0,-1} ,{1,2,-1,-1,-1,-1,3,-1,-1,3},{-1,-1,-1,-1,-1,4,-1, 4,4,-1},{8,8,5,6,7,-1,8,-1,-1,8},{-1,-1,-1,-1,-1, 9,-1,10,11,-1}};public void locate(String vn,String vt){for(int a=0;a<5;a++){if(VN[a].equals(vn)){i=a;break;}else i=-1;}for(int b=0;b<10;b++){if(VT[b].equals(vt)){j=b;break;}else j=-1;}}public void equal(int vn,int vt){String cs="";if(analysis_table[vn][vt]==-1) {int a;for(a=0;a<follow[vn].length;a++){if(follow[vn][a].equals(VT[vt]))break;}if(a<follow[vn].length)error1();else error2(vt);}else {cs=CS[analysis_table[vn][vt]];int cs_length=cs.length();char achar[]=new char[cs_length];char bchar[]=new char[cs_length];cs.getChars(0,cs_length,achar,0);for(inta=0,b=cs_length-1;a<cs_length;a++,b--){bchar[b]=achar[a];}String newstr=new String(bchar);in_Stack(newstr);}}public void error1(){System.out.println("出错,弹出栈顶符号");}public void error2(int vt){System.out.println("出错,跳过"+VT[vt]);in_Stack(VN[i]);i1++;}public void error3(String str){System.out.println("错误,不匹配终结符"+str);i1++;}public void in_Stack(String str){try{FileWriter fw = new FileWriter("test.txt", true);PrintWriter pw=new PrintWriter(fw);pw.write(str);pw.close();fw.close();}catch(IOException ef){}}public String out_Stack(){String c="";try{Reader du=new FileReader("test.txt"); BufferedReader br = new BufferedReader(du);c=br.readLine();br.close();du.close();File f1=new File("test.txt");f1.delete();}catch(IOException eio){}c=c.trim();Stringsub_str=c.substring(0,c.length()-1);in_Stack(sub_str);Stringzhand=c.substring(c.length()-1,c.length());return zhand;}public static void main(String args[]){File f=new File("test.txt");f.delete();predict pd=new predict();String fenxi;Stringinput=JOptionPane.showInputDialog("请输入算术表达式:");input=input.trim();char gchar[]=new char[1];pd.in_Stack("#E");fenxi="E";while(i1<input.length()){int a,b,c;fenxi=pd.out_Stack();System.out.println("------------------------------------------------");System.out.print("栈顶元素:"+fenxi+'\t');input.getChars(i1,i1+1,gchar,0);String vt=new String(gchar);vt=vt.trim();System.out.print("当前单词记号:"+vt+ "\t");for(c=0;c<10;c++){if(VT[c].equals(fenxi))break;}for(a=0;a<5;a++){if(VN[a].equals(fenxi)){System.out.print("展开非终结符"+fenxi+"->");for(b=0;b<10;b++){if(VT[b].equals(vt)&&analysis_table[a][ b]!=-1){System.out.print(CS[analysis_table[a][b] ]+"\n");break;}}}}if(c<10&&!fenxi.equals(vt)) pd.error3(fenxi);if(fenxi.equals(vt)){System.out.println("匹配终结符"+fenxi+'\t');i1++;}else {pd.locate(fenxi,vt);pd.equal(i,j);}}System.out.println("结束");}}2.试验测试:给定一符合该文法的句子,如d+n/d,运行预测分析程序,给出分析过程和每一步的分析结果,输出形式如下图:给定一不符合该文法的句子,如dd**n,运行预测分析程序,给出分析和每一步的分析过程,并给出对错误的处理分析过程,输出形式如下图:四、实验总结:1.本次通过试验,我学会了预测分析表的构造方法,即给文法的正规式编号:存放在字符数组中,从0开始编号,正规式的编号即为该正规式在数组中对应的下标。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
void push(char a)
{
top++;
stack[top]=a;
}
char pop()
{
return stack[top--];
}
int includevt(char x)
{
for(int i=0;i<length_vt;i++)
{
if(VT[i]==x) return 1;
}
return 0;
}
}
}
else if(includean(x,a)==-1)
{
flag=1;
printf("出错,从栈顶弹出%c\n",x);
x=pop();
}
else
{
flag=1;
printf("出错,跳过%c\n",a);
pp++;
a=aa[pp];
}
}
else
{
flag=1;
printf("出错,跳过%c\n",a);
a=aa[pp]; //将下一输入符号读入a;
}
else
{
flag=1;
printf("出错,跳过%c\n",a);
pp++;
a=aa[pp];
}
}
else if(includean(x,a)>=0)
{
int h=includean(x,a);
printf("展开非终结符%s%s\n",F[h],Fa[h]);
charVT[5]={'a','l','d','b','#'}; //终结符表
intlength_vt=5; //终结符的个数
charFa[6][6]={"aZ","ABl","NULL","dY","bY","NULL"};
charF[6][6]={"A->","Z->","B->","Y->"};
intlength_vn=5;//非终结符的个数
charVT[15][5]={"id","+","*","(",")","#"};//终结符表
intlength_vt=6;//终结符的个数
charFa[15][10]={"TE'","+TE'","","FT'","*FT'","","(E)","id"};
预测分析表方法
一、实验目的
理解预测分析表方法的实现原理。
二、实验内容:
编写一通用的预测法分析程序,要求有一定的错误处理能力,出错后能够使程序继续运行下去,直到分析过程结束。可通过不同的文法(通过数据表现)进行测试。
二、实验内容提示
1.算法数据构造:
构造终结符数组:char Vt[10][5]={“id”,”+”……};
int k;
for(k=0;k<10;k++)
if(Fa[h][k]=='\0') break;
if(k==4)
{
//printf("+++++++++++pop %c \n",x);
}
else
{
while(k!=0) //按逆序依次把yk、yk?1、…、y1压入栈中
{
k--;
push(Fa[h][k]);
}
void destory()
{
int flag=0;
int flagg=0;
push('#'); //将"#"和文法开始符依次压入栈中
push(VN[0]);
char a=aa[pp]; //把第一个输入符号读入a
char x;
do{
if(flag==0)
x=pop(); //把栈顶符号弹出并放入x中
3,-2,-1,3,-2,-2,0,0,0,0,0,
-1,5, 4,-1,5, 5,0,0,0,0,0,
7,-2,-2,6,-2,-2,0,0,0,0,0};
//预测分析表,-1表示出错,-2表示该行终结符的follow集合,用于错误处理,正数表示产生式在数组Fa中的编号,0表示多余的列。
(1)预测分析表的构造方法1
initscanner();
printf("要分析的语句是:%s\n",aa);
printf("语法分析工程如下:\n");
printf("栈顶元素\t\t当前单词记号\t\t\t动作\n");
printf("--------------------------------------------------------------------\n");
-2,-2,-2,1,2,-2,3,-2,-2,3,
-2,-2,-2,-1,-1,4,-1,4,4,-1,
5,6,7,8,8,-2,8,-2,-2,8,
-1,-1,-1,-1,-1,9,-1,10,11,-1};
# else
charVN[4]={'A','Z','B','Y'}; //非终结符表
intlength_vn=4; //非终结符的个数
destory();
return 0;
}
//产生式表:0:E->Te 1:e->+Te 2:e->-Te 3:e->空
charF[12][6]={"E->","e->","e->","e->","T->","t->","t->","t->","t->","F->","F->","F->"};
intanalysis_table[5][10]={-2,-2,-2,-2,-2,0,-1,0,0,-1,
if(x∈VT)
{
if(x==a)将下一输入符号读入a;
elseerror(3);
}
else
if(M[x,a]=“x→y1y2…yk”)
{
按逆序依次把yk、yk−1、…、y1压入栈中;
输出“x→y1y2…yk”;
}
elseifafollow(x)error(1);else error(2);
//在前述的数据定义中查表为-2表示afollow(x)
输出形式参考下图($为结束符):
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define TT 0
char aa[20]=" ";
int pp=0;
# if TT
charVN[5]={'E','e','T','t','F'}; //非终结符表
//产生式表:0:E->TE' 1:E'->+TE' 2:E'->空
// 3:T->FT' 4:T'->*FT' 5:T'->空6:F->(E) 7:F->id
intanalysis_table[10][11]={0,-1,-1,0,-2,-2,0,0,0,0,0,
-1,1,-1,-1,2,2,0,0,0,0,0,
给文法的正规式编号:存放在字符数组中,从0开始编号,正规式的编号即为该正规式在数组中对应的下标。如上述Fa数组表示存储产生式。
构造正规式数组:char P[10][10]={“E-..}; (正规式可只存储右半部分,如E->TE’可存储为TE’,正规式中的符号可替换,如可将E’改为M )
{
If(errornum==1)………………
Else if(errornum==2)……………
Else………………..
//或者可用choose case语句处理
}
4.增加了错误处理的预测分析程序预测分析程序的算法:
将“#”和文法开始符依次压入栈中;
把第一个输入符号读入a;
do{
把栈顶符号弹出并放入x中;
紧急方式的错误恢复方法(抛弃某些符号,继续向下分析)
(1)栈顶为非终结符A,串中当前单词属于FOLLOW(A),则从栈中弹出A(此时可认为输入串中缺少A表示的结构),继续分析。---------错误编号为1
(2)栈顶为非终结符A,串中当前单词不属于FOLLOW(A),则可使串指针下移一个位置(认为输入串中当前单词多余),继续分析。----------错误编号为2
pp++;
a=aa[pp];
}
}while(x!='#');
相关文档
最新文档