编译原理课设报告2
编译原理课程设计报告
《编译原理》课程设计报告一、课程设计目的通过课程设计进一步理解高级语言在计算机中的执行过程,了解现代编译器的运作机制,加深对编译原理中重点算法和编译技术的理解,提高自己自学和理解的能力。
学会如何利用已有软件JFLex、Java_cup对词法分析器及语法分析器的构造。
二、设计概述本tiger语言编译器的编译过程涉及到编译五个阶段中的二个,即词法分析器、语法分析器。
其中语法分析后还完成了语法树的打印的构造以及类型检查。
词法分析器由JFLex编译正则式生成,词法分析器编译产生式生成,语法分析器由CUP生成。
结果通过GUI界面呈现在使用者面前。
编译程序需要在单词级别上来分析和翻译源程序,所以首先要识别出单词,而词法分析部分的任务是:从左至右扫描源程序的字符串,按照词法规则(正则文法规则)识别出一个个正确的单词,并转换成该单词相应的二元式(种别码、属性值)交给语法分析使用。
因此,词法分析是编译的基础。
执行词法分析的程序称为词法分析器。
语法分析是编译程序的核心部分,其主要任务是确定语法结构,检查语法错误,报告错误的性质和位置,并进行适当的纠错工作。
三、设计过程(一)设计构思程序主要完成三大功能模块:词法分析器、语法分析器、GUI人机交互界面。
词法分析器由JFLex编译正则式生成,其中必须为外界提供一个获取记号流的接口,实验中定为java_cup.runtime.Symbol next_token。
语法分析器是建立在词法分析器上的,故必须包含词法分析器以便获得记号流,next_token为语法分析器提供TOKEN,语法分析器的对外接口是:java_cup.runtime.Symbol debug_parse(),同时返回语法树的根节点。
GUI 界面是提供人机交互的,它能够依次显示词法分析阶段分析得到的所有TOKEN 的信息,语法阶段生成的语法树,另外对于词法和语法阶段出现的错误在“错误提示”文本框中一一列举出来,提供用户改进代码的信息。
编译原理课程设计报告
课程设计报告( 2021--2022年度第一学期)名称:编译技术课程设计题目:算符优先分析法研究院系:班级:学号:学生姓名:指导教师:设计周数:一周成绩:日期:2021年12 月31日1 课程设计的目的和要求1.1 课程设计的目的本次设计的时间为1周,目的是通过使用高级语言实现部分算法加强对编译技术和理论的理解。
设计的题目要求具有一定的规模,应涵盖本课程内容和实际应用相关的主要技术。
1.2 课程设计的要求1. 文法使用产生式来定义;2. 分别给出每一个非终结符的FIRSTVT和LASTVT集。
3. 画出算符优先关系表;4. 判定给定的文法是否是算符优先文法;5. 给定符号串判定是否是文法中的句子,分析过程用分析表格的方式打印出来。
2 系统描述举例如下:本次实验使用Visual Studio 2019软件,利用只规定终结符之间的优先关系的自底向上移进-规约法实现对算符优先分析法的研究,输出非终结符的FIRSTVT和LASTVT集,算符优先关系表和对句子的分析表格,均在DOS窗口显示。
2.1 文法的描述G[S]: S->#E#;E->E+T|T;F-P!F|P;T->T*F|F;P->(E)|i2.2 属性文法的描述表2-1 条件语句及其语义规则3 概要设计3.1 概要设计(体现系统的设计思路和主要功能)主要步骤包括:用户自己输入文法,实质上是算数表达式的计算。
构建每个非终结符的FirstVT()和LastVT()集。
构建优先关系符号表。
构建词法分析的程序。
编写主函数,用户输入文法对语句利用算符优先文法进行判别。
算法的主体思想:用栈存储已经看到的输入符号,用优先关系指导移动归约语法分析器的动作,如果栈顶的终结符和下一个输入符之间的优先关系是<或=,则语法分析器移动,表示还没有发现句柄的右端,如果是>关系,就调用归约。
3.2 开发环境实验采用C++程序语言进行设计开发工具为Visual Studio 20194 详细设计4.1 系统的类图图4-1 文法类图4.2 主要算法的流程图图4-2 求非终结符的FIRSTVT 和LASTVT 集流程图求LASTVT 集的过程与此类似,但符号串的扫描顺序是从后开始若产生式右部第一个字符为非终结符 则直接将其加入first 集中else first[x].insert(str[0]);寻找该非终结符 的first 集 dfs(y);将该非终结符的first 集也加进去for (; it != first[y].end(); it++)first[x].insert(*it);if (isupper(str[0]))若产生式右部第一个字符为非终结符 string& left = VN_set[x].left;string&str = VN_set[x].right[i];产生产生式左部非终结符的FIRSTVT 集图4-3 构造算符优先关系表流程图图4-4 对输入串进行算符优先分析流程图4.3 数据分析与定义char relation[MAX][MAX]; //算符优先关系表vector<char> VT;vector<WF> VN_set; //类型为文法的数组VN_setmap<string, int> VN_dic; //map映射,一条产生式对应的第几条的序号set<char> first[MAX]; //FIRSTVT集set<char> last[MAX]; //LASTVT集4.4 系统界面设计用户输入文法个数和每条产生式的内容后,输出结果格式如下:分为:产生式、FIRSTVT集、;LASTVT集、算符优先关系表和分析过程图4-5 系统输出界面概况5 测试方法和测试结果5.1 测试用例1输入如程序5-1所示。
编译原理课程设计报告
2011-2012学年第二学期《编译原理》课程设计报告学院:计算机科学与工程学院班级:学生姓名:学号:成绩:指导教师:时间:2012年5 月目录一、课程设计的目的 ---------------------------------------------------------------- - 1 -二、课堂实验及课程设计的内容 -------------------------------------------------- - 1 -2.1、课堂实验内容-------------------------------------------------------------- - 1 -2.2、课程设计内容-------------------------------------------------------------- - 1 -三、visual studio 2008 简介------------------------------------------------------- - 2 -四、问题分析及相关原理介绍 ----------------------------------------------------- - 3 -4.1、实验部分问题分析及相关原理介绍 ---------------------------------- - 3 -4.1.1、词法分析功能介绍及分析------------------------------------- - 3 -4.1.2、语法分析功能介绍及分析------------------------------------- - 3 -4.1.3、语义分析功能介绍及分析------------------------------------- - 4 -4.2、课程设计部分问题分析及相关原理介绍 ---------------------------- - 5 -4.2.1、编译程序介绍 ----------------------------------------------------- - 5 -4.2.2、对所写编译程序的源语言的描述(C语言) -------------- - 6 -4.2.3、各部分的功能介绍及分析 -------------------------------------- - 7 -4.3、关键算法:单词的识别-------------------------------------------------- - 8 -4.3.1、算法思想介绍 ----------------------------------------------------- - 8 -4.3.2、算法功能及分析 -------------------------------------------------- - 8 -五、设计思路及关键问题的解决方法 ------------------------------------------ - 10 -5.1、编译系统------------------------------------------------------------------ - 10 -5.1.1、设计思路 --------------------------------------------------------- - 10 -5.2、词法分析器总控算法--------------------------------------------------- - 12 -5.2.1、设计思路 --------------------------------------------------------- - 12 -5.2.2、关键问题及其解决方法 --------------------------------------- - 13 -六、结果及测试分析-------------------------------------------------------------- - 14 -6.1、软件运行环境及限制--------------------------------------------------- - 14 -6.2、测试数据说明------------------------------------------------------------ - 14 -6.3、运行结果及功能说明--------------------------------------------------- - 16 -6.4、测试及分析说明--------------------------------------------------------- - 16 -七、总结及心得体会 --------------------------------------------------------------- - 17 -7.1、设计过程------------------------------------------------------------------ - 17 -7.2、困难与收获 ------------------------------------------------------------- - 17 -八、参考文献 ------------------------------------------------------------------------ - 18 -一、课程设计的目的通过设计、编写和调试词法分析程序(又称扫描器),了解扫描器的组成结构,不同种类单词的识别方法,加深了对词法分析作用的理解。
编译原理课程设计报告报告
编译原理课程设计报告一、目的与要求目的:在分析理解一个教学型编译程序(如PL/0)的基础上,对其词法分析程序、语法分析程序和语义处理程序进行部分修改扩充。
达到进一步了解程序编译过程的基本原理和基本实现方法的目的。
要求:对PL/0作以下修改扩充:基本内容(成绩范围:“中”、“及格”或“不及格”)(1)扩充赋值运算:+= 和-=(2)扩充语句REPEAT<语句序列>UNTIL <条件>其中,<条件>是循环条件,即条件不成立时,重复执行循环体的< 语句序列>;条件成立时,循环结束。
选做内容(成绩评定范围扩大到:“优”和“良”)(1)增加运算:++ 和--。
(2)增加类型:①字符类型;②实数类型。
(3)扩充函数:①有返回值和返回语句;②有参数函数。
(4)增加一维数组类型(可增加指令)。
(5)其他典型语言设施。
二、实验环境与工具(1)计算机及操作系统:PC机,WindowsXP(2)程序设计语言:C(3)教学型编译程序:PL/0三、设计方案(1)概述:源、目标语言,实现工具(平台),运行平台源语言: PL/0目标语言: 目标代码(生成的文件后缀为*.COD)实现平台: VC++ 6.0运行平台: WindowsXP(2)结构设计说明:各功能模块描述Error()出错处理,打印出错位置和错误编码GetCh()漏掉空格,读取一个字符GetSym()词法分析,读取一个单词GEN()目标代码生成过程,本过程用于把生成的目标代码写入目标代码数组,供后面的解释器解释执行TEST()测试当前单词是否合法过程testENTER()登陆符号表过程enterPOSITION() 在符号表中查找指定符号所在位置的函数position,如果找不到就返回0V ARDECLARATION()变量声明LISTCODE()列出目标代码清单;FACTOR()因子处理过程factorTERM()项处理过程term;EXPRESSION()表达式处理过程CONDITION()条件处理过程STATEMENT()语句处理过程BLOCK()语法分析过程BASE(): 通过静态链求出数据区基地址的函数,INTERPRET ():对目标代码解释运行过程(3)主要成分描述①符号表struct tablestruct{char name[al]; /* 名字*/enum object kind; /* 类型:const ,var ,procedure*/int val; /* 数值,仅const 使用*/int level; /* 所处层,仅const 不使用*/int adr; /* 地址,仅const 不使用*/Int size; /* 需要分配的数据区空间*/};struct tablestruct table[txmax]; /* 名字表*/②运行时存储组织和管理由于编译时目标程序运行的数据空间大小已经规定,所以存储组织属于静态存储。
南邮编译原理报告实验二
实验报告(2015 / 2016 学年第二学期)课程名称编译原理实验名称语法分析器的构造实验时间2016 年5月26日指导单位计算机软件教学中心指导教师黄海平学生姓名班级学号学院 (系) 计算机学院、专业计算机科学软件学院与技术实验报告实验名称语法分析器的构造指导教师黄海平实验类型验证实验学时4实验时间2016.5.26 一、实验目的和要求实验目的:设计、编制、调试一个LL(1) 语法分析器,利用语法分析器对符号串的识别,加深对语法分析原理的理解。
实验要求:1、检测左递归,如果有则进行消除;2、求解 FIRST 集和 FOLLOW 集;3、构建 LL(1) 分析表;4、构建 LL 分析程序,对于用户输入的句子,能够利用所构造的分析程序进行分析,并显示出分析过程。
以上实验要求可分两个同学完成。
例如构建分析表一个同学完成、构建分析程序并分析符号串另一个同学完成。
二、实验环境 (实验设备 )硬件:计算机软件: Visual C ++6.0二、实验原理及内容实验内容:设计并实现一个LL(1) 语法分析器,实现对算术文法G[E]:E->E+T|TT->T*F|FF->(E)|i所定义的符号串进行识别,例如符号串abc+age+80为文法所定义的句子,符号串 (abc-80(*s5)不是文法所定义的句子。
实验代码:#include<cstdio>#include<string>#include<iostream>using namespace std;void input_grammer(string *G)// 输入文法 G,n个非终结符{int i=0;// 计数char ch='y';while(ch=='y'){cin>>G[i++];cout<<"继续输入 ?(y/n)\n";cin>>ch;}}void preprocess(string *G,string *P,string &U,string &u,int &n,int &t,int &k)// 将文法 G预处理产生式集合 P,非终结符、终结符集合 U、u,{int i,j,r,temp;// 计数char C;//记录规则中()后的符号int flag;// 检测到()n=t=k=0;for( i=0;i<50;i++) P[i]="";// 字符串如果不初始化,在使用P[i][j]=a 时将不能改变,可以用 P[i].append(1,a)U=u="";// 字符串如果不初始化,无法使用U[i]=a 赋值,可以用 U.append(1,a)for(n=0;!G[n].empty();n++){ U[n]=G[n][0];}// 非终结符集合, n为非终结符个数for(i=0;i<n;i++){for(j=4;j<G[i].length();j++){if(U.find(G[i][j])==string::npos&&u.find(G[i][j])==string::npos)if(G[i][j]!='|'&&G[i][j]!='^')//if(G[i][j]!='('&&G[i][j]!=')'&&G[i][j]!='|'&&G[i][j]!='^')u[t++]=G[i][j];}}// 终结符集合, t为终结符个数for(i=0;i<n;i++){flag=0;r=4;for(j=4;j<G[i].length();j++){P[k][0]=U[i];P[k][1]=':';P[k][2]=':';P[k][3]='=';/* if(G[i][j]=='('){j++;flag=1;for(temp=j;G[i][temp]!=')';temp++);C=G[i][temp+1];//C记录()后跟的字符,将 C添加到()中所有字符串后面}if(G[i][j]==')') {j++;flag=0;}*/if(G[i][j]=='|'){//if(flag==1) P[k][r++]=C;k++;j++;P[k][0]=U[i];P[k][1]=':';P[k][2]=':';P[k][3]='=';r=4;P[k][r++]=G[i][j];}else{P[k][r++]=G[i][j];}}k++;}// 获得产生式集合 P,k为产生式个数}int eliminate_1(string *G,string *P,string U,string *GG)//消除文法 G1中所有直接左递归得到文法G2,要能够消除含有多个左递归的情况){string arfa,beta;//所有形如 A::=A α |中β的α、β连接起来形成的字符串arfa、betaint i,j,temp,m=0;// 计数int flag=0;//flag=1 表示文法有左递归int flagg=0;//flagg=1 表示某条规则有左递归char C='A';//由于消除左递归新增的非终结符,从 A 开始增加,只要不在原来问法的非终结符中即可加入for(i=0;i<20&&U[i]!=' ';i++){flagg=0; arfa=beta="";for(j=0;j<100&&P[j][0]!=' ';j++){if(P[j][0]==U[i]){if(P[j][4]==U[i])// 产生式 j有左递归{flagg=1;for(temp=5;P[j][temp]!=' ';temp++) arfa.append(1,P[j][temp]);if(P[j+1][4]==U[i]) arfa.append("|");// 不止一个产生式含有左递归}else{for(temp=4;P[j][temp]!=' ';temp++) beta.append(1,P[j][temp]);if(P[j+1][0]==U[i]&&P[j+1][4]!=U[i]) beta.append("|");}}}if(flagg==0)// 对于不含左递归的文法规则不重写{GG[m]=G[i]; m++;}else{flag=1;//文法存在左递归GG[m].append(1,U[i]);GG[m].append("::=");if(beta.find('|')!=string::npos) GG[m].append("("+beta+")");else GG[m].append(beta);while(U.find(C)!=string::npos){C++;}GG[m].append(1,C);m++;GG[m].append(1,C);GG[m].append("::=");if(arfa.find('|')!=string::npos) GG[m].append("("+arfa+")");else GG[m].append(arfa);GG[m].append(1,C);GG[m].append("|^");m++;C++;}//A::=A α改|写β成 A::= β A,‘A’ =α A'|,β}return flag;}int* ifempty(string* P,string U,int k,int n){int* empty=new int [n];// 指示非终结符能否推导到空串int i,j,r;for(r=0;r<n;r++) empty[r]=0;// 默认所有非终结符都不能推导到空int flag=1;//1 表示 empty数组有修改int step=100;//假设一条规则最大推导步数为步while(step--){for(i=0;i<k;i++){r=U.find(P[i][0]);if(P[i][4]=='^') empty[r]=1;//直接推导到空else{for(j=4;P[i][j]!=' ';j++){if(U.find(P[i][j])!=string::npos){if(empty[U.find(P[i][j])]==0) break;}else break;}if(P[i][j]==' ') empty[r]=1;//多步推导到空else flag=0;}}}return empty;}string* FIRST_X(string* P,string U,string u,int* empty,int k,int n){int i,j,r,s,tmp;string* first=new string[n];char a;int step=100;//最大推导步数while(step--){//cout<<"step"<<100-step<<endl;for(i=0;i<k;i++){//cout<<P[i]<<endl;r=U.find(P[i][0]);if(P[i][4]=='^'&&first[r].find('^')==string::npos)first[r].append(1,'^');// 规则右部首符号为空else{for(j=4;P[i][j]!=' ';j++){a=P[i][j];if(u.find(a)!=string::npos&&first[r].find(a)==string::npos)//规则右部首符号是终结符{first[r].append(1,a);break;//添加并结束}if(U.find(P[i][j])!=string::npos)//规则右部首符号是非终结符,形如 X:: =Y1Y2...Yk{s=U.find(P[i][j]);//cout<<P[i][j]<<":\n";for(tmp=0;first[s][tmp]!='\0';tmp++){a=first[s][tmp];if(a!='^'&&first[r].find(a)==string::npos)//将FIRST[Y1] 中的非空符加入first[r].append(1,a);}}if(!empty[s]) break;// 若Y1不能推导到空,结束}if(P[i][j]==' ')if(first[r].find('^')==string::npos)first[r].append(1,'^');// 若Y1、Y2...Yk 都能推导到空,则加入空符号}}}return first;}string FIRST(string U,string u,string* first,string s)// 求符号串 s=X1X2...Xn 的FIRST集{int i,j,r;char a;string fir;for(i=0;i<s.length();i++){if(s[i]=='^') fir.append(1,'^');if(u.find(s[i])!=string::npos&&fir.find(s[i])==string::npos){fir.append(1,s[i]);break;}//X1 是终结符,添加并结束循环if(U.find(s[i])!=string::npos)//X1 是非终结符{r=U.find(s[i]);for(j=0;first[r][j]!='\0';j++){a=first[r][j];if(a!='^'&&fir.find(a)==string::npos)//将FIRST(X1)中的非空符号加入fir.append(1,a);}if(first[r].find('^')==string::npos) break;// 若X1不可推导到空,循环停止}if(i==s.length())// 若X1-Xk 都可推导到空if(fir.find(s[i])==string::npos)//fir 中还未加入空符号fir.append(1,'^');}return fir;}string** create_table(string *P,string U,string u,int n,int t,int k,string* first)// 构造-13-{int i,j,p,q;string arfa;//记录规则右部string fir,follow;string FOLLOW[5]={")#",")#","+)#","+)#","+*)#"};string **table=new string*[n]; for(i=0;i<n;i++)table[i]=new string[t+1]; for(i=0;i<n;i++)for(j=0;j<t+1;j++)table[i][j]="";//table存储分析表的元素,“”表示 errorfor(i=0;i<k;i++){arfa=P[i];arfa.erase(0,4);//删除前个字符,如: E::=E+T,则arfa="E+T"fir=FIRST(U,u,first,arfa);for(j=0;j<t;j++){p=U.find(P[i][0]);if(fir.find(u[j])!=string::npos){q=j;table[p][q]=P[i];}// 对first()中的每一终结符置相应的规则}if(fir.find('^')!=string::npos){follow=FOLLOW[p];// 对规则左部求 follow()for(j=0;j<t;j++){if((q=follow.find(u[j]))!=string::npos){q=j;table[p][q]=P[i];}// 对follow ()中的每一终结符置相应的规则}table[p][t]=P[i];// 对#所在元素置相应规则}}return table;}void analyse(string **table,string U,string u,int t,string s)//分析符号串 s {string stack;//分析栈string ss=s;//记录原符号串char x;//栈顶符号char a;//下一个要输入的字符int flag=0;// 匹配成功标志int i=0,j=0,step=1;// 符号栈计数、输入串计数、步骤数 int p,q,r;string temp;for(i=0;!s[i];i++){if(u.find(s[i])==string::npos)// 出现非法的符号cout<<s<<"不是该文法的句子 \n";return;}s.append(1,'#');stack.append(1,'#');//进入分’析#栈’stack.append(1,U[0]);i++;//文法开始符进入分析栈a=s[0];//cout<<stack<<endl;cout<<"步骤分析栈余留输入串所用产生式\n";while(!flag){// cout<<" 步骤分析栈余留输入串所用产生式 \n"cout<<step<<""<<stack<<""<<s<<"";x=stack[i];stack.erase(i,1);i--;//取栈顶符号 x,并从栈顶退出//cout<<x<<endl;if(u.find(x)!=string::npos)//x 是终结符的情况{if(x==a){s.erase(0,1);a=s[0];//栈顶符号与当前输入符号匹配,则输入下一个符号cout<<"\n";// 未使用产生式,输出空}else{cout<<"error\n";cout<<ss<<"不是该文法的句子 \n";break;}}if(x=='#'){if(a=='#') {flag=1;cout<<" 成功 \n";}// 栈顶和余留输入串都为#,匹配成功else{cout<<"error\n";cout<<ss<<"不是该文法的句子 \n";break;}}if(U.find(x)!=string::npos)//x 是非终结符的情况{p=U.find(x);q=u.find(a);if(a=='#') q=t;temp=table[p][q];cout<<temp<<endl;//输出使用的产生式if(temp[0]!=' ')// 分析表中对应项不为 error{r=9;while(temp[r]==' ') r--;while(r>3){if(temp[r]!='^'){stack.append(1,temp[r]);//将X::=x1x2... 的规则右部各符号压栈i++;}r--;}}else{cout<<"error\n";cout<<ss<<"不是该文法的句子 \n";break;}}step++;}if(flag) cout<<endl<<ss<<"是该文法的句子 \n";}int main(){int i,j;string *G=new string[50];// 文法 Gstring *P=new string[50];// 产生式集合 Pstring U,u;//文法 G非终结符集合 U,终结符集合 uint n,t,k;// 非终结符、终结符个数 ,产生式数string *GG=new string[50];// 消除左递归后的文法 GGstring *PP=new string[50];// 文法 GG的产生式集合 PPstring UU,uu;//文法 GG非终结符集合 U,终结符集合 uint nn,tt,kk;// 消除左递归后的非终结符、终结符个数,产生式数string** table;// 分析表cout<<"欢迎使用 LL(1) 语法分析器 !\n\n\n";cout<<"请输入文法(同一左部的规则在同一行输入,例如:E::=E+T|T;用 ^表示空串) \n";input_grammer(G);preprocess(G,P,U,u,n,t,k);cout<<"\n该文法有 "<<n<<" 个非终结符: \n";for(i=0;i<n;i++) cout<<U[i];cout<<endl;cout<<"该文法有 "<<t<<" 个终结符: \n";for(i=0;i<t;i++)cout<<u[i];cout<<"\n\n左递归检测与消除 \n\n";if(eliminate_1(G,P,U,GG)){preprocess(GG,PP,UU,uu,nn,tt,kk);cout<<"该文法存在左递归! \n\n消除左递归后的文法 :\n\n"; for(i=0;i<nn;i++)cout<<GG[i]<<endl;cout<<endl;cout<<"新文法有 "<<nn<<" 个非终结符: \n";for(i=0;i<nn;i++)cout<<UU[i];cout<<endl;cout<<"新文法有 "<<tt<<" 个终结符: \n";for(i=0;i<tt;i++)cout<<uu[i];cout<<endl;//cout<<" 新文法有 "<<kk<<" 个产生式: \n";//for(i=0;i<kk;i++)cout<<PP[i]<<endl;}else{cout<<" 该文法不存在左递归 \n";GG=G;PP=P;UU=U;uu=u;nn=n;tt=t;kk=k;}cout<<"求解 FIRST集\n\n";int *empty=ifempty(PP,UU,kk,nn);string* first=FIRST_X(PP,UU,uu,empty,kk,nn);string FOLLOW[5]={")#",")#","+)#","+)#","+*)#"};for(i=0;i<nn;i++)cout<<"FIRST("<<UU[i]<<"):"<<first[i]<<endl;cout<<"求解 FOLLOW 集\n\n";for(i=0;i<nn;i++)cout<<"FOLLOW("<<UU[i]<<"):"<<FOLLOW[i]<<endl; cout<<"\n\n构造文法分析表 \n\n"; table=create_table(PP,UU,uu,nn,tt,kk,first);cout<<"";for(i=0;i<tt;i++) cout<<""<<uu[i]<<"";cout<<"#"<<endl;for( i=0;i<nn;i++){cout<<UU[i]<<"";for(j=0;j<t+1;j++)cout<<table[i][j];cout<<endl;}cout<<"\n\n分析符号串 \n\n"; string s;cout<<"请输入要分析的符号串\n";cin>>s;analyse(table,UU,uu,tt,s); return 0;}实验结果:四、实验小结(包括问题和解决方法、心得体会、意见与建议等)在这次实验中,我又一次复习了,什么是LL( 1)语法分析器,如何对符号串进行分析。
编译原理课程实验报告
五、实验体会
指导教师评语:
日期:
编译原理课程实验报告实验2语法分析院系姓名任课教师实验地点实验课表现学号出勤表现得分操作结果得分指导教师实验时间实验报告得分实验总分一实验目的要求需分析本次实验的基本目的并综述你是如何实现这些目的的二实验内容要求对如下工作进行展开描述1给出如下语言成分的文法描述函数定义或过程定义变量说明赋值表达式循环分支2语法分析程序的总体结构及物理实现3语法分析表及其数据结构和查找算法4语法分析表的生成算法5错误处理错误的位置及类型等三实验结果要求将实验获得的结果进行描述基本内容包括1针对一测试程序输出其语法分析结果2输出针对此测试程序对应的语法错误报告注其中的测试样例需先用已编写的词法分析程序进行处理
变量说明
赋值
表达式
循环
分支
(2)语法分析程序的总体结构及物理实现
(3)语法分析表及其数据结构和查找算法
(4)语法分析表的生成算法
(5)错误处理
错误的位置及类型等
三、实验结果
要求:将实验获得的结果进行描述,基本内容包括:
(1)针对一测试程序输出其语法分析结果;
(2)输出针对此测试程序对应的语法错误报告;
编译原理课程实验报告
实验2:语法分析
姓名
院系
学号
任课教师
指导教师
实验地点
实验时间
实验课表现
出勤、表现得分
实验报告
得分
实验总分
操作结果得分
一、实验目的
要求:需分析本次实验的基本目的,并综述你是如何实现这些目的的?
二、实验内容
要求:对如下工作进行展开描述
编译原理课程设计报告
目录一.课程设计目的┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅2 二.课程设计题目描述和要求┅┅┅┅┅┅┅┅┅┅┅┅┅┅21、算术表达式的描述┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅ 22、课程设计要求描述┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅23、实现的功能描述┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅25、分析器的使用描述┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅3三.课程设计实现描述┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅31、实现平台┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅32、课程设计基本思路描述┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅33、指定向下与递归下降分析方法的基本原理描述┅┅┅┅┅┅44、程序运行的最后界面┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅ 55、演示分析┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅6 四.课程设计总结┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅7 五.实验中的代码描述┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅7 五.参考书目┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅19一、课程设计目的通过设计、编制、调试一个算术表达式的语法及语义分析程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析。
加深对文法分析器的知识的掌握,掌握计算机语言的语法分析的过程。
以及掌握计算机语言的语法分析程序设计与文法应用的实现方法。
能够熟练运用一种分析方法,自上而下或自下而上的方法分析一个给定的文法,我使用的是自上而下的分析方法。
以及通过思考以及动手制作分析器的过程来锻炼自己的编程能力和逻辑思维能力,体会计算机编译器的奥妙之处。
二、课程设计题目描述和要求1、算术表达式的文法的描述:〈无符号整数〉∷=〈数字〉{〈数字〉}〈标识符〉∷=〈字母〉{〈字母〉|〈数字〉}〈表达式〉∷=〈项〉{〈加法运算符〉〈项〉}〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉}〈因子〉∷=〈标志符〉|〈无符号整数〉〈加法运算符〉∷=+|-〈乘法运算符〉∷=*|/〈字母〉∷= a | b | … | z〈数字〉∷= 0 | 1 | … | 92、课程设计的要求描述:1)在递归下降法、LL(1)、算符优先分析法或者LR法中选择其中一种方法完成以上任务,中间代码选用四元式。
四川大学-编译原理课程设计报告
编译原理课程设计报告课题名称:编译原理课程设计C-语言词法与语法分析器的实现提交文档学生姓名:提交文档学生学号:同组成员名单:指导教师姓名:指导教师评阅成绩:指导教师评阅意见:..提交报告时间:年月日C-词法与语法分析器的实现1.课程设计目标(1)题目实用性C-语言拥有一个完整语言的基本属性,通过编写C-语言的词法分析和语法分析,对于理解编译原理的相关理论和知识有很大的作用。
通过编写C-语言词法和语法分析程序,能够对编译原理的相关知识:正则表达式、有限自动机、语法分析等有一个比较清晰的了解和掌握。
(2)C-语言的词法说明①语言的关键字:else if int return void while所有的关键字都是保留字,并且必须是小写。
②专用符号:+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */③其他标记是ID和NUM,通过下列正则表达式定义:ID = letter letter*NUM = digit digit*letter = a|..|z|A|..|Zdigit = 0|..|9注:ID表示标识符,NUM表示数字,letter表示一个字母,digit表示一个数字。
小写和大写字母是有区别的。
④空格由空白、换行符和制表符组成。
空格通常被忽略。
⑤注释用通常的c语言符号/ * . . . * /围起来。
注释可以放在任何空白出现的位置(即注释不能放在标记内)上,且可以超过一行。
注释不能嵌套。
(3)程序设计目标能够对一个程序正确的进行词法及语法分析。
2.分析与设计(1)设计思想a.词法分析词法分析的实现主要利用有穷自动机理论。
有穷自动机可用作描述在输入串中识别模式的过程,因此也能用作构造扫描程序。
通过有穷自动机理论能够容易的设计出词法分析器。
b.语法分析语法分析采用递归下降分析。
递归下降法是语法分析中最易懂的一种方法。
它的主要原理是,对每个非终结符按其产生式结构构造相应语法分析子程序,其中终结符产生匹配命令,而非终结符则产生过程调用命令。
编译原理课程设计报告
武汉纺织大学编译原理课程设计实验报告学院:数学及计算机专业:计算机姓名:班级:学号:编译原理编译原理课设报告一、实验目的加强对编译程序的整体认识和了解,巩固《编译原理》课程所学知识。
通过本次课程设计掌握编译程序调试技巧和设计编译程序一般的原则,加深对词法分析、语法分析、语义分析等编译阶段及实用编译系统的认识。
使学生能将编译理论及实际应用结合起来,提高学生软件开发的能力。
二、实验内容1)仔细阅读PL/0编译程序文本(编译原理(第二版) 张素琴吕映芝蒋维杜戴桂兰主编清华大学出版社),并上机调试通过。
2)对PL/0语言进行下列扩充(1)扩充一维整型数组。
扩充var数组:VAR <数组标识名>(<下界>:<上界>)〈下界〉和〈上界〉可用常量标识名。
(2)扩充条件语句的功能使其为:IF<条件>THEN<语句>[ELSE<语句>](3)增加repeat重复语句:REPEAT<语句>{;<语句>}UNTIL<条件>可根据自己具体情况从中选择2个以上题目进行扩充。
三、实验原理PL/0语言可以看成PASCAL语言的子集,它的编译程序是一个编译解释执行系统。
PL/0的目标程序为假想栈式计算机的汇编语言,及具体计算机无关。
PL/0的编译程序和目标程序的解释执行程序都是用PASCAL语言书写的,因此PL/0语言可在配备PASCAL语言的任何机器上实现。
其编译过程采用一趟扫描方式,以语法分析程序为核心,词法分析和代码生成程序都作为一个独立的过程,当语法分析需要读单词时就调用词法分析程序,而当语法分析正确需要生成相应的目标代码时,则调用代码生成程序。
用表格管理程序建立变量、常量和过程表示符的说明及引用之间的信息联系。
当源程序编译正确时,PL/0编译程序自动调用解释执行程序,对目标代码进行解释执行,并按用户程序的要求输入数据和输出运行结果。
编译原理课程设计报告
实验1:用Lex设计词法分析器1实验目的:学会用lex设计一个词法分析器。
实验内容:使用lex为下述文法语言写一个词法分析器。
实验要求:输入为用该语言所写的源程序文件;输出为记号序列,每个记号显示为二元组(记号名,记号属性值)的形式。
输出可以在屏幕上,也可以输出到文件中。
不要求建立符号表。
在cygwin下用flex和gcc工具将实验调试通过,并能通过例子parser0中testcases 目录下的测试例的测试。
实验参考:和。
语言文法:<程序> PROGRAM <标识符> ; <分程序><分程序> <变量说明> BEGIN <语句表> END.<变量说明> VAR <变量说明表>;<变量说明表><变量表>: <类型> | <变量表>: <类型>; <变量说明表><类型> INTEGER | REAL<变量表> <变量> | <变量>, <变量表><语句表> <语句> | <语句>; <语句表><语句> <赋值语句> | <条件语句> | <WHILE语句> | <复合语句><赋值语句><变量> := <算术表达式><条件语句> IF <关系表达式> THEN <语句> ELSE <语句><WHILE语句> WHILE <关系表达式> DO <语句><复合语句> BEGIN <语句表> END<算术表达式> <项> | <算术表达式> + <项> | <算术表达式> - <项><项> <因式> | <项> * <因式> | <项> / <因式><因式> <变量> | <常数> | (<算术表达式>)<关系表达式> <算术表达式> <关系符> <算术表达式><变量> <标识符><标识符> <标识符><字母> | <标识符><数字> | <字母><常数> <整数> | <浮点数><整数> <数字> | <数字> <整数><浮点数> .<整数> | <整数>.<整数><关系符> < | <= | = | > | >=| <><字母> A | B | …| X | Y | Z | a | b | …| x | y | z<数字>0|1|2|…|9程序代码:%{#include <>#define LT 1#define LE 2#define GT 3#define GE 4#define EQ 5#define NE 6#define PROGRAM 7#define END 13#define VAR 9#define IF 10#define THEN 11#define ELSE 12#define WHILE 18#define DO 19#define ID 20#define NUMBER 21#define RELOP 22#define NEWLINE 23#define ERRORCHAR 24%}delim [ \t \n]ws {delim}+letter [A-Za-z]digit [0-9]id _|{letter}({letter}|{digit})*number {digit}+(\.{digit}+)?(E[+-]?{digit}+)?int1 {digit}|{digit}{int1}*/%s COMMENT%%<INITIAL>"/*" {BEGIN COMMENT;ECHO;} <COMMENT>"*/" {BEGIN INITIAL;ECHO;} <COMMENT>.|\n {ECHO;}/* ECHO是一个宏,相当于 fprintf(yyout, "%s", yytext)*/ <INITIAL>{ws} {;}<INITIAL>while {return (WHILE);}<INITIAL>do {return (DO);}<INITIAL>PROGRAM {return (PROGRAM);}<INITIAL>end {return (END);}<INITIAL>VAR {return (VAR);}<INITIAL>if {return (IF);}<INITIAL>then {return (THEN);}<INITIAL>else {return (ELSE);}<INITIAL>{id} {return (ID);}<INITIAL>{number} {return (NUMBER);}<INITIAL>"<" {return (RELOP);}<INITIAL>"<=" {return (RELOP);}<INITIAL>"=" {return (RELOP);}<INITIAL>"<>" {return (RELOP);}<INITIAL>">" {return (RELOP);}<INITIAL>">=" {return (RELOP);}<INITIAL>"+" {return (RELOP);}<INITIAL>"-" {return (RELOP);}<INITIAL>"*" {return (RELOP);}<INITIAL>"/" {return (RELOP);}<INITIAL>":=" {return (RELOP);}<INITIAL>";" {return (RELOP);}<INITIAL>"." {return (RELOP);}<INITIAL>"," {return (RELOP);}<INITIAL>. {return ERRORCHAR;}%%int yywrap (){return 1;}void writeout(int c){switch(c){case ERRORCHAR: fprintf(yyout, "(ERRORCHAR, \"%s\") ", yytext);break;case RELOP: fprintf(yyout, "(RELOP, \"%s\") ", yytext);break;case WHILE: fprintf(yyout, "(WHILE, \"%s\") ", yytext);break;case DO: fprintf(yyout, "(DO, \"%s\") ", yytext);break;case NUMBER: fprintf(yyout, "(NUM, \"%s\") ", yytext);break;case ID: fprintf(yyout, "(ID, \"%s\") ", yytext);break;case NEWLINE: fprintf(yyout, "\n");break;case PROGRAM: fprintf(yyout, "(PROGRAM, \"%s\") ", yytext);break;case END: fprintf(yyout, "(END, \"%s\") ", yytext);break;case VAR: fprintf(yyout, "(VAR, \"%s\") ", yytext);break;case IF: fprintf(yyout, "(IF, \"%s\") ", yytext);break;case THEN: fprintf(yyout, "(THEN, \"%s\") ", yytext);break;case ELSE: fprintf(yyout, "(ELSE, \"%s\") ", yytext);break;default:break;}return;}int main (int argc, char ** argv){int c,j=0;if (argc>=2){if ((yyin = fopen(argv[1], "r")) == NULL){printf("Can't open file %s\n", argv[1]);return 1;}if (argc>=3){yyout=fopen(argv[2], "w");}}while (c = yylex()){writeout(c);j++;if (j%5 == 0) writeout(NEWLINE);}if(argc>=2){fclose(yyin);if (argc>=3) fclose(yyout);}return 0;}测试文件为:PROGRAM test;VAR i, j, k: INTEGER;f0: REAL;BEGINi := 1;j := 1;k := 0;f0 := ;WHILE k<=100 DOBEGINIF j <20 THENBEGINj := i;k := k+1;f0 := f0*ENDELSEBEGINj := k;k := k-2;f0 := f0/.2ENDENDEND.运行结果:实验2:用Lex设计词法分析器2实验目的:学会用lex设计一个词法分析器,并考虑其与后续语法分析器的链接问题。
编译原理课程设计报告毕业论文
编译原理课程设计报告一、课程设计目的通过课程设计,可以进一步了解高级语言在计算机中的执行过程,了解现代编译器的运行机制,加深对编译原理中关键算法和编译技术的理解,提高自学和理解能力。
了解如何利用现有软件JFLex和Java_cup构造词法分析器和解析器。
二、设计概述这个tiger语言编译器的编译过程涉及到编译五个阶段中的两个,即词法分析器和语法分析器。
其中,解析后完成语法树打印的构建,以检查类型。
词法分析器由JFLex 编译器正则公式生成,词法分析器由编译器产生式生成,解析器由CUP生成。
结果通过GUI界面呈现给用户。
编译器需要对源程序进行单词级的分析和翻译,所以首先要做的就是识别单词,而词法分析的任务就是从左到右扫描源程序的字符串,根据词法规则(常规语法规则)识别出正确的单词,并转换成单词对应的二进制形式(类别码,属性值)进行语法分析。
所以词法分析是编译的基础。
执行词法分析的程序叫做词法分析器。
语法分析是编译器的核心部分。
它的主要任务是确定语法结构,检查语法错误,报告错误的性质和位置,并进行适当的纠错。
三、设计程序(一)设计构思该程序主要完成三个功能模块:词法分析器、语法分析器和GUI人机界面。
词法分析器由JFLex编译正则公式生成,其中必须为外界提供一个获取令牌流的接口。
实验中命名为Java _ cup . runtime . symbol next _ token。
解析器是建立在词法分析器上的,所以它必须包含词法分析器来获取令牌流。
next_token为解析器提供了令牌。
解析器的对外接口是:Java _ cup . runtime . symbol debug _ parse(),它返回语法树的根节点。
GUI 提供人机交互。
它可以顺序显示词法分析阶段获得的所有标记信息和语法阶段生成的语法树。
此外,词法和语法阶段的错误会在“错误提示”文本框中列出,为用户提供改进代码的信息。
流程图:鲍·阿布辛Print.java//打印出语法树……//Tiger 的抽象语法类数据包错误消息ErrorMsg.java//用于生成包含详细信息的错误消息为cupparser 打包Java _ cup.runtime//support包解析Grm.java//解析分析器MainInterface.java//图形用户界面Sym.java//令牌的十进制表示Yylex.java//莱克斯分析器包装语义Entry.java//用于值环境中的绑定Env.java//保存一个值、类型环境和一个错误打印机ExpTy.java//持有翻译和类型检查的结果FunEntry.java//用于函数绑定程序输入流 词法分析程序 GUI 界面句法分析程序 代币 语法树 标记流 错误的语法和类词汇错误Semant.java//主类型检查模块VarEntry.java//用于变量绑定包装符号Symbol.java//使字符串成为独特的符号对象Table.java//用示波器做环境包翻译包类型//描述tiger _ languagetypes(二)词法分析程序这部分工作主要是通过正则表达式的编写,熟悉使用JFLex正确编写正则表达式,并生成相应的词法分析器。
《编译原理》设计方案报告
《编译原理》设计方案报告一、项目概述二、课程目标本课程的主要目标是使学生能够掌握编译器的设计与实现原理,理解编译过程中的各个环节,以及掌握常见的编译器构建工具和技术。
具体目标如下:1.理解编译器的基本原理和工作流程;2.掌握常见的编译器构建工具和技术;3.能够独立设计和实现简单的编译器;4.培养学生的系统设计和问题解决能力。
三、课程内容本课程的主要内容包括:1.编译器的概念和基本原理;2.词法分析器和语法分析器的设计与实现;3.语义分析和中间代码生成;4.优化和目标代码生成;5.编译器构建工具和技术。
四、教学方法本课程采用以学生为中心的教学方法,主要包括以下几种教学手段:1.模块化教学:将课程内容分为多个模块,每个模块进行独立的教学和实践;2.理论与实践相结合:通过理论课、实验课等形式,使学生能够将理论知识应用到实际中;3.项目驱动教学:引入编译器设计与实现的实际项目,让学生能够在实践中巩固所学的知识;4.小组合作学习:将学生分成小组,进行协作学习,增强学生的团队合作能力。
五、评价方式为了评价学生对课程内容的掌握程度,本课程采用以下评价方式:1.平时成绩:包括课堂表现、作业和实验成绩等;2.项目成果:针对编译器设计与实现的项目,评价学生的项目成果和实现质量;3.期末考试:以闭卷考试形式对学生的总体掌握情况进行评价。
六、项目进度安排本课程的项目进度安排如下:1.第1-2周:介绍编译器的概念和基本原理;2.第3-6周:词法分析器和语法分析器的设计与实现;3.第7-9周:语义分析和中间代码生成;4.第10-12周:优化和目标代码生成;5.第13-14周:编译器构建工具和技术;6.第15-16周:项目演示和总结。
七、教学资源支持为了支持本课程的教学,我们将提供以下教学资源:1.教材:选用经典的编译原理教材,如《编译原理》(龙书)等;2.课件:编写详细的课件,包括理论知识和实践案例;3.实验指导:编写实验指导书,引导学生进行编译器设计与实现的实践;4. 实验环境:提供编译器构建工具和开发环境,如Lex/Flex、Yacc/Bison等。
编译课程设计报告
编译课程设计报告一、教学目标本课程的教学目标是使学生掌握编译原理的基本概念、方法和算法,培养学生运用编译原理解决实际问题的能力。
具体目标如下:1.知识目标:(1)了解编译原理的基本概念,如编译器、源语言、目标语言等。
(2)掌握编译过程中的各个阶段,如词法分析、语法分析、语义分析、中间代码生成、目标代码生成等。
(3)熟悉常见编译优化技术,如代码简化、死代码消除、循环优化等。
(4)了解编译器实现的基本方法,如递归下降分析、LL分析、LR分析等。
2.技能目标:(1)能够使用编译原理相关工具,如lex、yacc等。
(2)具备简单的编译器设计与实现能力。
(3)能够分析程序的性能,并应用编译优化技术进行优化。
3.情感态度价值观目标:(1)培养学生对编译原理的兴趣,提高学生自主学习的积极性。
(2)培养学生团队合作精神,提高学生解决实际问题的能力。
二、教学内容本课程的教学内容主要包括以下几个部分:1.编译原理基本概念:介绍编译器、源语言、目标语言等基本概念。
2.编译过程及其各个阶段:讲解词法分析、语法分析、语义分析、中间代码生成、目标代码生成等阶段。
3.编译优化技术:介绍代码简化、死代码消除、循环优化等优化技术。
4.编译器实现方法:讲解递归下降分析、LL分析、LR分析等实现方法。
5.编译器工具使用:介绍lex、yacc等工具的使用方法。
6.编译器设计与实现:讲解编译器的设计与实现过程。
三、教学方法本课程采用讲授法、讨论法、案例分析法和实验法等多种教学方法,以激发学生的学习兴趣和主动性。
1.讲授法:用于讲解编译原理的基本概念、方法和算法。
2.讨论法:学生针对编译原理中的重点、难点问题进行讨论,提高学生的理解能力。
3.案例分析法:通过分析实际案例,使学生更好地掌握编译原理的应用。
4.实验法:让学生亲自动手实现简单的编译器,提高学生的实践能力。
四、教学资源本课程的教学资源包括教材、参考书、多媒体资料和实验设备等。
1.教材:选用《编译原理》等权威教材,为学生提供系统、科学的学习资料。
编译原理实验报告-语法分析
编译原理课程实验报告实验2:语法分析
三、系统设计得分
要求:分为系统概要设计和系统详细设计。
(1)系统概要设计:给出必要的系统宏观层面设计图,如系统框架图、数据流图、功能模块结构图等以及相应的文字说明。
1)系统的数据流图:
说明
说明:本语法分析器是基于上一个实验词法分析器的基础上,通过在界面写或者是导入源程序,词法分析器将源程序识别的词法单元传递给语法分析器,语法分析器验证这个词法单元组成的串是否可以由源语言的文法生成,能够输出语法分析的结果,文法的first集、follow 集和预测分析表,当然也可以以易于理解的方式报告语法错误。
2)系统框架图
本系统框架主要是三部分,一部分是词法分析,负责识别源程序的词法单元识别,并将其存
因为预测分析表实在是过于庞大,因此本处分段截取预测分析表,下面的表是接在上面表的右侧。
(3)针对一测试程序输出其句法分析结果;
测试程序:
语法分析结果:
语法分析树:
(4)输出针对此测试程序对应的语法错误报告;
带错误的测试程序:
语法错误报告:
(5)对实验结果进行分析。
总结:
本语法分析器具有强大的语法分析功能
●允许变量的连续声明,比如int a,b,c;
●允许声明的同时赋值,比如string c = “你好”;
●允许对数组的声明和引用,同时进行赋值,比如char[4] a = {‘a’,’b’,’c’,’d’};a[0] = ‘m’;
●支持多种类型的声明和赋值,比如int,short,long,flaot,double,char,string,boolean
的声明和赋值;
●允许声明和使用一个过程函数,比如:。
编译原理课设报告2
编译原理课程设计题目:pl/0编译程序的改进与完善学生所在学院:信息科学与工程学院学生所在班级:06级计算机软件1班学生姓名:学生学号:指导教师:张世辉一、课设目的:1.阅读、研究、改进、设计和调试一个简单的编译程序;2.加深对编译程序理论和编译过程的理解。
二、课设内容:1扩充语句for(<语句>;<条件>;<语句>)<语句>;2扩充语句if <条件> then <语句> else <语句>;3扩充语句repeat <语句>;until <条件>;4增加自增自减运算++和—和+=,-=运算;5修改不等号#,为!=;6增加一维数组声明格式:<ident>[<ident>/<number>:<ident>/<number>];赋值格式:<ident>[<index>]:=<表达式>;调用格式:<ident>[<index>]三、程序结构:PL/0源程序图1 编译程序结构图2功能模块调用1.各功能模块的作用:Pl0.c:主程序Error:出错处理,打印出错位置和错误编码Getsym:词法分析,读取一个单词Getch:漏掉空格,读取一个字符Gen:生成目标代码,并送入目标程序区Test:测试当前当前符号是否合法Block:分程序分析处理过程,词法语法分析Enter:登陆名字表Position:查找标识符在名字表中的位置Constdeclaration:常量定义处理Vardeclaraction:变量说明处理Listcode:列出目标代码清单Statement:语句处理Expression:表达式处理Term:项处理Factor:因子处理Condition:条件处理Interpret:对目标代码的解释执行程序Base:通过静态链求出数据取得基地址增加两个功能:Arraydeclaration:数组声明处理Arraycoef:数组索引计算和“虚拟机”动作生成2.保留字:enum symbol {nul, ident, number, plus, minus, times, slash, oddsym, eql, neq,lss, leq, gtr, geq, lparen,rparen, comma, semicolon, period, becomes,beginsym, endsym, ifsym, thensym,elsesym,forsym, inc, dec, whilesym, writesym,readsym, dosym, callsym, constsym,varsym,procsym, repeatsym, untilsym, plusbk, minusbk,lbrack, rbrack, colon,}共43个,其中补充保留字为:else, for, repeat, until, plusbk, minusbk,Lbrack, rbrack, colon3.虚拟机代码enum fct { lit, opr, lod, sto, cal, inte, jmp, jpc, lda, sta, }共10个,补充的lda,sta用于数组操作4.名字表中的类型enum object{ constant, variable, procedure, arrays, }共4个,扩充arrays,以便实现数组5.名字表结构struct tablestruct{char name[al];enum object kind;int val;int level;int adr;int size;//扩充名字表结构,增加一个data域保存数组的下界int data; /* 其他数据,对arrays来说是下界*/} 6.错误信息表(1) 常数说明中的=写成了:=(2) 常数说明中的=后应是数字(3)常数说明中的标识符后应是=(4) const,var,procedure后应为标识符(5)漏掉了,或;(6)过程说明后的符号不正确(应是语句开始符,或过程定义符)(7)应是语句开始符(8)程序体内语句部分的后跟符不正确(9)程序结尾丢了句号。
编译原理实验报告2-词法分析程序的设计.
实验2 词法分析程序的设计一、实验目的掌握计算机语言的词法分析程序的开发方法。
二、实验内容编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。
三、实验要求1、根据以下的正规式,编制正规文法,画出状态图;标识符<字母>(<字母>|<数字字符>)*十进制整数0 | ((1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*)八进制整数0(1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)*十六进制整数0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)*运算符和界符+ - * / > < = ( ) ;关键字if then else while do2、根据状态图,设计词法分析函数int scan( ),完成以下功能:1)从文本文件中读入测试源代码,根据状态转换图,分析出一个单词,2)以二元式形式输出单词<单词种类,单词属性>其中单词种类用整数表示:0:标识符1:十进制整数2:八进制整数3:十六进制整数运算符和界符,关键字采用一字一符,不编码其中单词属性表示如下:标识符,整数由于采用一类一符,属性用单词表示运算符和界符,关键字采用一字一符,属性为空3、编写测试程序,反复调用函数scan( ),输出单词种别和属性。
四、实验环境PC微机DOS操作系统或Windows 操作系统Turbo C 程序集成环境或Visual C++ 程序集成环境五、实验步骤1、根据正规式,画出状态转换图;2、根据状态图,设计词法分析算法;观察状态图,其中状态2、4、7、10(右上角打了星号)需要回调一个字符。
声明一些变量和函数:ch: 字符变量,存放最新读进的源程序字符。
strToken: 字符串变量,存放构成单词符号的字符串。
编译原理教程实验报告
一、实验目的本次实验旨在使学生通过编译原理的学习,了解编译程序的设计原理及实现技术,掌握编译程序的各个阶段,并能将所学知识应用于实际编程中。
二、实验内容1. 词法分析2. 语法分析3. 语义分析4. 中间代码生成5. 代码优化6. 目标代码生成三、实验步骤1. 词法分析(1)设计词法分析器,识别输入源代码中的各种词法单元;(2)使用C语言实现词法分析器,并进行测试。
2. 语法分析(1)根据文法规则设计语法分析器,识别输入源代码的语法结构;(2)使用C语言实现语法分析器,并进行测试。
3. 语义分析(1)设计语义分析器,检查语法分析后的语法树,确保语义正确;(2)使用C语言实现语义分析器,并进行测试。
4. 中间代码生成(1)设计中间代码生成器,将语义分析后的语法树转换为中间代码;(2)使用C语言实现中间代码生成器,并进行测试。
5. 代码优化(1)设计代码优化器,对中间代码进行优化,提高程序性能;(2)使用C语言实现代码优化器,并进行测试。
6. 目标代码生成(1)设计目标代码生成器,将优化后的中间代码转换为特定目标机的汇编语言;(2)使用C语言实现目标代码生成器,并进行测试。
四、实验结果与分析1. 词法分析实验结果:成功识别输入源代码中的各种词法单元,包括标识符、关键字、运算符、常量等。
2. 语法分析实验结果:成功识别输入源代码的语法结构,包括表达式、语句、程序等。
3. 语义分析实验结果:成功检查语法分析后的语法树,确保语义正确。
4. 中间代码生成实验结果:成功将语义分析后的语法树转换为中间代码,为后续优化和目标代码生成提供基础。
5. 代码优化实验结果:成功对中间代码进行优化,提高程序性能。
6. 目标代码生成实验结果:成功将优化后的中间代码转换为特定目标机的汇编语言,为程序在目标机上运行做准备。
五、实验心得1. 编译原理是一门理论与实践相结合的课程,通过本次实验,我对编译程序的设计原理及实现技术有了更深入的了解。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编译原理课程设计题目:pl/0编译程序的改进与完善学生所在学院:信息科学与工程学院学生所在班级:06级计算机软件1班学生姓名:学生学号:指导教师:张世辉一、课设目的:1.阅读、研究、改进、设计和调试一个简单的编译程序;2.加深对编译程序理论和编译过程的理解。
二、课设内容:1扩充语句for(<语句>;<条件>;<语句>)<语句>;2扩充语句if <条件> then <语句> else <语句>;3扩充语句repeat <语句>;until <条件>;4增加自增自减运算++和—和+=,-=运算;5修改不等号#,为!=;6增加一维数组声明格式:<ident>[<ident>/<number>:<ident>/<number>];赋值格式:<ident>[<index>]:=<表达式>;调用格式:<ident>[<index>]三、程序结构:PL/0源程序图1 编译程序结构图2功能模块调用1.各功能模块的作用:Pl0.c:主程序Error:出错处理,打印出错位置和错误编码Getsym:词法分析,读取一个单词Getch:漏掉空格,读取一个字符Gen:生成目标代码,并送入目标程序区Test:测试当前当前符号是否合法Block:分程序分析处理过程,词法语法分析Enter:登陆名字表Position:查找标识符在名字表中的位置Constdeclaration:常量定义处理Vardeclaraction:变量说明处理Listcode:列出目标代码清单Statement:语句处理Expression:表达式处理Term:项处理Factor:因子处理Condition:条件处理Interpret:对目标代码的解释执行程序Base:通过静态链求出数据取得基地址增加两个功能:Arraydeclaration:数组声明处理Arraycoef:数组索引计算和“虚拟机”动作生成2.保留字:enum symbol {nul, ident, number, plus, minus, times, slash, oddsym, eql, neq,lss, leq, gtr, geq, lparen,rparen, comma, semicolon, period, becomes,beginsym, endsym, ifsym, thensym,elsesym,forsym, inc, dec, whilesym, writesym,readsym, dosym, callsym, constsym,varsym,procsym, repeatsym, untilsym, plusbk, minusbk,lbrack, rbrack, colon,}共43个,其中补充保留字为:else, for, repeat, until, plusbk, minusbk,Lbrack, rbrack, colon3.虚拟机代码enum fct { lit, opr, lod, sto, cal, inte, jmp, jpc, lda, sta, }共10个,补充的lda,sta用于数组操作4.名字表中的类型enum object{ constant, variable, procedure, arrays, }共4个,扩充arrays,以便实现数组5.名字表结构struct tablestruct{char name[al];enum object kind;int val;int level;int adr;int size;//扩充名字表结构,增加一个data域保存数组的下界int data; /* 其他数据,对arrays来说是下界*/} 6.错误信息表(1) 常数说明中的=写成了:=(2) 常数说明中的=后应是数字(3)常数说明中的标识符后应是=(4) const,var,procedure后应为标识符(5)漏掉了,或;(6)过程说明后的符号不正确(应是语句开始符,或过程定义符)(7)应是语句开始符(8)程序体内语句部分的后跟符不正确(9)程序结尾丢了句号。
(10)语句之间漏了;(11)标识符未说明(12)赋值语句中,赋值号左部标识符属性应是变量(13)赋值号左部标识符属性应是赋值号(14)call后应为标识符(15)call后标识符属性应为过程(16)条件语句中丢了then(17)丢了end或;(18)while循环语句中丢了do(19)语句后的符号不正确(20)应为关系运算符(21)表达式内标识符属性不能是过程(22)表达式中漏掉右括号)(23)因子后的非法符号(24)表达式的开始符不能使此符号(31)数越界(32)read语句括号中的标识符不是变量补充错误处理:(50)数组格式错误(51)数组访问错误7.语法描述图:图3 程序语法描述图图4 分程序语法描述图图5 语句语法描述图图6条件语法描述图图7 表达式语法描述图图8 项语法描述图图9 因子语法描述图四、功能扩充1.在语句处理中增加repeat-until语句if(sym == repeatsym){cx1 = cx;getsymdo;statementdo(nxtlev, ptx, lev);if(sym == untilsym){getsymdo;conditiondo(nxtlev, ptx, lev);cx2=cx;gendo(jpc, 0, 0);code[cx2].a=cx1; }else error(33); //没有写until出错} }注意:repeat是可以作为语句的开始符,所有要在初始化函数中的语句开始符中添加statbegsys[repeatsym]=true;语句。
2.语句处理中加入for循环语句if(sym == forsym){getsymdo;if(sym != lparen) error(34);//没有左括号出错else {getsymdo;statementdo(nxtlev, ptx, lev); //S1代码if(sym != semicolon) error(10); //语句缺少分号出错else{cx1=cx;getsymdo;conditiondo(nxtlev, ptx, lev); //E代码if(sym!=semicolon)error(10);//语句缺少分号出错else {cx2=cx;gendo(jpc,0,0);cx3=cx;gendo(jmp,0,0);getsymdo;cx4=cx;statementdo(nxtlev, ptx, lev); //S2代码if(sym != rparen) error(22);//缺少右括号出错else {gendo(jmp,0,cx1);getsymdo;cx5=cx;statementdo(nxtlev, ptx, lev); //S3代码code[cx3].a=cx5;gendo(jmp,0,cx4);code[cx2].a=cx;} } } } }3.语句处理中加入if-then-else语句在原有程序if(sym==then){...}后加入下列代码:cx1 = cx;gendo(jpc, 0, 0);statementdo(fsys, ptx, lev);if(sym == elsesym){getsymdo;cx2 = cx;gendo(jmp, 0, 0);code[cx1].a = cx;statementdo(fsys, ptx, lev);code[cx2].a = cx;}else code[cx1].a = cx;4.扩充++和—运算符对于++和--运算符,扩充时要注意存在两个情况:1)作为语句的时候;2)作为表达式中的因子的时候。
注意:扩充时增加因子开始符facbegsys[incs]=true 和facbegsys[decs]=true 。
扩充的语法描述见结构设计中的PL/0分程序和主要语句的语法描述中的描述图,详细代码见程序。
1)作为语句的时候,有四种情况:a++; a--; ++a; --a;文法的EBNF 表示形式为:<自增自减语句>::=<标识符>[++ |--]|[++|-- ]<标识符>文法分析过程大体如下图:++a 和—a a++和a —生成中间代码对于a++;++a;和a--;--a;语句的处理如下:先将变量的值取出放在栈顶,后将1入栈,后执行加法或减法运算oprv 指令的2(加法)、3(减法),后将运算后的栈顶值存回变量。
a++;和++a;语句的中间代码:lod 0 3;lit 0 1;opr 0 2;sto 0 3;a--;和--a;语句的中间代码:lod 0 3;lit 0 1;opr 0 3;sto 0 3;2)作为因子的时候,有两种情况:a++和a--作为因子,比如:b:=a++*a--;语句++a 和--a 作为因子,比如:b:=--a+2*++a;语句文法的EBNF 表示形式为:<表达式>::=...[ ++|--]<标识符>|<标识符>[++| --]...其中的...表示前后都可以有其他的项或因子生成中间代码①对于因子++a和--a的中间代码生成处理和a++;等语句处理一样;②对于因子a++和a—的中间代码生成处理如下:a++:lod 0 3;lit 0 1;opr 0 2;sto 0 3;lod 0 3;lit 0 1;opr 0 3; a--:lod 0 3;lit 0 1;opr 0 3;sto 0 3;lod 0 3;lit 0 1;opr 0 2;先将变量的值取出放在栈顶,后将1入栈,后执行加法或减法运算opr指令的2(加法)、3(减法),后将运算后的栈顶值存回变量,后将变量的值又取出来放入栈顶,后将1入栈,如果是a++就执行减法,如果是a—就执行加法,以实现先用a的值后再加1。
5.修改不等号#为!=注释源程序中的ssym['#'] = neq语句,在getsym中加入下列代码://修改不等号为!=else if(ch=='!'){getchdo;if(ch=='='){sym=neq;getchdo; }else sym=nul; }6.加入对一维数组的支持本程序将数组看做变量的一种,由var声明函数调用array声明函数完成数组声明,这样就处加入文件输出的相关语句外,可以完全保留block 函数和enter函数;通过改写factor函数使数组因子包括了后缀的索引号,这样就可以调用通用的表达式函数赋值数组了。