当前位置:文档之家› 编译原理词法分析器语法分析器实验报告

编译原理词法分析器语法分析器实验报告

(此文档为word格式,下载后您可任意编辑修改!)编译技术班级网络0802学号姓名叶晨舟指导老师朱玉全2011年 7 月 4 日一、目的编译技术是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。

从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。

二、任务及要求基本要求:1.词法分析器产生下述小语言的单词序列这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表:对于这个小语言,有几点重要的限制:首先,所有的关键字(如IF﹑WHILE等)都是“保留字”。

所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。

例如,下面的写法是绝对禁止的:IF(5)=x其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。

也就是说,对于关键字不专设对应的转换图。

但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。

当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。

再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。

例如,一个条件语句应写为IF i>0 i= 1;而绝对不要写成IFi>0 i=1;因为对于后者,我们的分析器将无条件地将IFI看成一个标识符。

这个小语言的单词符号的状态转换图,如下图:2.语法分析器能识别由加+ 减- 乘* 除乘方^ 括号()操作数所组成的算术表达式,其文法如下:E→E+T|E-T|TT→T*F|TF|FF→P^F|Pp→(E)|i使用的算法可以是:预测分析法;递归下降分析法;算符优先分析法;LR分析法等。

3.中间代码生成器产生上述算术表达式的中间代码(四元式序列)三、实现过程给出各题目的详细算法描述,数据结构和函数说明,流程图。

1、词法分析器的流程图2、语法分析器主程序图3、中间代码生成器流程图:四、源程序词法分析器:#include<string. 0;elsereturn s->next->data;}int find(char c,char array[]) 查找函数,{int i;int flag=0;for(i=0;i<100;i++){if(c==array[i])flag=1;}return flag;}int location(char c,char array[]) 定位函数,指出字符所在位置{int i;for(i=0;i<100;i++){if(c==array[i])return i;}}void error() 出错函数定义{printf("%15c出错!\n",' ');}void analyse(char Vn[],char Vt[]){int i,j,m,p,q,length,t,(str);i++){if(!find(str[i],Vt)){printf("输入字符串有误!请重新输入!");goto opt0;break;}}stackk *st;initlink(st);pushlink(st,'#');pushlink(st,Vn[0]); #与识别符号入栈j=0;",' ',' ',' ');opt1:printf("%-16d",(str);t++){printf("%c",str[t]); 显示剩余字符串}if(find(X,Vt)&& X!='#') 分析栈的栈顶元素和剩余输入串的第一个元素相比较{if(X==w){printf("%15c匹配\n",X);j++;w=str[j];goto opt1;}elseerror();}else{if(X=='#'){if(X==w){printf("%8c是该文法的句子!\n",' ');}elseerror();}else{p=location(X,Vn);q=location(w,Vt);char *S1="null",*S2="NULL";if(strcmp(M[p][q].m,S1)==0||strcmp(M[p][q].m,S2)==0) 查找产生式error();else{char str0[100];strcpy(str0,M[p][q].m);printf("%15c-->%s\n",X,str0); 显示对应的产生式if(strcmp(str0,"$")==0)goto opt1;else{length=strlen(str0); 逆序进栈for(m=length-1;m>=0;m--){pushlink(st,str0[m]);}goto opt1;}}}}}int main(){int i,k,n,r;char Vn[100],Vt[100],select;printf("******************************************************************\n");printf("对任意输入LL(1)文法的分析表,判断验证字符串是否为该文法的句子\n");printf("并能给出分析和演示过程。

