课程设计任务书课题名称《编译原理》课程设计完成时间指导教师职称学生姓名班级总体设计要求总体设计要求:课程设计内容共给定1个题目,每个学生按照课程设计要求,在规定的两周时间内独立完成。题目:编译程序构造涉及内容:词法分析、语法分析、语义分析生成中间代码工作内容及时间进度安排第一周、周1:设计动员,布置课程设计任务,查阅资料,制定方案,进行程序方案设计。第一周、周2-周5:编写和调试程序第二周、周1-周3:编写和调试程序第二周、周4:整理,撰写设计报告。第二周、周5:验收,提交设计报告,评定成绩。毕业设计成果1、课程设计报告书一份2、源程序清单一份3、成果使用说明书一份-2-内容摘要``````````````````第1章绪论1.1、课程设计目的1.2、课程设计意义1.3、课程设计要求1.4、课程设计内容1.4.1、题目编译程序构造1.4.2、内容涉及词法分析、自下而上语法分析程序的实现:SLR(1)分析器的实现以及生成中间代码。1.4.3、具体要求根据LR分析算法构造SLR(1)分析程序,并完成语法分析动作(当需要一个单词时,调用词法分析程序获取),同时完成语义分析生成四元式输出。要求程序具有通用性,改变文法时只需改变程序的数据初值,无需改变程序主体;要求完成一条说明语句、一条算数表达式和赋值语句的翻译,生成中间代码。变量说明语句的文法及相应的语义子程序:.att表示数据类型属性,fill函数表示将单词id及其类别属性填写符号表。-3-(0)S→D;{acc}(1)D→intid{fill(id,int);D.att=int;}(2)D→floatid{fill(id,float);D.att=float;}(3)D→D(1),id{fill(id,D(1).att);D.att=D(1).att;}算数表达式和赋值语句的文法及相应的语义子程序。(1)A→id=E;{p=lookup(id.name);emit(E.PALCE,,p);}(2)E→E(1)+T{E.PALCE=newtemp();emit(+,E(1).PALCE,T.PALCE,E.PALCE)}(3)E→T{E.PALCE=T.PALCE;}(4)T→T(1)*F{T.PALCE=newtemp();emit(+,T(1).PALCE,F.PALCE,T.PALCE)}(5)T→F{T.PALCE=F.PALCE;}(6)F→(E){F.PALCE=E.PALCE;}(7)F→id{P=LOOKUP(id.name);F.PALCE=P;}(8)F→num{P=LOOKUP(num.value)F.PALCE=P;}构造其用于SLR(1)分析的识别活前缀的DFA以及action表和goto表。然后编程实现。(关于词法分析部分只需识别出与此文法相关的单词即可(+,*,(,),id,=))。1.4.4、程序设计提示(1)分析栈设计时可以用一个栈完成,也可以设计三个栈:一个符号栈,一个状态栈,一个语义栈,则归约时,则需要在符号栈中退掉n个符号,在状态栈中退掉n个符号(n为产生式符号个数),语义栈中退掉n个符号对应的语义;(2)终结符表和非终结符表的组织和预测分析程序中相同(将符号对应到一个数字,表示在分析表中对应的下标)。(3)action表中的错误处理:简化的错误处理:当查找action表出现空白时,则当前单词无法移进和规约,可简单的认为当前单词为多余的单词,则抛弃当前单词,读下一单词继续分析。1.4.5、测试数据源文件中数据:intarea,r;r=1;area=r*r+r;程序要求输出二元式序列、符号表、语法分析过程、四元式序列。-4-1.4.6、程序扩展要求第2章程序总体设计-5-第3章程序详细设计与实现3.1、词法分析首先定义结构体typedefstruct//状态栈{intdata[max];inttop;}seqstack1;typedefstruct//符号栈{stringdata[max];inttop;}seqstack2;structreserveedword//保留字表结构{stringword;charvalue;}reserveedword1[maxsize];structidentifer//标识符表结构{charidentiname[15];charidentitype[15];intaddress;}identifer1[maxsize];structconstant//常量表结构{stringconstantname;stringvalue;-6-intconstantaddress;}constant1[maxsize];词法分析主要函数结构:voidInitscanner()//该函数用于用C语言当中常见的关键字初始化保留表voidIsalpha(chars)//用于判断读入的字符是不是字母voidIsnumber(chars)//用于判断读入的字符是不是数字voidIsother(chars)//判断除数字与字母之外的其他字符voidLexscan()//用于循环从程序中读入字符并判断应调用那个判断函数字符voidOutput(inti,intj,charss[15])//输出二元式本模块程序的伪代码如下:打开文件infile.open(input.txt,ios::in);if(!infile){cerr读取的文件打开失败!endl;exit(1);}初始化保留字表Initscanner();循环读入从文件当中Scanner(){while(ch!='#'){在该函数中判断应该调用的判断函数Lexscan(){infile.get(ch);if(((ch='A')&&(ch='Z'))||((ch='a')&&(ch='z')))Isalpha(ch){Output};elseif((ch='0')&&(ch='9'))Isnumber(ch){Output};elseIsother(ch){Output};}}}关闭文件infile.close();词法分析器中从源文件读出一个单词,判断其类型是关键字、标识符还是普通符号,根据其类型为结构体各项赋值,并将其传给语法分析函数。-7-3.2、语法分析由于说明语句与算术表达式和赋值语句所使用的是不同的文法,所以两者的ACTION表和GOTO表也不一样,本次课设采用二维数组存放ACTION表和GOTO表信息,其中移进用大于0的数表示,归约用小于0的数表示,成功用100表示(acc),其他处用0表示,查表时遇到相应的数进行相应的操作。其中,归约部分需要根据其产生式的信息进行,所以程序中有如下定义:stringv1[8]={int,float,;,,,id,#,D,S};//存放说明文法当中的字符stringv2[13]={#,id,=,num,;,+,*,(,),F,A,E,T};//存放算本文法当中的字符根据状态转换图(DFA)构造SLR(1)分析表:其中说明文法和算术文法分别构造,同时在每个表当中既有action表又有goto表intanalysis_table1[10][8]={3,4,0,0,0,0,2,1,0,0,0,0,0,100,0,0,0,0,5,6,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,9,0,0,0,0,0,-2,-2,0,0,0,0,0,0,-3,-3,0,0,0,0,0,0,-4,-4,0,0,0,0};intanalysis_table2[17][13]={0,2,0,0,0,0,0,0,0,0,1,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,9,0,8,0,0,0,7,0,6,0,4,5,0,0,0,0,10,11,0,0,0,0,0,0,0,0,0,0,0,-3,-3,12,0,-3,0,0,0,0,0,0,0,0,-5,-5,-5,0,-5,0,0,0,0,0,9,0,8,0,0,0,7,0,6,0,13,5,0,0,0,0,-8,-8,-8,0,-8,0,0,0,0,0,0,0,0,-7,-7,-7,0,-7,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,8,0,0,0,7,0,6,0,0,14,0,9,0,8,0,0,0,7,0,15,0,0,0,0,0,0,0,0,11,0,0,16,0,0,0,0,0,0,0,0,-2,-2,12,0,-2,0,0,0,0,0,0,0,0,-4,-4,-4,0,-4,0,0,0,0,0,0,0,0,-6,-6,-6,0,-6,0,0,0,0};语法分析当中各个函数说明及伪代码:voidaction1(inti,strings)//通过词法分析传过来的值判断移进动作三个栈(状态栈,符号栈,语义栈)应该读入哪些值。voidaction2(inti,strings)//同action1只是表示算术文法-8-intaddress(stringm[],inti,stringx)//获得在分析表中的列下标voidgoto1(inti,strings)//通过判断栈中的元素,来判断用那个产生式来进行规约voidgoto2(inti,strings)//同goto1voidslr1()//对说明文法进行语法分析voidslr1()//对算术文法进行语法分析伪代码如下:先判断是说明文法还是算术文法If(说明文法)Slr1(){push_seq1(s1,0);push_seq2(s2,#);push_seq2(s3,_);while(1){j=address(v1,8,get1);top_seq1(s1,top);j=analysis_table1[top][j];if(j0){{if(j==-1)用S-D;归约elseif(j==-2)用D-intid归约elseif(j==-3)用D-floatid归约elseif(j==-4)用D-D,id归约}elseif(j0)action1(top,get1);}}elseSlr2(){push_seq1(s1,0);push_seq2(s2,#);push_seq2(s3,_);while(1){j=address(v2,13,get1);-9-j=analysis_table2[top][j];if(j0)action2(top,get1);elseif(j0){if(j==-1)用A-id=E;归约elseif(j==-2)用E-E+T归约elseif(j==-3)用E-T归约elseif(j==-4)用T-T*F归约);elseif(j==-5)用T-F归约elseif(j==-6)用F-(E)归约elseif(j==-7)用F-id归约elseif(j==-8)用F-num归约}}3.3、语义分析一个程序经过词法分析,语法分析之后,表明该院程序在书写上是正确的,但是未对程序的内部逻辑语义进行分析,接下来是进行语义分析。语义分析当中各个函数说明:voidprint(strings[])//打印四元式str1,stringstr2,stringstr3,stringstr4)//产生四元式stringnewtemp()//产生一个新的临时变量-10-3.4、程序实现结果图图3-4语义分析结果图-11-图3-5二元式图3-6符号表图3-7四元式附录#includeiostream#includefstreamusingnamespacestd;#definemaxsize5021#definemax30ifstreaminfile;charch;intm,n,kk=0,addr=0,t=1;stringget1;stringin[maxsize];stringins[maxsize];strings