编译原理的课程设计.doc_第1页
编译原理的课程设计.doc_第2页
编译原理的课程设计.doc_第3页
编译原理的课程设计.doc_第4页
编译原理的课程设计.doc_第5页
已阅读5页,还剩43页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

二、课程设计正文1 编写一个l-语言的词法分析器,从左到右逐个字符地对l-语言的源程序进行扫描,产生一个个单词符号的机内表示。程序结构如图l-1所示: scanner isalpha isnumberischarisother outputerror 图 l-111 sanner()1 功能:完成初始化,并循环调用子模块,完成单词的识别。2 算法描述如下void scanner() 调用scannerinit()进行初始化; 读入源程序的第一个字符; while (字符!=eof) if (字符= =字母)isalpha();else if ( 字符= = 数字) isnumber(); else if (字符= =)ischar(); else isother();打印结束信息;结束操作;12 isalpha() 1功能:识别保留字和标识符。 2算法描述如下: void isalpha() while(字符为字母或数字或_) 记录当前字符; 读取下一字符;判断当前字符串是否为保留字,并设置标志位h;调用output()函数输出保留字或标识符; 13 isnumber() 1功能:识别整数和实数。 2算法描述如下: void isnumber() int flag=0; while (字符为数字) 记录当前字符; 读取下一字符; if(字符为.号) 记录当前字符; flag=1; 读下一字符; 跳出循环;记单词编码为整数的编码(当前token为整数);if(flag=1) if (当前字符为数字) 记录当前数字; while(当前字符为数字) 记录字符; 读取下一字符;记单词编码为实数的编码(当前token为实数);else error(2);if (当前字符为.)删除余下数字;if (当前字符为字母) 舍去后面的部分;output();14 ischar() 1功能:识别字符串。 2算法描述: void ischar() for (;) 读取下一字符; 现行token为字符串; if(当前字符不是.号) 记录字符; else break;output();读下一字符;15 isother() 1功能:识别其他单词。 2算法描述如下: void isother() switch(当前字符) 对于不同字符做出不同处理,主要有: 1、符号内容的记取; 2、查出机内码; 3、调用output()输出至token()文件; 4、读取下一字符; 5、对于错误符号将其删除,并报错;16 scannerinit() 1功能:进行初始化,主要包括: 1、建立单词编码表、token表、符号表,并将它们清空。 2、打开单词编码文件,并将单词编码读到编码表中。17 output() 1功能:输出识别出的单词,包括: 2若单词为标识符或常数再查,填符号表。18 error() 1.功能:判断错误原因。2在由词法分析程序对l语言源程序分析产生的token,符号表文件的基础上,从完成语法语义分析,并产生相应的中间代码-四元式序列。21 paser() 1功能:主模块,完成初始化,并调用复合语句分析模块和说明语句分析模块,完成分析任务。 2算法描述如下: void paser() 初始化; 从token文件读取第一个单词; if (单词= =program) 读取下一单词; if (单词= =标识符) 读取下一单词; if(单词为;) 行数加一; 读取下一单词; if (单词为var) declear( ); if (单词为begin) s_begin(); if (code 不是等于号) error(49);else 出错处理;else 出错处理;else出错处理;else 出错处理;22 s_begin() 1功能:完成复合语句的分析。 2算法描述 s_begin() if (当前字符为begin) 读取下一字符; 调用l_analize(); if(当前字符为end) 结束; else 非正常结束,返回0;读取下一字符;返回; 23 l_analize() 1功能:完成语句序列分析。 2算法描述 l_analize() int rtn; switch(当前字符) case if:调用s_if()函数;break; case begin :调用s_begin()函数;braek; case 标识符:调用 s_let()函数;break; case while:调用 s_while();break;if (当前字符为:) 行数加一; 读取下一字符; 递归调用l_analize()else return rtn;24 s_let() 1功能:完成赋值语句的分析。 2算法分析 s_let(int a) if (当前字符为标识符) if (需要记录变量的地址) 记录赋值变量的地址;读取下一个单词; if(当前单词为赋值号) 调用表达式分析函数l_analize(); if(表达式正确) 生成赋值句四元式;else 赋值句出错;return四元式序号;25 s_if() 1功能:完成条件语句的分析。 2算法描述: int s_if() int a; int rtn=0; 定义一个真出口true_address和一个假出口flase_address; if(当前单词为if) 布尔表达式初始化; 调用布尔表达式分析函数b_analize(); rtn=布尔表达式的四元式首址; 产生无条件跳转四元式; if (当前单词为then) 读取下一单词; switch(当前单词) case if:调用s_if()函数;break; case begin :调用s_begin()函数;braek; case 标识符:调用 s_let()函数;break; case while:调用 s_while();break; backpatch(); if(当前单词为else) 读取下一单词; switch(当前单词) case if:调用s_if()函数;break; case begin :调用s_begin()函数;braek; case 标识符:调用 s_let()函数;break; case while:调用 s_while();break; backpatch(); else rtn;else 报错;(缺少then)rtn;26 s_while() 1功能:完成while循环语句的分析。 2算法描述; int s_while() int rtn=0;boor_value,true_address,false_address; if (当前单词为while) rtn=布尔表达式分析函数b_analize(); boor_value=布尔表达式值地址; 产生跳转四元式; if(当前单词为do) 读取下一单词; switch(当前单词) case if:调用s_if()函数;break; case begin :调用s_begin()函数;braek; case 标识符:调用 s_let()函数;break; case while:调用 s_while();break; backpatch();backpatch();else 出错,缺少do;return rtn;27 gen() 该函数形成一个四元式,并将其输出至四元式文件。28 e_analize() 1该函数是算术分析表达式的主模块,它调用算术表达式的子模块,采用递归下降分析法完成算术表达式的分析。 2算术表达式的各个子模块: ae_init()将算术表达式读入分析栈; bint e_addsub()完成e-te1|t的分析; cint e1_addsub(int a) 完成e1-+te1|-te1| dt_muldiv() 完成t-ft1|f的分析; et1_muldiv(int a) 完成t1-*ft1|/ft1|; ff_number() 完成f-i|(e)的分析;29 b_analize() 1布尔表达式分析的主模块,调用其他布尔表达式的子模块,采用递归下降分析法完成布尔表达式的分析。并返回该布尔表达式的首个四元式地址。 ab_or()完成b-lb|l的分析; bb1_or(int a) 完成b1-orlb1|的分析; cl_and() 完成l-ml1|m的分析; dl1_and()完成l1-andm1|的分析; em_not()完成m-notm|k的分析; fk_end()完成k-i|false|true|(b)的分析; gk_cmp()完成k-isi,s-|=|=|的分析。三、课程设计总结 1、 实验中遇到的问题 词法分析器程序中要读入一个单词编码文件,但是文件的格式在编写的时候和程序有点差异,因而导致输出结果再三的错误。语法/语义分析器中,在修改符号表时,出现错误,最终没有的到正确结果。2、 对实验原理有更深的理解 通过该课程设计,掌握了什么是编译程序,编译程序工作的基本过程及其各阶段的基本任务,熟悉了编译程序总流程框图,了解了编译程序的生成过程,构造工具及其相关的技术对课本上的知识有了更深的理解,课本上的知识师机械的,表面的.通过把该算法的内容,算法的执行顺序在计算机上实现,把原来以为很深奥的书本知识变的更为简单,对实验原理有更深的理解。3、 对该理论在实践中的应用有深刻的理解 通过把该算法的内容,算法的执行顺序在计算机上实现,知道和理解了该理论在计算机中是怎样执行的,对该理论在实践中的应用有深刻的理解。四、参考文献1 贺讯. 编译方法学习指导与实践.北京:机械工业出版社, 第一版. 2004年8月。 五、附录1单词编码文件ni.txt and1or11begin2program12bool3real13+23=33do4then14-2434else5true15*2535end6var16/2636false7while17.27=37if8标识符18,28integer9整数19:29not10实数20;30(21:=31)22=32char 382测试代码文件11.txt program abc; var a:real; begin if a22.2 then x:=c+d; end3词法分析完整源代码 #include#include#include#define length 61#define n 100/*/typedef struct tokenint label;char name30;int code;int addr;token;typedef struct keywordchar name30;int code;keyword;typedef struct symbleint number;int type;char name30;symble;/*/char ch;int var_count;int error_count;int label_count;int code_count;int addr_count;int lineofpro;char filename30;file*keyfin;file*sourcefin;file*tokenfout;file*symblefout;keyword keylength;token currenttoken;symble currentsimble;symble symblelistn;/*/void scanner();void scannerinit();void isalpha();void isnumber();void isanotation();void ischar();void isother();void output();void error(int a);int wordhave();int strcmp(char*s,char*t)for(;*s=*t;s+,t+)if(*s=0)return 0;return 1;/*/int main()int i=0,j=0;code_count=0;lineofpro=0;var_count=0;addr_count=1;label_count=1;for(i=0;in;i+)symblelisti.number=0;symblelisti.type=0;for(j=0;j30;j+)symblelj=0;scanner();system(pause);return 0;/*主程序*/void scanner()int i=0;error_count=0;scannerinit();printf( * );printf( *l语言词法分析器);printf( * ); printf(输入原文件名:);for(;)scanf(%c,&filenamei);if(filenamei=10)break;i+;filenamei=0;if(sourcefin=fopen(filename,rt)=null)printf(无法打开文件 %s.n,filename);exit(1);if(tokenfout=fopen(token.txt,wt+)=null)printf(无法打开文件 symble.txtn);exit(1);if(symblefout=fopen(symble.txt,wt+)=null)printf(无法打开文件 symble.txtn);exit(1);ch=fgetc(sourcefin);while(ch!=eof)for(i=0;i47)&(ch64)&(ch96)&(ch123)|(ch=_)isalpha(); elseif(ch=)ischar(); else isother();fclose(sourcefin);fclose(tokenfout);fclose(symblefout);printf(分析完毕/n);/*初始化*/void scannerinit()int i=1;int k=0;if(keyfin=fopen(ni.txt,rt)=null)printf(cannot open ni.txtn);exit(1);for(i=0;i60;i+)for(k=0;k30;k+)k=0;for(i=0;i47)&(ch47)&(ch47)&(ch47)&(ch64)&(ch96)&(ch64)&(ch96)&(ch47)&(ch64)&(ch96)&(ch123)|(ch=_)currentti+=ch; ch=fgetc(sourcefin);for(i=1;ilength;i+)h=strcmp(currentt,);if(!h)break;if(!h)currenttoken.code=keyi.code;currenttoken.addr=-1;else currenttoken.code=18;currenttoken.addr=addr_count+;currenttoken.label=label_count+;output();/*字符串处理*/void ischar()int i=0;for(;)ch=fgetc(sourcefin);currenttoken.code=20;if(ch!=) currentti+=ch;else break;currenttoken.addr=addr_count+;currenttoken.label=label_count+;output();ch=fgetc(sourcefin);/*其他情况*/void isother()char ch1;int i;for(i=0;i30;i+)currentti=0;switch(ch)case(:currentt0=(;currenttoken.code=21;currenttoken.addr=-1;currenttoken.label=label_count+;output();ch=fgetc(sourcefin);break;case):currentt0=);currenttoken.code=22;currenttoken.addr=-1;currenttoken.label=label_count+;output();ch=fgetc(sourcefin);break;case*:currentt0=*;currenttoken.code=25;currenttoken.addr=-1;currenttoken.label=label_count+;output();ch=fgetc(sourcefin);break; case+:currentt0=+;currenttoken.code=23;currenttoken.addr=-1;currenttoken.label=label_count+;output();ch=fgetc(sourcefin);break;case,:currentt0=1;currenttoken.code=28;currenttoken.addr=-1;currenttoken.label=label_count+;output();ch=fgetc(sourcefin);break;case-:currentt0=-;currenttoken.code=24;currenttoken.addr=-1;currenttoken.label=label_count+;output();ch=fgetc(sourcefin);break;case.:currentt0=.;currenttoken.code=27;currenttoken.addr=-1;currenttoken.label=label_count+;output();ch=fgetc(sourcefin);break;case:ch1=ch;ch=fgetc(sourcefin);if(ch!=)currentt0=:; currenttoken.code=29; currenttoken.addr=-1; currenttoken.label=label_count+; output();elsecurrentt0=:;currentt1=; currenttoken.code=31; currenttoken.addr=-1; currenttoken.label=label_count+; output(); ch=fgetc(sourcefin); break;case;:currentt0=;currenttoken.code=30;currenttoken.addr=-1;currenttoken.label=label_count+;output();ch=fgetc(sourcefin);break;case:ch1=fgetc(sourcefin);if(ch1=) currentt0=)currentt0=; currenttoken.code=35; currenttoken.addr=-1; currenttoken.label=label_count+; output(); ch1=fgetc(sourcefin); elsecurrentt0=:ch1=fgetc(sourcefin);if(ch1=) currentt0=; currentt1=;currenttoken.code=37; currenttoken.addr=-1; currenttoken.label=label_count+; output(); ch1=fgetc(sourcefin);elsecurrentt0=; currenttoken.code=36; currenttoken.addr=-1; currenttoken.label=label_count+; output();ch=ch1;break;case 10: lineofpro+; ch=fgetc(sourcefin); break;case 13: lineofpro+; ch=fgetc(sourcefin); break;case : ch=fgetc(sourcefin); break;case eof: error(1);ch=fgetc(sourcefin);break;/*输出模块*/void output()int flag,i=0;int k;/*查填符号模块*/if(currenttoken.code=18)|(currenttoken.code=19)|(currenttoken.code=20)currentsimble.number=currenttoken.addr;currentsimble.type=currenttoken.code;strcpy(currents,currentt);flag=wordhave();if(currenttoken.code=18)&(flag=1)|(currenttoken.code=20)|(currenttoken.code=19)fprintf(symblefout,%3d %3d %sn,currentsimble.number,currentsimble.type,currents);/*输出到token表*/for(;)if(currentti+=0)break;fprintf(tokenfout,%3d %s,currenttoken.label,currentt);printf(%3d %s,currenttoken.label,currentt);for(k=20-i;k0;k-)fprintf(tokenfout, );printf( );fprintf(tokenfout,%3d %3dn,currenttoken.code,currenttoken.addr);printf(%3d %3dn,currenttoken.code,currenttoken.addr);void error(int a)error_count+;switch(a)case 1: printf(error %2d 非法字符于 %3d 行.n, error_count,lineofpro+1);break;case 2: printf(error %2d 实常数出过于 %3d 行.n, error_count,lineofpro+1);break;case 3: printf(error %2d 没有匹配的注释符 */ n,error_count);break;case 4: printf(error %2d 非正常结束!n,error_count);break; default: break;return;int wordhave()int flag,i=0;for(i=0;ivar_count;i+)flag=strcmp(currents,symblel);if(flag=0)currenttoken.addr=symblelisti.number;return 0;symblelistvar_count.number=currenttoken.addr;symblelistvar_count.type=currenttoken.code;strcpy(symblelistvar_,currentt);var_count+;return 1;4词法分析的结果 5词法分析产生的token文件 6词法分析产生的符号表文件 7语法/语义分析器的完整代码 #include#include#includetypedef struct stackchar name20;int cod;int addr;stack;typedef struct equint op;int op1;int op2;int result;equ;typedef struct varchar name20;int addr;int type;int value;var;#define exp_len 100#define equ_len 1024#define one 50001#define zero 50000#define e_expr 7#define if 8#define while 9#define for 10#define b_exp 12file *tokenfin;file *symblefin;file *equfout;int code ;int address;int lineofpro;int lineofequ;stack var_listexp_len;stack exprexp_len;equ equequ_len;var templistequ_len;char id20;int var_count;int len_count;int pos;int now_addr;int temp_count;int error_count;int let_count;int e_contrl;int e_rtn;int true_address;int false_address;int gen_pos;int equpush(int op,int a,int b,int r);void getnext();void error(int num);int num(char cc);int gen(int op,int a,int b,int r);void declear();void initstack();void push(int cod,int addr);int newtemp();void backpatch(int addr,int addr2);/布尔表达式分析函数int b_analize();void b_init();int b_or();int b1_or(int a);int l_and();int l1_and(int a);int m_not();int k_end();int k_cmp();/算术表达式分析函数int e_analize();void e_init();int e_addsub();int e1_addsub(int

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论