\n");printf("******************************************************************\n"); opt2:printf("请输入各终结符(#号表示结束)Vt[i]:\n");for(i=0;i<100;i++){scanf("%c",&Vt[i]);if(Vt[i]=='#'){r=i;break;}}printf("请输入非终结符个数:\n");scanf("%d",&n);getchar();for (i=0;i<n;i++){printf("请输入非终结符Vn[%d]:\n",i);scanf("%c",&Vn[i]);getchar();printf("请输入此非终结符对应各终结符的产生式右部(null或NULL表示出错;$表示空串):\n");for(k=0;k<=r;k++){scanf("%s",M[i][k].m);getchar();}}opt3:printf("请输入要分析的字符串,且以#结束:\n");analyse(Vn, Vt);printf("********************请选择***********************\n");printf(" 1: 输入字符串\n");printf(" 2: 输入新分析表\n");printf(" 0: 退出\n");printf("*************************************************\n"); opt4:cin>>select;switch(select){case '1': {goto opt3;break;}case '2': {goto opt2;}case '0': {break;}default: {printf("输入错误!请重新选择:");goto opt4;break;}}return 0;}运行结果:语法分析器源程序:#include<string.[10];char ch;int syn,p,m=0,n,row,sum=0;char *rwtab[20]={"dim","if","do","stop","end" ,"and","begin","bool","case","char", "false","for","int","not","or","set","then","true","until","while"};void scaner(){for(n=0;n<9;n++) token[n]=NULL;ch=prog[p++];while(ch==' '){ch=prog[p];p++;}if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){m=0;while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){token[m++]=ch;ch=prog[p++];}token[m++]='\0';p--;syn=21;for(n=0;n<20;n++){if(strcmp(token,rwtab[n])==0){syn=n+1;break;}}}else if((ch>='0'&&ch<='9')){{sum=0;while((ch>='0'&&ch<='9')){sum=sum*10+ch-'0';ch=prog[p++];}}p--;syn=7+15;if(sum>32767)syn=-1;}else switch(ch){case'=':syn=8+15;token[0]=ch;break; case'+':syn=9+15;token[0]=ch;break; case'*':m=0;token[m++]=ch;ch=prog[p++];if(ch=='*'){syn=11+15;token[m++]=ch;}else{syn=10+15;p--;break;case',':syn=12+15;token[0]=ch;break; case'(':syn=13+15;token[0]=ch;break; case')':syn=14+15;token[0]=ch;break; case'#':syn=0;token[0]=ch;break; case'<':m=0;token[m++]=ch;ch=prog[p++];if(ch=='>'){syn=17+15;token[m++]=ch;}else if(ch=='='){syn=16+15;token[m++]=ch;}else{syn=15+15;p--;}break;case'>':m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=19+15;token[m++]=ch;}else{syn=18+15;p--;}break;case':':m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=21+15;token[m++]=ch;}{syn=20+15;p--;}break;case'':syn=22+15;token[0]=ch;break;case'-':syn=23+15;token[0]=ch;break;case';':syn=24+15;token[0]=ch;break;default: syn=-1;break;}}void main(){p=0;row=1;cout<<endl<<endl<<endl;cout<<"***************************小型词法分析器**********************************"<<endl<<endl;cout<<"请输入一段程序(以#结束):";do{cin.get(ch);prog[p++]=ch;}while(ch!='#');p=0;cout<<endl<<"**************************词法分析结果如下*********************************"<<endl;cout<<" 种别编码自身值"<<endl;do{scaner();switch(syn){case 22 : cout<<" ("<<syn<<" , "<<sum<<")"<<endl; break;case -1: cout<< " Error in row"<<row<<"!"<<endl; break;default: cout<<" ("<<syn<<" , "<<token<<")"<<endl;break;}}while (syn!=0);运行结果:}中间代码生成器源程序:表达式生成四元式递归子程序法#include<string>#include <iostream>using namespace std;#define DEFAULT_SIZE 100char EMachine(char w); 表达式E的自动机char TMachine(char w); 表达式T的自动机char FMachine(char w); 表达式F的自动机bool ZMachine(); 表达式Z的自动机string intToString(int a); 整形变成字符串形函数class stack 栈类定义{private:int top;string *stacka;int maxsize;public:stack(int size=DEFAULT_SIZE);~stack(){ delete [] stacka; }void push(const string &item);string pop(void);string gettop(void) const ;bool empty(void) const { return (top==-1); }bool full(void) const { return (top==maxsize-1); }void clear(void) { top=-1; }stack::stack(int size) 栈类的构造函数{top=-1;maxsize=size;stacka=new string[maxsize];if(!stacka){cerr<<"allocate memory failed."<<endl;exit(1);}}void stack::push(const string &item) 压栈操作{if(full()){cerr<<"stack full, cannot push."<<endl;return;}top++;stacka[top]=item;}string stack::pop(void) 出栈操作{if(empty()){cerr<<"stack empty, cannot pop."<<endl;exit(1) ;}string item=stacka[top];top--;return item;}string stack::gettop(void) const 取栈顶操作{if(empty()){cerr<<"stack empty, cannot gettop."<<endl;exit(1) ;}return stacka[top];}static stack wordStack; 符号栈static int noOfQuet=0; 静态四元式个数记录static int noOfT = 1; 静态状态个数记录void main(){ 主函数char yesOrNo; 进行一个循环操作控制do{cout<<"请输入算术表达式:"<<endl;noOfT = 1; 每次结束询问ZMachine();cout<<endl<<"Continue?Y es or Not:";cin>>yesOrNo; 输入“Y”则继续}while(yesOrNo=='y'); 否则程序结束}bool ZMachine(){ Z自动机char w;cin>>w;w = EMachine(w); 调用E自动机if(w=='#'){ 遇到“#”则结束return true;}else{return false;}}char EMachine(char w){ E自动机string operate,a,b,c;string state[5];w = TMachine(w); 调用T自动机while(w=='+'||w=='-'){ 是加或减符号operate = w;cin>>w; 读入下一字符w = TMachine(w); 调用T自动机b = wordStack.pop(); 字符栈弹出a = wordStack.pop(); 两个操作字符cout<<"(\""<<operate<<"\","<<a<<","<<b<<",t"<<noOfT<<")"<<endl;c = "t"+intToString(noOfT); 输出四元式wordStack.push(c); 新状态压栈noOfT++; 状态计数加一}return w;}char TMachine(char w){string operate,a,b,c;string state[5];w = FMachine(w); 调用F自动机while(w=='*'||w==''){ 是乘除号operate = w;cin>>w; 读取下一字符w = FMachine(w); 调用F自动机b = wordStack.pop(); 符号栈弹出a = wordStack.pop(); 两个操作字符cout<<"(\""<<operate<<"\","<<a<<","<<b<<",t"<<noOfT<<")"<<endl;c = "t"+intToString(noOfT); 输出四元式wordStack.push(c); 新状态压栈noOfT++; 状态计数加1}return w;}char FMachine(char w){ F自动机string theWord;if(w>='a'&&w<='z'||w>='A'&&w<='Z'){theWord = w; 当前字符是字母wordStack.push(theWord); 则压栈}else if(w == '('){ 是左括号cin>>w; 则读取下一字符w = EMachine(w); 调用E自动机if(w!=')'){ 不是右括号则输入有误,报错cerr<<"the input is wrong!"<<endl;exit(0);}}else{ 否则有误,报错cerr<<"the input is wrong!"<<endl;exit(0);}cin>>w; 读取下一字符return w;}string intToString(int a){ 整形变字符串形函数string d;char b='0',c;int i;while(a!=0){i = a%10;a = a10;c = (int)b + i;d = c + d;}return d;}Y=a+b*(c+(-d)*(e+f))Y=(a+b*(c-d*ef+g*(h-i*x*(j+k*(-l)*(j+k)))+w))H=(d+a-(c+b-q)*a)+c-(a+b*(c+d))六、总结通过这次实验,我对编译原理这门专业必修课有了进一步的深层次了解,把理论知识应用于实验中,也让我重新熟悉了C++语言的相关内容,加深了对C++语言知识的深化和用途的理解。

相关主题