1、编译原理词法分析器实验报告编译技术 班 级 学 号 姓 名 指导老师 20xx年 7 月 4 日一、目的编译技术是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。二、任务及要求基本要求:1 词法分析器 产生下述小语言的单词序列这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表: 单词符号种别编码助记符内码值DIMIFDOSTOPEND标识符常数(整)=+*,()123456789
2、1011121314$DIM$IF$DO$STOP$END$ID$INT$ASSIGN$PLUS$STAR$POWER$COMMA$LPAR$RPAR-内部字符串标准二进形式-对于这个小语言,有几点重要的限制:首先,所有的关键字(如IFWHILE等)都是“保留字”。所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。例如,下面的写法是绝对禁止的: IF(5)=x 其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。也就是说,对于关键字不专设对应的转换图。但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。当转换图识别出一个标识符时,就去查对这张表,确定它
3、是否为一个关键字。再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。例如,一个条件语句应写为 IF i0 i= 1;而绝对不要写成 IFi0 i=1;因为对于后者,我们的分析器将无条件地将IFI看成一个标识符。这个小语言的单词符号的状态转换图,如下图: 2 语法分析器 能识别由加+ 减- 乘* 除/ 乘方 括号()操作数所组成的算术表达式,其文法如下:EE+T|E-T|TTT*F|T/F|FFPF|Pp(E)|i 使用的算法可以是:预测分析法;递归下降分析法;算符优先分析法;LR分析法等。3 中间代码生成器 产生
4、上述算术表达式的中间代码(四元式序列)三、实现过程给出各题目的详细算法描述,数据结构和函数说明,流程图。1、词法分析器的流程图2、语法分析器主程序图3、中间代码生成器流程图:四、源程序词法分析器:#include#include#includeusing namespace std;typedef struct table /分析表存储结构 char m100; table;table M100100; /定义分析表typedef struct stacknode /定义栈内元素节点 (带头结点(为空)的) char data; struct stacknode *next;stackk;vo
5、id initlink(stackk *&s) /初始化新栈 s=(stackk *)malloc(sizeof(stackk); s-next=NULL;void poplink(stackk *&s) /顶元素出栈 stackk *p;char v; if(s-next!=NULL) p=s-next; v=p-data; s-next=p-next; free(p);void pushlink(stackk *&s,char x) /新 元 素 入 栈 stackk *p; p=(stackk *)malloc(sizeof(stackk); p-data=x; p-next=s-nex
6、t; s-next=p;void display(stackk *s) /打印 现实显示 栈内元素 stackk *p; int i=0,j; char st100; p=s-next; while(p!=NULL) sti+=p-data; p=p-next; for(j=i-1;j=0;j-) printf(%c,stj); for(j=0;jnext=NULL) return 0; else return s-next-data; int find(char c,char array) /查找函数,int i;int flag=0;for(i=0;i100;i+)if(c=arrayi)
7、 flag=1;return flag;int location(char c,char array) /定位函数,指出字符所在位置int i;for(i=0;i100;i+)if(c=arrayi) return i;void error() /出错函数定义 printf(%15c出错!n, );void analyse(char Vn,char Vt) int i,j,m,p,q,length,t,h; char w,X; char str100;opt0: scanf(%s,str); for(i=0;istrlen(str);i+) if(!find(stri,Vt) printf(输
8、入字符串有误!请重新输入!); goto opt0; break; stackk *st; initlink(st); pushlink(st,#); pushlink(st,Vn0); /#与识别符号入栈 j=0; h=1; w=str0; printf(步骤%-12c分析栈%-24c剩余输入串%-12c所用产生式n, , , );opt1: printf(%-16d,h); /显示步骤 h+; display(st); /显示分析栈中内容 X=gettop(st); /上托栈顶符号放入X poplink(st); for(int k=0;k14+j;k+) /打印对齐格式 printf(%
9、c, ); for(t=j;t%sn,X,str0); /显示对应的产生式 if(strcmp(str0,$)=0) goto opt1; else length=strlen(str0); /逆序进栈 for(m=length-1;m=0;m-) pushlink(st,str0m); goto opt1; int main() int i,k,n,r; char Vn100,Vt100,select; printf(*n); printf(对任意输入LL(1)文法的分析表,判断验证字符串是否为该文法的句子 n); printf(并能给出分析和演示过程。 n); printf(*n);opt
10、2: printf(请输入各终结符(#号表示结束 )Vti:n); for(i=0;i100;i+) scanf(%c,&Vti); if(Vti=#) r=i; break; printf(请输入非终结符个数:n); scanf(%d,&n); getchar(); for (i=0;in;i+) printf(请输入非终结符Vn%d:n,i); scanf(%c,&Vni); getchar(); printf(请输入此非终结符对应各终结符的产生式右部(null或NULL表示出错;$表示空串):n); for(k=0;kselect; switch(select) case 1: goto
11、 opt3;break; case 2: goto opt2; case 0: break; default: printf(输入错误!请重新选择:); goto opt4; break; return 0;运行结果:语法分析器 源程序:#include#includeusing namespace std;char prog100,token10;char ch;int syn,p,m=0,n,row,sum=0;char *rwtab20=dim,if,do,stop,end ,and,begin,bool,case,char, false,for,int,not,or,set,then,
12、true,until,while; void scaner() for(n=0;n=a&ch=A&ch=0&ch=a&ch=A&ch=Z) tokenm+=ch; ch=progp+; tokenm+=0; p-; syn=21; for(n=0;n=0&ch=0&ch32767) syn=-1; else switch(ch) case=:syn=8+15;token0=ch;break; case+:syn=9+15;token0=ch;break; case*: m=0; tokenm+=ch; ch=progp+; if(ch=*) syn=11+15; tokenm+=ch; els
13、e syn=10+15; p-; break;case,:syn=12+15;token0=ch;break;case(:syn=13+15;token0=ch;break;case):syn=14+15;token0=ch;break;case#:syn=0;token0=ch;break;case) syn=17+15; tokenm+=ch; else if(ch=) syn=16+15; tokenm+=ch; else syn=15+15; p-; break;case:m=0;tokenm+=ch; ch=progp+; if(ch=) syn=19+15; tokenm+=ch;
14、 else syn=18+15; p-; break;case:m=0;tokenm+=ch; ch=progp+; if(ch=) syn=21+15; tokenm+=ch; else syn=20+15; p-; break;case/:syn=22+15;token0=ch;break;case-:syn=23+15;token0=ch;break;case;:syn=24+15;token0=ch;break;default: syn=-1;break; void main() p=0; row=1; coutendlendlendl; cout*小型词法分析器*endlendl;
15、cout请输入一段程序(以#结束):; do cin.get(ch); progp+=ch; while(ch!=#); p=0; coutendl*词法分析结果如下*endl; cout 种别编码 自身值endl; do scaner(); switch(syn) case 22 : cout (syn , sum)endl; break; case -1: cout Error in rowrow!endl; break; default: cout (syn , token)endl;break; while (syn!=0);运行结果:中间代码生成器源程序:表达式生成四元式递归子程序法
16、#include#include 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(in
17、t 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 st
18、ringmaxsize; if(!stacka) cerrallocate memory failed.endl; exit(1); void stack:push(const string &item) /压栈操作 if(full() cerrstack full, cannot push.endl; return; top+; stackatop=item;string stack:pop(void) /出栈操作 if(empty() cerrstack empty, cannot pop.endl; exit(1) ; string item=stackatop; top-; retur
19、n item;string stack:gettop(void) const /取栈顶操作 if(empty() cerrstack empty, cannot gettop.endl; exit(1) ; return stackatop;static stack wordStack; /符号栈static int noOfQuet=0; /静态四元式个数记录static int noOfT = 1; /静态状态个数记录 void main() /主函数 char yesOrNo; /进行一个循环操作控制 do cout请输入算术表达式:endl; noOfT = 1; /每次结束询问 ZM
20、achine(); coutendlyesOrNo; /输入“Y”则继续 while(yesOrNo=y); /否则程序结束bool ZMachine() /Z自动机 char w; cinw; w = EMachine(w); /调用E自动机 if(w=#) /遇到“#”则结束 return true; else return false; char EMachine(char w) /E自动机 string operate,a,b,c; string state5; w = TMachine(w); /调用T自动机 while(w=+|w=-) /是加或减符号 operate = w; cinw; /读入下一字符 w = TMachine(w); /调用T自动机 b = wordStack.pop(); /字符栈弹出 a = wordStack.pop(); /两个操作字符 cout(operate,a,b,tnoOfT)endl; c = t+intToString(noOfT); /输出四元式 wordStack.push(c); /新状态压栈 noOfT+; /状态计
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1