编译原理课程设计(词法分析,语法分析,语义分析,代码生成)
(完整版)编译原理词法分析和语法分析报告+代码(C语言版)[1]
![(完整版)编译原理词法分析和语法分析报告+代码(C语言版)[1]](https://img.taocdn.com/s3/m/cbda17cbed630b1c58eeb512.png)
词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。
二、实验要求2.1待分析的简单的词法( 1)关键字:begin if then while do end所有的关键字都是小写。
( 2)运算符和界符:=+-*/<<=<>>>==;()#( 3)其他单词是标识符(ID )和整型常数( SUM ),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*( 4)空格有空白、制表符和换行符组成。
空格一般用来分隔ID 、SUM 、运算符、界符和关键字,词法分析阶段通常被忽略。
2.2各种单词符号对应的种别码:表 2.1各种单词符号对应的种别码单词符号种别码单词符号种别码bgin1:17If2: =18Then3<20wile4<>21do5<=22end6>23lettet( letter|digit ) *10>=24 dight dight*11=25 +13;26—14(27*15)28/16#02.3词法分析程序的功能:输入:所给文法的源程序字符串。
输出:二元组( syn,token 或 sum)构成的序列。
其中: syn 为单词种别码;token 为存放的单词自身字符串;sum 为整型常数。
例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end # 的源文件,经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)三、词法分析程序的算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
3.1主程序示意图:主程序示意图如图3-1 所示。
其中初始包括以下两个方面:⑴ 关键字表的初值。
编译原理课程设计教案

编译原理课程设计教案第一章:编译原理概述1.1 编译器的作用与重要性解释编译器将高级语言程序转换为机器语言程序的过程强调编译器在软件开发中的关键角色1.2 编译原理的基本概念介绍编译程序的基本组成部分,如词法分析器、语法分析器、语义分析器、中间代码器、目标代码器和代码优化器等解释源程序、目标程序和中间代码的概念1.3 编译过程的阶段详细介绍编译过程的各个阶段,包括词法分析、语法分析、语义分析、中间代码、代码优化和目标代码强调每个阶段的目标和重要性第二章:词法分析2.1 词法分析的基本概念解释词法分析器的任务和作用介绍词法单位的概念,如标识符、关键字、常量和符号等2.2 词法分析的技术和方法介绍词法分析常用的技术和方法,如有限自动机、正则表达式和词法规则等解释词法分析过程中的扫描线和词法单元的产生过程2.3 词法分析器的实现介绍如何实现一个简单的词法分析器,包括词法规则的定义和词法分析器的构造提供相关的编程练习,让学生通过编写代码实现基本的词法分析功能第三章:语法分析3.1 语法分析的基本概念解释语法分析器的任务和作用介绍语法规则和语法树的概念3.2 语法分析的技术和方法介绍语法分析常用的技术和方法,如递归下降分析法、LL分析法、LR分析法等解释语法分析过程中的分析表和状态机的概念3.3 语法分析器的实现介绍如何实现一个简单的语法分析器,包括语法规则的定义和语法分析器的构造提供相关的编程练习,让学生通过编写代码实现基本的语法分析功能第四章:语义分析4.1 语义分析的基本概念解释语义分析器的任务和作用介绍语义规则和语义错误的概念4.2 语义分析的技术和方法介绍语义分析常用的技术和方法,如类型检查、上下文无关文法分析、语义规则等解释语义分析过程中的语义规则和语义冲突的解决方法4.3 语义分析器的实现介绍如何实现一个简单的语义分析器,包括语义规则的定义和语义分析器的构造提供相关的编程练习,让学生通过编写代码实现基本的语义分析功能第五章:中间代码5.1 中间代码的基本概念解释中间代码器的任务和作用介绍中间代码的概念和中间代码的原则5.2 中间代码的技术和方法介绍中间代码的常用技术和方法,如三地址代码、静态单赋值代码等解释中间代码过程中的基本规则和操作符的转换5.3 中间代码器的实现介绍如何实现一个简单的中间代码器,包括中间代码的定义和中间代码器的构造提供相关的编程练习,让学生通过编写代码实现基本的中间代码功能第六章:代码优化6.1 代码优化的基本概念解释代码优化器的任务和作用介绍代码优化的目标和常见的优化技术6.2 常见代码优化技术详细介绍各种代码优化技术,如常量折叠、死代码消除、循环优化、表达式简化等强调优化技术对提高程序性能的重要性6.3 代码优化器的实现介绍如何实现一个简单的代码优化器,包括优化规则的定义和代码优化器的构造提供相关的编程练习,让学生通过编写代码实现基本的代码优化功能第七章:目标代码7.1 目标代码的基本概念解释目标代码器的任务和作用介绍目标代码的概念和目标代码的原则7.2 目标代码的技术和方法介绍目标代码的常用技术和方法,如寄存器分配、指令调度等解释目标代码过程中的基本规则和操作符的转换7.3 目标代码器的实现介绍如何实现一个简单的目标代码器,包括目标代码的定义和目标代码器的构造提供相关的编程练习,让学生通过编写代码实现基本的目标代码功能第八章:调试技术8.1 调试技术的基本概念解释调试器的作用和重要性介绍调试过程中的常见问题和调试技术8.2 调试器的结构和原理详细介绍调试器的结构和原理,如断点、单步执行、查看变量等功能强调调试技术对发现和修复程序错误的重要性8.3 调试器的实现介绍如何实现一个简单的调试器,包括断点的设置、单步执行、变量查看等功能提供相关的编程练习,让学生通过编写代码实现基本的调试功能第九章:编译器性能评价9.1 编译器性能评价的基本概念解释编译器性能评价的目的和方法介绍编译器性能评价的指标和评价方法9.2 编译器性能评价的指标和评价方法详细介绍编译器性能评价的指标,如执行速度、内存占用、编译时间等介绍常用的编译器性能评价方法和工具9.3 编译器性能评价的实践介绍如何进行编译器性能评价的实践,包括评价指标的选取和评价方法的实施提供相关的实践练习,让学生通过实际操作评价编译器的性能第十章:编译原理应用与发展趋势10.1 编译原理在软件开发中的应用介绍编译原理在软件开发中的应用领域,如解释器设计、即时编译、程序分析等强调编译原理在提高程序性能和开发效率方面的重要性10.2 编译原理的研究现状与未来发展介绍编译原理研究领域的前沿技术和最新研究成果探讨编译原理未来的发展趋势和挑战10.3 编译原理在实践中的应用案例分析分析编译原理在实际项目中的应用案例,如开源编译器项目、商业编译器产品等引导学生思考如何将编译原理应用于实际工程实践中的问题重点和难点解析重点环节一:编译器的作用与重要性编译器作为程序设计语言和计算机硬件之间的桥梁,其作用不可忽视。
编译原理_教学设计方案

一、课程概述编译原理是计算机科学中的一个核心课程,主要研究如何将高级语言程序转换为机器语言或中间代码的过程。
本课程旨在使学生掌握编译器的基本原理和设计方法,培养学生分析和解决问题的能力。
二、教学目标1. 知识目标:- 理解编译器的基本概念、工作原理和设计方法。
- 掌握词法分析、语法分析、语义分析、代码生成和优化等编译器核心组件的工作原理。
- 了解编译器在软件工程中的重要作用。
2. 能力目标:- 能够分析和设计简单的编译器。
- 能够运用编译原理知识解决实际问题。
- 培养学生的编程能力和算法设计能力。
3. 素质目标:- 培养学生的逻辑思维能力和严谨的学术态度。
- 增强学生的团队合作意识和沟通能力。
三、教学内容1. 引言:编译器的概念、发展历史和作用。
2. 词法分析:正规表达式、有限自动机、词法分析器设计。
3. 语法分析:上下文无关文法、递归下降分析、LL(1)分析、LR分析。
4. 语义分析:类型检查、作用域分析、语义规则。
5. 中间代码生成:三地址码、四元式、逆波兰表示法。
6. 代码优化:数据流分析、代码优化策略。
7. 目标代码生成:机器代码、汇编语言、目标代码生成技术。
8. 编译器构造工具:编译器生成器、代码优化工具。
四、教学方法1. 讲授法:系统讲解编译原理的基本概念、原理和方法。
2. 案例分析法:通过分析经典的编译器案例,加深对理论知识的理解。
3. 实验法:设计实验,让学生动手实现编译器的基本组件。
4. 讨论法:组织课堂讨论,激发学生的学习兴趣,培养学生的批判性思维。
5. 项目法:设计编译器开发项目,让学生综合运用所学知识。
五、教学过程1. 导入:介绍编译原理的重要性,激发学生的学习兴趣。
2. 讲解:系统讲解编译原理的基本概念和原理。
3. 案例分析:分析经典的编译器案例,帮助学生理解理论知识。
4. 实验:设计实验,让学生动手实现编译器的基本组件。
5. 讨论:组织课堂讨论,解决学生在学习过程中遇到的问题。
编译原理课程设计(词法分析,语法分析,语义分析,代码生成)

#include<cstdio>#include<iostream>#include<cstdlib>#include<fstream>#include<string>#include<cmath>using namespace std;/*********************下面是一些重要数据结构的声明***************************/struct token//词法token结构体{int code;//编码int num;//递增编号token *next;};token *token_head,*token_tail;//token队列struct str//词法string结构体{int num;//编号string word;//字符串内容str *next;};str *string_head,*string_tail;//string队列struct ivan//语法产生式结构体{char left;//产生式的左部string right;//产生式的右部int len;//产生式右部的长度};ivan css[20];//语法20个产生式struct pank//语法action表结构体{char sr;//移进或归约int state;//转到的状态编号};pank action[46][18];//action表int go_to[46][11];//语法go_to表struct ike//语法分析栈结构体,双链{ike *pre;int num;//状态int word;//符号编码ike *next;};ike *stack_head,*stack_tail;//分析栈首尾指针struct L//语义四元式的数据结构{int k;string op;//操作符string op1;//操作数string op2;//操作数string result;//结果L *next;//语义四元式向后指针L *Ltrue;//回填true链向前指针L *Lfalse;//回填false链向前指针};L *L_four_head,*L_four_tail,*L_true_head,*L_false_head;//四元式链,true链,false链struct symb//语义输入时符号表{string word;//变量名称int addr;//变量地址symb *next;};symb *symb_head,*symb_tail;//语义符号链表/*********************下面是与词法分析相关的一些函数的声明***************************/void scan();//按字符读取源文件void cifa_main();//词法分析主程序int judge(char ch);//判断输入字符的类型void out1(char ch);//写入token.txtvoid out3(char ch,string word);//写入string.txtvoid input1(token *temp);//插入结点到队列tokenvoid input3(str *temp);//插入结点到队列stringvoid output();//输出三个队列的内容void outfile();//输出三个队列的内容到相应文件中/*********************下面是与语法分析相关的一些函数的声明***************************/void yufa_main();//语法分析主程序void yufa_initialize();//初始化语法分析数据结构int yufa_SLR1(int a);//语法分析主体部分int ID1(int a);//给输入字符编号,转化成action表列编号string ID10(int i);//给输入字符反编号int ID2(char ch);//给非终结状态编号,转化成go_to表列编号int ID20(char ch);//给非终结状态编号char ID21(int j);//给非终结状态反编号void add(ike *temp);//给ike分析栈链表增加一个结点void del();//给ike分析栈链表删除一个结点/*********************下面是与语义分析相关的一些函数的声明***************************/void yuyi_main(int m);//语义分析主程序void add_L_four(L *temp);//向四元式链中加一个结点void add_L_true(L *temp);//向true链中加一个结点void add_L_false(L *temp);//向false链中加一个结点void add_symb(symb *temp);//向语义符号表链中加一个结点void output_yuyi();//输出中间代码四元式和最后符号表string newop(int m);//把数字变成字符串string id_numtoname(int num);//把编号转换成相应的变量名int lookup(string m);//变量声明检查/*********************下面是一些全局变量的声明***************************/FILE *fp;//文件指针int wordcount;//标志符计数int err;//标志词法分析结果正确或错误int nl;//读取行数int yuyi_linshi;//语义临时变量string E_name,T_name,F_name,M_name,id_name,id1_name,id2_name,errword;//用于归约时名称传递和未声明变量的输出int id_num,id1_num,id2_num,id_left,id_while,id_then,id_do;//用于记录一些特殊的字符位置信息/****************************主程序开始**************************/int main(){cout<<"************************"<<endl;cout<<"* 说明:*"<<endl;cout<<"* 第一部分:词法分析*"<<endl;cout<<"* 第二部分:语法分析*"<<endl;cout<<"* 第三部分:语义分析*"<<endl;cout<<"************************"<<endl;cifa_main();//词法yufa_main();//语法output_yuyi();//语义cout<<endl;system("pause");return(0);}/****************************以上是主程序,以下是词法**************************/void cifa_main(){token_head=new token;token_head->next=NULL;token_tail=new token;token_tail->next=NULL;string_head=new str;string_head->next=NULL;string_tail=new str;string_tail->next=NULL;//初始化三个队列的首尾指针L_four_head=new L;L_four_head->next=NULL;L_four_tail=new L;L_four_tail->k=0;L_four_tail->next=NULL;L_true_head=new L;L_true_head->Ltrue=NULL;L_false_head=new L;L_false_head->Lfalse=NULL;symb_head=new symb;symb_head->next=NULL;symb_tail=new symb;symb_tail->next=NULL;yuyi_linshi=-1;id_num=0;wordcount=0;//初始化字符计数器err=0;//初始化词法分析错误标志nl=1;//初始化读取行数scan();if(err==0){char m;output();cout<<"词法分析正确完成!"<<endl<<endl<<"如果将结果保存到文件中请输入y ,否则请输入其它字母:";cin>>m;cout<<endl;if(m=='y'){outfile();cout<<"结果成功保存在token.txt和sting.txt两个文件中,请打开查看"<<endl;cout<<endl;}}void scan(){cout<<endl;system("pause");cout<<endl;char ch;string word;char document[50];int flag=0;cout<<"请输入源文件路径及名称:";cin>>document;cout<<endl;cout<<"************************"<<endl;cout<<"* 第一部分:词法分析*"<<endl;cout<<"************************"<<endl;if((fp=fopen(document,"rt"))==NULL){err=1;cout<<"无法找到该文件!"<<endl;return;}while(!feof(fp)){word="";ch=fgetc(fp);flag=judge(ch);if(flag==1)out1(ch);else if(flag==3)out3(ch,word);else if(flag==4 || flag==5 ||flag==6)continue;else{cout<<nl<<"行"<<"错误:非法字符! "<<ch<<endl;err=1;}}fclose(fp);}int judge(char ch)int flag=0;if(ch=='=' || ch=='+' || ch=='*' || ch=='>' || ch==':' || ch==';' || ch=='{' || ch=='}' || ch=='(' || ch==')') flag=1;//界符else if(('a'<=ch && ch<='z') || ('A'<=ch && ch<='Z'))flag=3;//字母else if(ch==' ')flag=4;//空格else if(feof(fp))flag=5;//结束else if(ch=='\n'){flag=6;//换行nl++;}elseflag=0;//非法字符return(flag);}void out1(char ch){int id;switch(ch){case '=' : id=1;break;case '+' : id=2;break;case '*' : id=3;break;case '>' : id=4;break;case ':' : id=5;break;case ';' : id=6;break;case '{' : id=7;break;case '}' : id=8;break;case '(' : id=9;break;case ')' : id=10;break;//界符编码default : id=0;}token *temp;temp=new token;temp->code=id;temp->num=-1;temp->next=NULL;input1(temp);return;}void out3(char ch,string word){token *temp;temp=new token;temp->code=-1;temp->num=-1;temp->next=NULL;str *temp1;temp1=new str;temp1->num=-1;temp1->word="";temp1->next=NULL;int flag=0;word=word+ch;ch=fgetc(fp);flag=judge(ch);if(flag==1 || flag==4 || flag==5 || flag==6){if(word=="and" || word=="if" || word=="then" || word=="while" || word=="do" || word=="int") {if(word=="and")temp->code=31;else if(word=="if")temp->code=32;else if(word=="then")temp->code=33;else if(word=="while")temp->code=35;else if(word=="do")temp->code=36;else if(word=="int")temp->code=37;//关键字编码input1(temp);if(flag==1)out1(ch);else if(flag==4 || flag==5 || flag==6)return;}else if(flag==1){wordcount++;temp->code=25;temp->num=wordcount;input1(temp);temp1->num=wordcount;temp1->word=word;input3(temp1);out1(ch);}else if(flag==4 || flag==5 || flag==6){wordcount++;temp->code=25;temp->num=wordcount;input1(temp);temp1->num=wordcount;temp1->word=word;input3(temp1);}return;}else if(flag==2 || flag==3)out3(ch,word);//形成字符串else{err=1;cout<<nl<<"行"<<"错误:非法字符! "<<ch<<endl; return;}}void input1(token *temp){if(token_head->next == NULL){token_head->next=temp;token_tail->next=temp;}else{token_tail->next->next=temp;token_tail->next=temp;}}void input3(str *temp){if(string_head->next == NULL){string_head->next=temp;string_tail->next=temp;}else{string_tail->next->next=temp;string_tail->next=temp;}}void output(){cout<<"token表内容如下:"<<endl;token *temp1;temp1=new token;temp1=token_head->next;while(temp1!=NULL){cout<<temp1->code;if(temp1->num == -1){cout<<endl;}else{cout<<" "<<temp1->num<<endl;}temp1=temp1->next;}cout<<"符号表内容如下:"<<endl;str *temp3;temp3=new str;temp3=string_head->next;while(temp3!=NULL){cout<<temp3->num<<" "<<temp3->word<<endl; temp3=temp3->next;}}void outfile(){ofstream fout1("token.txt");//写文件ofstream fout3("string.txt");token *temp1;temp1=new token;temp1=token_head->next;while(temp1!=NULL){fout1<<temp1->code;if(temp1->num == -1)fout1<<endl;elsefout1<<" "<<temp1->num<<endl;temp1=temp1->next;}str *temp3;temp3=new str;temp3=string_head->next;while(temp3!=NULL){fout3<<temp3->num<<" "<<temp3->word<<endl;temp3=temp3->next;}}/****************************以上是词法,以下是语法**************************/void yufa_main(){if(err==0){system("pause");cout<<endl;cout<<"************************"<<endl;cout<<"* 第二部分:语法分析*"<<endl;cout<<"************************"<<endl;yufa_initialize();//初始化语法分析数据结构token *temp;temp=new token;temp=token_head->next;int p,q;p=0;q=0;cout<<"语法分析过程如下:"<<endl;while(temp!=NULL){int w;w=ID1(temp->code);p=yufa_SLR1(w);if(p==1) break;if(p==0)temp=temp->next;if(temp==NULL) q=1;}//语法分析if(q==1)while(1){p=yufa_SLR1(17);if(p==3) break;}//最后输入$来完成语法分析}}void yufa_initialize(){stack_head=new ike;stack_tail=new ike;stack_head->pre=NULL;stack_head->next=stack_tail;stack_head->num=0;stack_head->word='!';stack_tail->pre=stack_head;stack_tail->next=NULL;//初始化栈分析链表css[0].left='Q';css[0].right="P";css[1].left='P';css[1].right="id()L;R";css[2].left='L';css[2].right="L;D";css[3].left='L';css[3].right="D";css[4].left='D';css[4].right="id:int";css[5].left='E';css[5].right="E+T";css[6].left='E';css[6].right="T";css[7].left='T';css[7].right="T*F";css[8].left='T';css[8].right="F";css[9].left='F';css[9].right="(E)";css[10].left='F';css[10].right="id";css[11].left='B';css[11].right="B and B";css[12].left='B';css[12].right="id>id";css[13].left='M';css[13].right="id=E";css[14].left='S';css[14].right="if B then M";css[15].left='S';css[15].right="while B do M";css[16].left='S';css[16].right="M";css[17].left='N';css[17].right="N;S";css[18].left='N';css[18].right="S";css[19].left='R';css[19].right="{N}";int i,j;for(i=0;i<20;i++){char *css_len;css_len=&css[i].right[0];css[i].len=strlen(css_len);}css[1].len=6;css[4].len=3;css[10].len=1;css[11].len=3;css[12].len=3;css[13].len=3;css[14].len=4;css[15].len=4;//初始化产生式for(i=0;i<46;i++){for(j=0;j<18;j++)action[i][j].sr='#';}//初始化action表for(i=0;i<46;i++){for(j=0;j<11;j++)go_to[i][j]=-1;}//初始化go_to表/****************************以下是给action表和go_to表赋初值************************/action[0][0].sr='s';action[0][0].state=2; action[1][17].sr='@';//结束action[2][1].sr='s';action[2][1].state=3; action[3][2].sr='s';action[3][2].state=4; action[4][0].sr='s';action[4][0].state=5; action[5][4].sr='s';action[5][4].state=6; action[6][11].sr='s';action[6][11].state=7; action[7][3].sr='r';action[7][3].state=4; action[8][3].sr='r';action[8][3].state=3; action[9][3].sr='s';action[9][3].state=10; action[10][0].sr='s';action[10][0].state=5; action[10][9].sr='s';action[10][9].state=13; action[11][17].sr='r';action[11][17].state=1; action[12][3].sr='r';action[12][3].state=2; action[13][0].sr='s';action[13][0].state=14; action[13][13].sr='s';action[13][13].state=23; action[13][15].sr='s';action[13][15].state=27; action[14][8].sr='s';action[14][8].state=15; action[15][0].sr='s';action[15][0].state=36; action[15][1].sr='s';action[15][1].state=41; action[16][6].sr='s';action[16][6].state=43; action[16][3].sr='r';action[16][3].state=13; action[16][10].sr='r';action[16][10].state=13; action[17][3].sr='s';action[17][3].state=19; action[17][10].sr='s';action[17][10].state=18; action[18][17].sr='r';action[18][17].state=19; action[19][0].sr='s';action[19][0].state=14; action[19][13].sr='s';action[19][13].state=23; action[19][15].sr='s';action[19][15].state=27; action[20][3].sr='r';action[20][3].state=17; action[20][10].sr='r';action[20][10].state=17; action[21][3].sr='r';action[21][3].state=18; action[21][10].sr='r';action[21][10].state=18; action[22][3].sr='r';action[22][3].state=16; action[22][10].sr='r';action[22][10].state=16; action[23][0].sr='s';action[23][0].state=31; action[24][12].sr='s';action[24][12].state=34; action[24][14].sr='s';action[24][14].state=25; action[25][0].sr='s';action[25][0].state=14; action[26][3].sr='r';action[26][3].state=14; action[26][10].sr='r';action[26][10].state=14; action[27][0].sr='s';action[27][0].state=31; action[28][12].sr='s';action[28][12].state=34; action[28][16].sr='s';action[28][16].state=29;action[30][3].sr='r';action[30][3].state=15; action[30][10].sr='r';action[30][10].state=15; action[31][7].sr='s';action[31][7].state=32; action[32][0].sr='s';action[32][0].state=33; action[33][12].sr='r';action[33][12].state=12; action[33][14].sr='r';action[33][14].state=12; action[33][16].sr='r';action[33][16].state=12; action[34][0].sr='s';action[34][0].state=31; action[35][12].sr='r';action[35][12].state=11; action[35][14].sr='r';action[35][14].state=11; action[35][16].sr='r';action[35][16].state=11; action[36][2].sr='r';action[36][2].state=10; action[36][3].sr='r';action[36][3].state=10; action[36][5].sr='r';action[36][5].state=10; action[36][6].sr='r';action[36][6].state=10; action[36][10].sr='r';action[36][10].state=10; action[37][2].sr='r';action[37][2].state=8; action[37][3].sr='r';action[37][3].state=8; action[37][5].sr='r';action[37][5].state=8; action[37][6].sr='r';action[37][6].state=8; action[37][10].sr='r';action[37][10].state=8; action[38][2].sr='r';action[38][2].state=6; action[38][3].sr='r';action[38][3].state=6; action[38][5].sr='s';action[38][5].state=39; action[38][6].sr='r';action[38][6].state=6; action[38][10].sr='r';action[38][10].state=6; action[39][0].sr='s';action[39][0].state=36; action[39][1].sr='s';action[39][1].state=41; action[40][2].sr='r';action[40][2].state=7; action[40][3].sr='r';action[40][3].state=7; action[40][5].sr='r';action[40][5].state=7; action[40][6].sr='r';action[40][6].state=7; action[40][10].sr='r';action[40][10].state=7; action[41][0].sr='s';action[41][0].state=36; action[41][1].sr='s';action[41][1].state=41; action[42][2].sr='s';action[42][2].state=45; action[42][6].sr='s';action[42][6].state=43; action[43][0].sr='s';action[43][0].state=36; action[43][1].sr='s';action[43][1].state=41; action[44][2].sr='r';action[44][2].state=5; action[44][3].sr='r';action[44][3].state=5; action[44][5].sr='s';action[44][5].state=39; action[44][6].sr='r';action[44][6].state=5;action[45][2].sr='r';action[45][2].state=9;action[45][3].sr='r';action[45][3].state=9;action[45][5].sr='r';action[45][5].state=9;action[45][6].sr='r';action[45][6].state=9;action[45][10].sr='r';action[45][10].state=9;go_to[0][0]=1;go_to[4][1]=8;go_to[4][9]=9;go_to[10][1]=12;go_to[10][2]=11;go_to[13][7]=22;go_to[13][8]=2 1;go_to[13][10]=17;go_to[15][3]=16;go_to[15][4]=38;go_to[15][5]=37;go_to[19][7]=20;go_to[19][8]=20;go_to[23][6]=24;go_to[2 5][7]=26;go_to[27][6]=28;go_to[29][7]=30;go_to[34][6]=35;go_to[39][5]=40;go_to[41][3]=42;go_to[41][4]=38;go_to[41][5]=37;go_to[4 3][4]=44;go_to[43][5]=37;/****************************action表和go_to表赋初值完毕************************/}int ID1(int i)//按action表,给输入字符编号{int j;j=-1;if(i==25) {j=0;id_num++;}//设置变量名称标志if(i==1) {j=8,id_left=id_num;}//设置产生试左边变量名称标志if(i==2) j=6;if(i==3) j=5;if(i==4) j=7;if(i==5) j=4;if(i==6) j=3;if(i==7) j=9;if(i==8) j=10;if(i==9) j=1;if(i==10) j=2;if(i==31) j=12;if(i==32) j=13;if(i==33) {j=14;id_then=L_four_tail->k+1;}//设置if语句中then位置标志if(i==35) {j=15;id_while=L_four_tail->k+1;}//设置while语句中while位置标志if(i==36) {j=16;id_do=L_four_tail->k+1;}//设置while语句中do位置标志if(i==37) j=11;return(j);}string ID10(int i)//反编号输入字符{string ch;if(i==0) ch="id";if(i==1) ch="(";if(i==2) ch=")";if(i==3) ch=";";if(i==4) ch=":";if(i==5) ch="*";if(i==6) ch="+";if(i==7) ch=">";if(i==8) ch="=";if(i==9) ch="{";if(i==10) ch="}";if(i==11) ch="int";if(i==12) ch="and";if(i==13) ch="if";if(i==14) ch="then";if(i==15) ch="while";if(i==16) ch="do";if(i==17) ch="$";return(ch);}int ID2(char ch)//按go_to表给非终结符编号{int j;j=-1;if(ch=='P') j=0;if(ch=='D') j=1;if(ch=='R') j=2;if(ch=='E') j=3;if(ch=='T') j=4;if(ch=='F') j=5;if(ch=='B') j=6;if(ch=='M') j=7;if(ch=='S') j=8;if(ch=='L') j=9;if(ch=='N') j=10;return(j);}int ID20(char ch)//给非终结符编号{int j;j=-1;if(ch=='P') j=100;if(ch=='D') j=101;if(ch=='R') j=102;if(ch=='E') j=103;if(ch=='T') j=104;if(ch=='F') j=105;if(ch=='B') j=106;if(ch=='M') j=107;if(ch=='S') j=108;if(ch=='L') j=109;if(ch=='N') j=1010;return(j);}char ID21(int j)//反编号非终结符{char ch;if(j==100 || j==0) ch='P';if(j==101 || j==1) ch='D';if(j==102 || j==2) ch='R';if(j==103 || j==3) ch='E';if(j==104 || j==4) ch='T';if(j==105 || j==5) ch='F';if(j==106 || j==6) ch='B';if(j==107 || j==7) ch='M';if(j==108 || j==8) ch='S';if(j==109 || j==9) ch='L';if(j==1010 || j==10) ch='N'; return(ch);}void add(ike *temp)//加一个结点{if(stack_head->next==stack_tail) {temp->pre=stack_head;temp->next=stack_tail;stack_head->next=temp;stack_tail->pre=temp;}else{temp->pre=stack_tail->pre; temp->next=stack_tail;stack_tail->pre->next=temp; stack_tail->pre=temp;}}void del()//删除一个结点{stack_tail->pre->pre->next=stack_tail;stack_tail->pre=stack_tail->pre->pre;}int yufa_SLR1(int w){/*cout<<"当前输入符号:"<<ID10(w)<<" ";*/int i,flag=0,state_temp;//flag错误标志,0正常移进,1错误,2归约,3结束char sr_temp;sr_temp=action[stack_tail->pre->num][w].sr;//动作state_temp=action[stack_tail->pre->num][w].state;//状态变化if(sr_temp=='#')//错误动作{flag=1;err=3;cout<<"语法分析出错!"<<endl;}else if(sr_temp=='s')//移进动作{ike *temp;temp=new ike;temp->next=NULL;temp->pre=NULL;temp->word=w;temp->num=state_temp;add(temp);cout/*<<"动作(移进):"*/<<sr_temp<<state_temp<<" "/*<<"状态转为:"<<stack_tail->pre->num<<" "<<"栈顶符号:"<<ID10(stack_tail->pre->word)*/<<endl;flag=0;}else if(sr_temp=='r')//归约动作{int p=ID2(css[state_temp].left);int q=css[state_temp].len;for(i=0;i<q;i++)del();ike *temp;temp=new ike;temp->next=NULL;temp->pre=NULL;temp->word=ID20(css[state_temp].left);temp->num=go_to[stack_tail->pre->num][p];//查go_to表add(temp);cout/*<<"动作(归约):"*/<<sr_temp<<state_temp<<" "<<css[state_temp].left<<"→"<<css[state_temp].right<<" "/*<<"状态转为:"<<stack_tail->pre->num<<" "<<"栈顶符号:"<<ID21(stack_tail->pre->word)*/<<endl;flag=2;yuyi_main(state_temp);//在产生树的同时进行语义分析}else if(sr_temp=='@')//结束动作{cout<<"END"/*<<"动作(归约):"<<sr_temp<<state_temp*/<<" "<<css[state_temp].left<<"→"<<css[state_temp].right<<" "/*<<"状态转为:"<<stack_tail->pre->num<<" "<<"栈顶符号:"<<ID21(stack_tail->pre->word)*/<<endl;flag=3;cout<<"语法分析正确完成!"<<endl;}else//其他意外情况{flag=1;err=3;cout<<"语法分析出错!"<<endl;}return(flag);}/****************************以上是语法,以下是语义**************************/void yuyi_main(int m){L *temp;int k;k=1;temp=new L;temp->op=" ";temp->op1=" ";temp->op2=" ";temp->result="";temp->next=NULL;temp->Ltrue=NULL;temp->Lfalse=NULL;if(m==4)//变量声明时加入符号表链{symb *Stemp;Stemp=new symb;id_name=id_numtoname(id_num);Stemp->word=id_name;Stemp->next=NULL;add_symb(Stemp);}if(m==5)//归约E→E+T{temp->op="+";temp->op1=E_name;temp->op2=T_name;yuyi_linshi++;//申请临时变量E_name="t"+newop(yuyi_linshi); temp->result=E_name;add_L_four(temp);//加一个四元式结点}if(m==6)//归约E→T{E_name=T_name;}if(m==7)//归约T→T*F{temp->op="*";temp->op1=T_name;temp->op2=F_name;yuyi_linshi++;//申请临时变量T_name="t"+newop(yuyi_linshi); temp->result=T_name;add_L_four(temp);//加一个四元式结点}if(m==8)//归约T→F{T_name=F_name;}if(m==9)//归约F→(E){F_name=E_name;}if(m==10)//归约F→id{id_name=id_numtoname(id_num);F_name=id_name;k=lookup(id_name);//检查变量是否声明if(k==0){err=2;errword=id_name;return;}}if(m==12)//归约B→id>id{temp->op="J>";id1_num=id_num-1;id1_name=id_numtoname(id1_num);k=lookup(id1_name);//检查变量是否声明if(k==0){err=2;errword=id1_name;return;}id2_num=id_num;id2_name=id_numtoname(id2_num);k=lookup(id2_name);//检查变量是否声明if(k==0){err=2;errword=id2_name;return;}temp->result="-1";temp->op1=id1_name;temp->op2=id2_name;add_L_four(temp);//加一个四元式结点add_L_true(temp);//加一个true链结点L *temp2;temp2=new L;temp2->op="J";temp2->op1=" ";temp2->op2=" ";temp2->result="-1";add_L_four(temp2);//加一个四元式结点add_L_false(temp2);//加一个false链结点}if(m==13)//归约M→id=E{temp->op="=";temp->op1=E_name;temp->op2=" ";id_name=id_numtoname(id_left);temp->result=id_name;add_L_four(temp);//加一个四元式结点yuyi_linshi=-1;//临时变量开始重新计数}if(m==14)//归约S→if B then M{int a;a=id_then;temp=L_true_head->Ltrue;while(temp!=NULL){temp->result="L"+newop(a);a=temp->k;temp=temp->Ltrue;}a=L_four_tail->k+1;temp=L_false_head->Lfalse;while(temp!=NULL){temp->result="L"+newop(a);temp=temp->Lfalse;}L_true_head->Ltrue=NULL;L_false_head->Lfalse=NULL;//回填并清空true链和false链}if(m==15)//归约S→while B do M{int a;a=id_do;temp=L_true_head->Ltrue;while(temp!=NULL){temp->result="L"+newop(a);a=temp->k;temp=temp->Ltrue;}a=L_four_tail->k+2;temp=L_false_head->Lfalse;while(temp!=NULL){temp->result="L"+newop(a);temp=temp->Lfalse;}L *temp1;temp1=new L;temp1->op="J";temp1->op1=" ";temp1->op2=" ";temp1->next=NULL;temp1->result="L"+newop(id_while);add_L_four(temp1);//加一个四元式结点L_true_head->Ltrue=NULL;L_false_head->Lfalse=NULL;//回填并清空true链和false链}}string newop(int m)//数字变成字符串{int shang,yushu;string chuan,chuan1;shang=m;chuan="";while(1){yushu=shang%10;chuan=chuan+char(48+yushu);shang=shang/10;if(shang==0)break;}int i;char *ch;ch=&chuan[0];chuan1="";for(i=strlen(ch)-1;i>=0;i--)chuan1=chuan1+chuan[i];return(chuan1);}void add_L_four(L *temp)//加一个四元式结点{temp->k=L_four_tail->k+1;if(L_four_head->next == NULL){L_four_head->next=temp;L_four_tail->next=temp;}else{L_four_tail->next->next=temp;L_four_tail->next=temp;}L_four_tail->k=L_four_tail->next->k;}void add_L_true(L *temp)//加一个true链结点{temp->Ltrue=L_true_head->Ltrue;L_true_head->Ltrue=temp;}void add_L_false(L *temp)//加一个false链结点{temp->Lfalse=L_false_head->Lfalse;L_false_head->Lfalse=temp;}void add_symb(symb *temp)//加一个语义符号表链结点{if(symb_head->next == NULL){temp->addr=0;symb_head->next=temp;symb_tail->next=temp;}else{temp->addr=symb_tail->next->addr+4;symb_tail->next->next=temp;symb_tail->next=temp;}}void output_yuyi(){if(err==0)//语义分析正确时的输出{cout<<endl;system("pause");cout<<endl;cout<<"************************"<<endl;cout<<"* 第三部分:语义分析*"<<endl;cout<<"************************"<<endl;cout<<"中间代码如下:"<<endl;L *temp;temp=L_four_head->next;while(temp!=NULL){。
编译原理与技术

编译原理与技术
当我们谈论编译原理与技术时,我们在讨论的是一种方法和技术,通过它们可以将高级编程语言转换为计算机可执行的机器码。
编译原理是计算机科学的一个重要领域,涉及到编译器的设计和开发过程。
编译原理的基本概念包括词法分析、语法分析、语义分析、中间代码生成、代码优化和代码生成等。
词法分析是将源代码转换成单词序列的过程,而语法分析则是将这些单词序列组织成语法树的过程。
语义分析负责检查语义错误,并生成中间代码。
中间代码生成是将高级语言转换为中间表示形式的过程,可以是抽象语法树、三地址码或类似的形式。
在这个阶段,编译器还可以进行各种优化,如常量折叠、循环展开和内联优化等。
代码生成是将中间代码转换为目标代码的过程,目标代码可以是机器码、汇编代码或其他可执行形式。
在最终的代码生成阶段,还可以进行最后的优化和调整,以提高代码的运行效率。
编译原理与技术在软件开发过程中起着关键作用。
通过使用编译原理与技术,开发人员可以更高效地将高级编程语言转换为计算机可以理解和执行的代码。
这种转换过程不仅可以提高程序的执行效率,还可以提供更好的错误检测和调试功能。
总之,编译原理与技术是一门重要的学科,可以帮助开发人员更好地理解和应用编译器技术,从而提高软件开发的效率和质量。
编译原理的实验报告

一、实验目的1. 理解编译原理的基本概念和原理。
2. 掌握编译器的各个阶段及其实现方法。
3. 能够运用编译原理的知识解决实际问题。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 20194. 实验内容:词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成三、实验内容1. 词法分析(1)实验目的:实现一个简单的词法分析器,将源代码中的字符序列转换为词法符号序列。
(2)实验步骤:1)定义词法符号类型,包括标识符、关键字、运算符、常量等。
2)设计词法分析器算法,对源代码进行遍历,将字符序列转换为词法符号序列。
3)实现词法分析器程序,输出词法符号序列。
(3)实验结果:输入源代码:int a = 10;输出词法符号序列:{<int, int>, <a, a>, <=, =>, <10, 10>, <;, ;>}2. 语法分析(1)实验目的:实现一个简单的语法分析器,将词法符号序列转换为抽象语法树(AST)。
(2)实验步骤:1)定义语法规则,包括产生式、非终结符、终结符等。
2)设计语法分析算法,根据语法规则对词法符号序列进行解析,生成AST。
3)实现语法分析器程序,输出AST。
(3)实验结果:输入词法符号序列:{<int, int>, <a, a>, <=, =>, <10, 10>, <;, ;>}输出AST:```AST:- ExpressionStatement- Expression- BinaryExpression- Identifier: a- Operator: =- Constant: 10```3. 语义分析(1)实验目的:实现语义分析器,对AST进行语义检查,确保程序的正确性。
(2)实验步骤:1)定义语义规则,包括类型检查、作用域检查等。
编译原理-课程教学设计方案

《编译原理》课程教学设计方案适用专业:计算机科学技术编制人:系部主任:审核人:编制日期:2014年4院15日目录一、《编译原理》课程整体教学设计方案 (1)(一)基本信息 (1)(二)课程设计 (1)(三)考核方案设计 (4)(四)教学组织形式 (5)(五)教学材料 (5)二、课程单元教学方案设计 (6)(一)教学内容1 (6)1、教案头 (6)2、教学过程设计 (6)(二)教学内容2 (7)1、教案头 (7)2、教学过程设计 (8)(三)教学内容3 (10)1、教案头 (10)2、教学过程设计 (10)《编译原理》课程教学设计方案一、《编译原理》课程整体教学设计方案(一)基本信息课程名称:编译原理学时:72学时课程类型:专业技能课学分:3学分所属系部:计算机科学系授课对象:二年级学生先修课程:《数据结构》、《离散数学》后续课程:《JAVA程序设计》课程团队负责人及成员:孔玉静(二)课程设计1、课程目标设计(1)能力目标:培养学生掌握构造编译程序的基本原理与设计方法,为培养计算机语言与大型应用程序的开发人才打下良好的基础。
(2)知识目标:通过本课程学习,使学生掌握编译程序的一般构造原理,包括语言基础知识、词法分析程序设计原理和构造方法。
各种语法分析技术和中间代码生成符号表的构造、代码优化、并行编译技术常识及运行时存储空间的组织等基本方法和主要实现技术。
2、课程教学内容设计3、能力训练项目设计4、教学进度表设计5、教学方法与教学手段设计课堂教学:多媒体教学进行教学,使学生能够很快掌握课程的主要知识和解决问题的方法。
辅导和答疑:以习题课对课程中的重要概念和典型问题的解决方法进行总结和深入讨论,巩固和加深课堂内学到的知识。
采用电子邮件方式直接与教师联系进行答疑。
自学与练习:除读懂教科书中所讲内容外,还需大量做题。
其目的是要通过做题弄懂、加深对概念的理解,提高解决问题的能力。
为此,安排一定的实验上机学时。
编译原理的课课程设计

编译原理的课课程设计一、教学目标本课程的教学目标是使学生掌握编译原理的基本概念、理论和方法,能够运用编译原理解决实际问题。
具体分为以下三个部分:1.知识目标:学生需要掌握编译原理的基本概念,包括编译器的基本结构、词法分析、语法分析、语义分析、中间代码生成、目标代码生成和优化等。
2.技能目标:学生需要具备使用编译原理解决实际问题的能力,包括能够使用编译器开发工具,进行词法分析、语法分析和语义分析等操作。
3.情感态度价值观目标:通过本课程的学习,使学生认识到编译原理在软件工程中的重要性,增强学生对计算机科学的热爱和责任感。
二、教学内容本课程的教学内容主要包括以下几个部分:1.编译器的基本结构:包括前端和后端的基本组成部分,以及它们之间的交互关系。
2.词法分析:包括词法规则的定义、词法分析器的实现和词法分析的过程。
3.语法分析:包括语法规则的定义、语法分析树的构建和语法分析的方法。
4.语义分析:包括语义规则的定义、语义分析的方法和语义分析的实现。
5.中间代码生成:包括中间代码的定义、中间代码生成的方法和中间代码优化的方法。
6.目标代码生成:包括目标代码的定义、目标代码生成的方法和目标代码优化的方法。
三、教学方法本课程采用多种教学方法,以激发学生的学习兴趣和主动性:1.讲授法:教师通过讲解编译原理的基本概念和理论,使学生掌握相关知识。
2.案例分析法:教师通过分析实际的编译器案例,使学生了解编译原理在实际中的应用。
3.实验法:学生通过动手实现编译器的基本功能,加深对编译原理的理解。
4.讨论法:学生通过分组讨论,共同解决问题,培养团队协作能力。
四、教学资源本课程的教学资源包括以下几个部分:1.教材:选用《编译原理》作为主要教材,为学生提供系统性的理论知识。
2.参考书:提供相关的参考书籍,为学生提供更多的学习资源。
3.多媒体资料:制作PPT、视频等多媒体资料,丰富课堂教学。
4.实验设备:提供计算机实验室,让学生能够实际操作编译器。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include<cstdio>#include<iostream>#include<cstdlib>#include<fstream>#include<string>#include<cmath>using namespace std;/*********************下面是一些重要数据结构的声明***************************/struct token//词法token结构体{int code;//编码int num;//递增编号token *next;};token *token_head,*token_tail;//token队列struct str//词法string结构体{int num;//编号string word;//字符串内容str *next;};str *string_head,*string_tail;//string队列struct ivan//语法产生式结构体{char left;//产生式的左部string right;//产生式的右部int len;//产生式右部的长度};ivan css[20];//语法20个产生式struct pank//语法action表结构体{char sr;//移进或归约int state;//转到的状态编号};pank action[46][18];//action表int go_to[46][11];//语法go_to表struct ike//语法分析栈结构体,双链{ike *pre;int num;//状态int word;//符号编码ike *next;};ike *stack_head,*stack_tail;//分析栈首尾指针struct L//语义四元式的数据结构{int k;string op;//操作符string op1;//操作数string op2;//操作数string result;//结果L *next;//语义四元式向后指针L *Ltrue;//回填true链向前指针L *Lfalse;//回填false链向前指针};L *L_four_head,*L_four_tail,*L_true_head,*L_false_head;//四元式链,true链,false链struct symb//语义输入时符号表{string word;//变量名称int addr;//变量地址symb *next;};symb *symb_head,*symb_tail;//语义符号链表/*********************下面是与词法分析相关的一些函数的声明***************************/void scan();//按字符读取源文件void cifa_main();//词法分析主程序int judge(char ch);//判断输入字符的类型void out1(char ch);//写入token.txtvoid out3(char ch,string word);//写入string.txtvoid input1(token *temp);//插入结点到队列tokenvoid input3(str *temp);//插入结点到队列stringvoid output();//输出三个队列的内容void outfile();//输出三个队列的内容到相应文件中/*********************下面是与语法分析相关的一些函数的声明***************************/void yufa_main();//语法分析主程序void yufa_initialize();//初始化语法分析数据结构int yufa_SLR1(int a);//语法分析主体部分int ID1(int a);//给输入字符编号,转化成action表列编号string ID10(int i);//给输入字符反编号int ID2(char ch);//给非终结状态编号,转化成go_to表列编号int ID20(char ch);//给非终结状态编号char ID21(int j);//给非终结状态反编号void add(ike *temp);//给ike分析栈链表增加一个结点void del();//给ike分析栈链表删除一个结点/*********************下面是与语义分析相关的一些函数的声明***************************/void yuyi_main(int m);//语义分析主程序void add_L_four(L *temp);//向四元式链中加一个结点void add_L_true(L *temp);//向true链中加一个结点void add_L_false(L *temp);//向false链中加一个结点void add_symb(symb *temp);//向语义符号表链中加一个结点void output_yuyi();//输出中间代码四元式和最后符号表string newop(int m);//把数字变成字符串string id_numtoname(int num);//把编号转换成相应的变量名int lookup(string m);//变量声明检查/*********************下面是一些全局变量的声明***************************/FILE *fp;//文件指针int wordcount;//标志符计数int err;//标志词法分析结果正确或错误int nl;//读取行数int yuyi_linshi;//语义临时变量string E_name,T_name,F_name,M_name,id_name,id1_name,id2_name,errword;//用于归约时名称传递和未声明变量的输出int id_num,id1_num,id2_num,id_left,id_while,id_then,id_do;//用于记录一些特殊的字符位置信息/****************************主程序开始**************************/int main(){cout<<"************************"<<endl;cout<<"* 说明:*"<<endl;cout<<"* 第一部分:词法分析*"<<endl;cout<<"* 第二部分:语法分析*"<<endl;cout<<"* 第三部分:语义分析*"<<endl;cout<<"************************"<<endl;cifa_main();//词法yufa_main();//语法output_yuyi();//语义cout<<endl;system("pause");return(0);}/****************************以上是主程序,以下是词法**************************/void cifa_main(){token_head=new token;token_head->next=NULL;token_tail=new token;token_tail->next=NULL;string_head=new str;string_head->next=NULL;string_tail=new str;string_tail->next=NULL;//初始化三个队列的首尾指针L_four_head=new L;L_four_head->next=NULL;L_four_tail=new L;L_four_tail->k=0;L_four_tail->next=NULL;L_true_head=new L;L_true_head->Ltrue=NULL;L_false_head=new L;L_false_head->Lfalse=NULL;symb_head=new symb;symb_head->next=NULL;symb_tail=new symb;symb_tail->next=NULL;yuyi_linshi=-1;id_num=0;wordcount=0;//初始化字符计数器err=0;//初始化词法分析错误标志nl=1;//初始化读取行数scan();if(err==0){char m;output();cout<<"词法分析正确完成!"<<endl<<endl<<"如果将结果保存到文件中请输入y ,否则请输入其它字母:";cin>>m;cout<<endl;if(m=='y'){outfile();cout<<"结果成功保存在token.txt和sting.txt两个文件中,请打开查看"<<endl;cout<<endl;}}void scan(){cout<<endl;system("pause");cout<<endl;char ch;string word;char document[50];int flag=0;cout<<"请输入源文件路径及名称:";cin>>document;cout<<endl;cout<<"************************"<<endl;cout<<"* 第一部分:词法分析*"<<endl;cout<<"************************"<<endl;if((fp=fopen(document,"rt"))==NULL){err=1;cout<<"无法找到该文件!"<<endl;return;}while(!feof(fp)){word="";ch=fgetc(fp);flag=judge(ch);if(flag==1)out1(ch);else if(flag==3)out3(ch,word);else if(flag==4 || flag==5 ||flag==6)continue;else{cout<<nl<<"行"<<"错误:非法字符! "<<ch<<endl;err=1;}}fclose(fp);}int judge(char ch)int flag=0;if(ch=='=' || ch=='+' || ch=='*' || ch=='>' || ch==':' || ch==';' || ch=='{' || ch=='}' || ch=='(' || ch==')') flag=1;//界符else if(('a'<=ch && ch<='z') || ('A'<=ch && ch<='Z'))flag=3;//字母else if(ch==' ')flag=4;//空格else if(feof(fp))flag=5;//结束else if(ch=='\n'){flag=6;//换行nl++;}elseflag=0;//非法字符return(flag);}void out1(char ch){int id;switch(ch){case '=' : id=1;break;case '+' : id=2;break;case '*' : id=3;break;case '>' : id=4;break;case ':' : id=5;break;case ';' : id=6;break;case '{' : id=7;break;case '}' : id=8;break;case '(' : id=9;break;case ')' : id=10;break;//界符编码default : id=0;}token *temp;temp=new token;temp->code=id;temp->num=-1;temp->next=NULL;input1(temp);return;}void out3(char ch,string word){token *temp;temp=new token;temp->code=-1;temp->num=-1;temp->next=NULL;str *temp1;temp1=new str;temp1->num=-1;temp1->word="";temp1->next=NULL;int flag=0;word=word+ch;ch=fgetc(fp);flag=judge(ch);if(flag==1 || flag==4 || flag==5 || flag==6){if(word=="and" || word=="if" || word=="then" || word=="while" || word=="do" || word=="int") {if(word=="and")temp->code=31;else if(word=="if")temp->code=32;else if(word=="then")temp->code=33;else if(word=="while")temp->code=35;else if(word=="do")temp->code=36;else if(word=="int")temp->code=37;//关键字编码input1(temp);if(flag==1)out1(ch);else if(flag==4 || flag==5 || flag==6)return;}else if(flag==1){wordcount++;temp->code=25;temp->num=wordcount;input1(temp);temp1->num=wordcount;temp1->word=word;input3(temp1);out1(ch);}else if(flag==4 || flag==5 || flag==6){wordcount++;temp->code=25;temp->num=wordcount;input1(temp);temp1->num=wordcount;temp1->word=word;input3(temp1);}return;}else if(flag==2 || flag==3)out3(ch,word);//形成字符串else{err=1;cout<<nl<<"行"<<"错误:非法字符! "<<ch<<endl; return;}}void input1(token *temp){if(token_head->next == NULL){token_head->next=temp;token_tail->next=temp;}else{token_tail->next->next=temp;token_tail->next=temp;}}void input3(str *temp){if(string_head->next == NULL){string_head->next=temp;string_tail->next=temp;}else{string_tail->next->next=temp;string_tail->next=temp;}}void output(){cout<<"token表内容如下:"<<endl;token *temp1;temp1=new token;temp1=token_head->next;while(temp1!=NULL){cout<<temp1->code;if(temp1->num == -1){cout<<endl;}else{cout<<" "<<temp1->num<<endl;}temp1=temp1->next;}cout<<"符号表内容如下:"<<endl;str *temp3;temp3=new str;temp3=string_head->next;while(temp3!=NULL){cout<<temp3->num<<" "<<temp3->word<<endl; temp3=temp3->next;}}void outfile(){ofstream fout1("token.txt");//写文件ofstream fout3("string.txt");token *temp1;temp1=new token;temp1=token_head->next;while(temp1!=NULL){fout1<<temp1->code;if(temp1->num == -1)fout1<<endl;elsefout1<<" "<<temp1->num<<endl;temp1=temp1->next;}str *temp3;temp3=new str;temp3=string_head->next;while(temp3!=NULL){fout3<<temp3->num<<" "<<temp3->word<<endl;temp3=temp3->next;}}/****************************以上是词法,以下是语法**************************/void yufa_main(){if(err==0){system("pause");cout<<endl;cout<<"************************"<<endl;cout<<"* 第二部分:语法分析*"<<endl;cout<<"************************"<<endl;yufa_initialize();//初始化语法分析数据结构token *temp;temp=new token;temp=token_head->next;int p,q;p=0;q=0;cout<<"语法分析过程如下:"<<endl;while(temp!=NULL){int w;w=ID1(temp->code);p=yufa_SLR1(w);if(p==1) break;if(p==0)temp=temp->next;if(temp==NULL) q=1;}//语法分析if(q==1)while(1){p=yufa_SLR1(17);if(p==3) break;}//最后输入$来完成语法分析}}void yufa_initialize(){stack_head=new ike;stack_tail=new ike;stack_head->pre=NULL;stack_head->next=stack_tail;stack_head->num=0;stack_head->word='!';stack_tail->pre=stack_head;stack_tail->next=NULL;//初始化栈分析链表css[0].left='Q';css[0].right="P";css[1].left='P';css[1].right="id()L;R";css[2].left='L';css[2].right="L;D";css[3].left='L';css[3].right="D";css[4].left='D';css[4].right="id:int";css[5].left='E';css[5].right="E+T";css[6].left='E';css[6].right="T";css[7].left='T';css[7].right="T*F";css[8].left='T';css[8].right="F";css[9].left='F';css[9].right="(E)";css[10].left='F';css[10].right="id";css[11].left='B';css[11].right="B and B";css[12].left='B';css[12].right="id>id";css[13].left='M';css[13].right="id=E";css[14].left='S';css[14].right="if B then M";css[15].left='S';css[15].right="while B do M";css[16].left='S';css[16].right="M";css[17].left='N';css[17].right="N;S";css[18].left='N';css[18].right="S";css[19].left='R';css[19].right="{N}";int i,j;for(i=0;i<20;i++){char *css_len;css_len=&css[i].right[0];css[i].len=strlen(css_len);}css[1].len=6;css[4].len=3;css[10].len=1;css[11].len=3;css[12].len=3;css[13].len=3;css[14].len=4;css[15].len=4;//初始化产生式for(i=0;i<46;i++){for(j=0;j<18;j++)action[i][j].sr='#';}//初始化action表for(i=0;i<46;i++){for(j=0;j<11;j++)go_to[i][j]=-1;}//初始化go_to表/****************************以下是给action表和go_to表赋初值************************/action[0][0].sr='s';action[0][0].state=2; action[1][17].sr='@';//结束action[2][1].sr='s';action[2][1].state=3; action[3][2].sr='s';action[3][2].state=4; action[4][0].sr='s';action[4][0].state=5; action[5][4].sr='s';action[5][4].state=6; action[6][11].sr='s';action[6][11].state=7; action[7][3].sr='r';action[7][3].state=4; action[8][3].sr='r';action[8][3].state=3; action[9][3].sr='s';action[9][3].state=10; action[10][0].sr='s';action[10][0].state=5; action[10][9].sr='s';action[10][9].state=13; action[11][17].sr='r';action[11][17].state=1; action[12][3].sr='r';action[12][3].state=2; action[13][0].sr='s';action[13][0].state=14; action[13][13].sr='s';action[13][13].state=23; action[13][15].sr='s';action[13][15].state=27; action[14][8].sr='s';action[14][8].state=15; action[15][0].sr='s';action[15][0].state=36; action[15][1].sr='s';action[15][1].state=41; action[16][6].sr='s';action[16][6].state=43; action[16][3].sr='r';action[16][3].state=13; action[16][10].sr='r';action[16][10].state=13; action[17][3].sr='s';action[17][3].state=19; action[17][10].sr='s';action[17][10].state=18; action[18][17].sr='r';action[18][17].state=19; action[19][0].sr='s';action[19][0].state=14; action[19][13].sr='s';action[19][13].state=23; action[19][15].sr='s';action[19][15].state=27; action[20][3].sr='r';action[20][3].state=17; action[20][10].sr='r';action[20][10].state=17; action[21][3].sr='r';action[21][3].state=18; action[21][10].sr='r';action[21][10].state=18; action[22][3].sr='r';action[22][3].state=16; action[22][10].sr='r';action[22][10].state=16; action[23][0].sr='s';action[23][0].state=31; action[24][12].sr='s';action[24][12].state=34; action[24][14].sr='s';action[24][14].state=25; action[25][0].sr='s';action[25][0].state=14; action[26][3].sr='r';action[26][3].state=14; action[26][10].sr='r';action[26][10].state=14; action[27][0].sr='s';action[27][0].state=31; action[28][12].sr='s';action[28][12].state=34; action[28][16].sr='s';action[28][16].state=29;action[30][3].sr='r';action[30][3].state=15; action[30][10].sr='r';action[30][10].state=15; action[31][7].sr='s';action[31][7].state=32; action[32][0].sr='s';action[32][0].state=33; action[33][12].sr='r';action[33][12].state=12; action[33][14].sr='r';action[33][14].state=12; action[33][16].sr='r';action[33][16].state=12; action[34][0].sr='s';action[34][0].state=31; action[35][12].sr='r';action[35][12].state=11; action[35][14].sr='r';action[35][14].state=11; action[35][16].sr='r';action[35][16].state=11; action[36][2].sr='r';action[36][2].state=10; action[36][3].sr='r';action[36][3].state=10; action[36][5].sr='r';action[36][5].state=10; action[36][6].sr='r';action[36][6].state=10; action[36][10].sr='r';action[36][10].state=10; action[37][2].sr='r';action[37][2].state=8; action[37][3].sr='r';action[37][3].state=8; action[37][5].sr='r';action[37][5].state=8; action[37][6].sr='r';action[37][6].state=8; action[37][10].sr='r';action[37][10].state=8; action[38][2].sr='r';action[38][2].state=6; action[38][3].sr='r';action[38][3].state=6; action[38][5].sr='s';action[38][5].state=39; action[38][6].sr='r';action[38][6].state=6; action[38][10].sr='r';action[38][10].state=6; action[39][0].sr='s';action[39][0].state=36; action[39][1].sr='s';action[39][1].state=41; action[40][2].sr='r';action[40][2].state=7; action[40][3].sr='r';action[40][3].state=7; action[40][5].sr='r';action[40][5].state=7; action[40][6].sr='r';action[40][6].state=7; action[40][10].sr='r';action[40][10].state=7; action[41][0].sr='s';action[41][0].state=36; action[41][1].sr='s';action[41][1].state=41; action[42][2].sr='s';action[42][2].state=45; action[42][6].sr='s';action[42][6].state=43; action[43][0].sr='s';action[43][0].state=36; action[43][1].sr='s';action[43][1].state=41; action[44][2].sr='r';action[44][2].state=5; action[44][3].sr='r';action[44][3].state=5; action[44][5].sr='s';action[44][5].state=39; action[44][6].sr='r';action[44][6].state=5;action[45][2].sr='r';action[45][2].state=9;action[45][3].sr='r';action[45][3].state=9;action[45][5].sr='r';action[45][5].state=9;action[45][6].sr='r';action[45][6].state=9;action[45][10].sr='r';action[45][10].state=9;go_to[0][0]=1;go_to[4][1]=8;go_to[4][9]=9;go_to[10][1]=12;go_to[10][2]=11;go_to[13][7]=22;go_to[13][8]=2 1;go_to[13][10]=17;go_to[15][3]=16;go_to[15][4]=38;go_to[15][5]=37;go_to[19][7]=20;go_to[19][8]=20;go_to[23][6]=24;go_to[2 5][7]=26;go_to[27][6]=28;go_to[29][7]=30;go_to[34][6]=35;go_to[39][5]=40;go_to[41][3]=42;go_to[41][4]=38;go_to[41][5]=37;go_to[4 3][4]=44;go_to[43][5]=37;/****************************action表和go_to表赋初值完毕************************/}int ID1(int i)//按action表,给输入字符编号{int j;j=-1;if(i==25) {j=0;id_num++;}//设置变量名称标志if(i==1) {j=8,id_left=id_num;}//设置产生试左边变量名称标志if(i==2) j=6;if(i==3) j=5;if(i==4) j=7;if(i==5) j=4;if(i==6) j=3;if(i==7) j=9;if(i==8) j=10;if(i==9) j=1;if(i==10) j=2;if(i==31) j=12;if(i==32) j=13;if(i==33) {j=14;id_then=L_four_tail->k+1;}//设置if语句中then位置标志if(i==35) {j=15;id_while=L_four_tail->k+1;}//设置while语句中while位置标志if(i==36) {j=16;id_do=L_four_tail->k+1;}//设置while语句中do位置标志if(i==37) j=11;return(j);}string ID10(int i)//反编号输入字符{string ch;if(i==0) ch="id";if(i==1) ch="(";if(i==2) ch=")";if(i==3) ch=";";if(i==4) ch=":";if(i==5) ch="*";if(i==6) ch="+";if(i==7) ch=">";if(i==8) ch="=";if(i==9) ch="{";if(i==10) ch="}";if(i==11) ch="int";if(i==12) ch="and";if(i==13) ch="if";if(i==14) ch="then";if(i==15) ch="while";if(i==16) ch="do";if(i==17) ch="$";return(ch);}int ID2(char ch)//按go_to表给非终结符编号{int j;j=-1;if(ch=='P') j=0;if(ch=='D') j=1;if(ch=='R') j=2;if(ch=='E') j=3;if(ch=='T') j=4;if(ch=='F') j=5;if(ch=='B') j=6;if(ch=='M') j=7;if(ch=='S') j=8;if(ch=='L') j=9;if(ch=='N') j=10;return(j);}int ID20(char ch)//给非终结符编号{int j;j=-1;if(ch=='P') j=100;if(ch=='D') j=101;if(ch=='R') j=102;if(ch=='E') j=103;if(ch=='T') j=104;if(ch=='F') j=105;if(ch=='B') j=106;if(ch=='M') j=107;if(ch=='S') j=108;if(ch=='L') j=109;if(ch=='N') j=1010;return(j);}char ID21(int j)//反编号非终结符{char ch;if(j==100 || j==0) ch='P';if(j==101 || j==1) ch='D';if(j==102 || j==2) ch='R';if(j==103 || j==3) ch='E';if(j==104 || j==4) ch='T';if(j==105 || j==5) ch='F';if(j==106 || j==6) ch='B';if(j==107 || j==7) ch='M';if(j==108 || j==8) ch='S';if(j==109 || j==9) ch='L';if(j==1010 || j==10) ch='N'; return(ch);}void add(ike *temp)//加一个结点{if(stack_head->next==stack_tail) {temp->pre=stack_head;temp->next=stack_tail;stack_head->next=temp;stack_tail->pre=temp;}else{temp->pre=stack_tail->pre; temp->next=stack_tail;stack_tail->pre->next=temp; stack_tail->pre=temp;}}void del()//删除一个结点{stack_tail->pre->pre->next=stack_tail;stack_tail->pre=stack_tail->pre->pre;}int yufa_SLR1(int w){/*cout<<"当前输入符号:"<<ID10(w)<<" ";*/int i,flag=0,state_temp;//flag错误标志,0正常移进,1错误,2归约,3结束char sr_temp;sr_temp=action[stack_tail->pre->num][w].sr;//动作state_temp=action[stack_tail->pre->num][w].state;//状态变化if(sr_temp=='#')//错误动作{flag=1;err=3;cout<<"语法分析出错!"<<endl;}else if(sr_temp=='s')//移进动作{ike *temp;temp=new ike;temp->next=NULL;temp->pre=NULL;temp->word=w;temp->num=state_temp;add(temp);cout/*<<"动作(移进):"*/<<sr_temp<<state_temp<<" "/*<<"状态转为:"<<stack_tail->pre->num<<" "<<"栈顶符号:"<<ID10(stack_tail->pre->word)*/<<endl;flag=0;}else if(sr_temp=='r')//归约动作{int p=ID2(css[state_temp].left);int q=css[state_temp].len;for(i=0;i<q;i++)del();ike *temp;temp=new ike;temp->next=NULL;temp->pre=NULL;temp->word=ID20(css[state_temp].left);temp->num=go_to[stack_tail->pre->num][p];//查go_to表add(temp);cout/*<<"动作(归约):"*/<<sr_temp<<state_temp<<" "<<css[state_temp].left<<"→"<<css[state_temp].right<<" "/*<<"状态转为:"<<stack_tail->pre->num<<" "<<"栈顶符号:"<<ID21(stack_tail->pre->word)*/<<endl;flag=2;yuyi_main(state_temp);//在产生树的同时进行语义分析}else if(sr_temp=='@')//结束动作{cout<<"END"/*<<"动作(归约):"<<sr_temp<<state_temp*/<<" "<<css[state_temp].left<<"→"<<css[state_temp].right<<" "/*<<"状态转为:"<<stack_tail->pre->num<<" "<<"栈顶符号:"<<ID21(stack_tail->pre->word)*/<<endl;flag=3;cout<<"语法分析正确完成!"<<endl;}else//其他意外情况{flag=1;err=3;cout<<"语法分析出错!"<<endl;}return(flag);}/****************************以上是语法,以下是语义**************************/void yuyi_main(int m){L *temp;int k;k=1;temp=new L;temp->op=" ";temp->op1=" ";temp->op2=" ";temp->result="";temp->next=NULL;temp->Ltrue=NULL;temp->Lfalse=NULL;if(m==4)//变量声明时加入符号表链{symb *Stemp;Stemp=new symb;id_name=id_numtoname(id_num);Stemp->word=id_name;Stemp->next=NULL;add_symb(Stemp);}if(m==5)//归约E→E+T{temp->op="+";temp->op1=E_name;temp->op2=T_name;yuyi_linshi++;//申请临时变量E_name="t"+newop(yuyi_linshi); temp->result=E_name;add_L_four(temp);//加一个四元式结点}if(m==6)//归约E→T{E_name=T_name;}if(m==7)//归约T→T*F{temp->op="*";temp->op1=T_name;temp->op2=F_name;yuyi_linshi++;//申请临时变量T_name="t"+newop(yuyi_linshi); temp->result=T_name;add_L_four(temp);//加一个四元式结点}if(m==8)//归约T→F{T_name=F_name;}if(m==9)//归约F→(E){F_name=E_name;}if(m==10)//归约F→id{id_name=id_numtoname(id_num);F_name=id_name;k=lookup(id_name);//检查变量是否声明if(k==0){err=2;errword=id_name;return;}}if(m==12)//归约B→id>id{temp->op="J>";id1_num=id_num-1;id1_name=id_numtoname(id1_num);k=lookup(id1_name);//检查变量是否声明if(k==0){err=2;errword=id1_name;return;}id2_num=id_num;id2_name=id_numtoname(id2_num);k=lookup(id2_name);//检查变量是否声明if(k==0){err=2;errword=id2_name;return;}temp->result="-1";temp->op1=id1_name;temp->op2=id2_name;add_L_four(temp);//加一个四元式结点add_L_true(temp);//加一个true链结点L *temp2;temp2=new L;temp2->op="J";temp2->op1=" ";temp2->op2=" ";temp2->result="-1";add_L_four(temp2);//加一个四元式结点add_L_false(temp2);//加一个false链结点}if(m==13)//归约M→id=E{temp->op="=";temp->op1=E_name;temp->op2=" ";id_name=id_numtoname(id_left);temp->result=id_name;add_L_four(temp);//加一个四元式结点yuyi_linshi=-1;//临时变量开始重新计数}if(m==14)//归约S→if B then M{int a;a=id_then;temp=L_true_head->Ltrue;while(temp!=NULL){temp->result="L"+newop(a);a=temp->k;temp=temp->Ltrue;}a=L_four_tail->k+1;temp=L_false_head->Lfalse;while(temp!=NULL){temp->result="L"+newop(a);temp=temp->Lfalse;}L_true_head->Ltrue=NULL;L_false_head->Lfalse=NULL;//回填并清空true链和false链}if(m==15)//归约S→while B do M{int a;a=id_do;temp=L_true_head->Ltrue;while(temp!=NULL){temp->result="L"+newop(a);a=temp->k;temp=temp->Ltrue;}a=L_four_tail->k+2;temp=L_false_head->Lfalse;while(temp!=NULL){temp->result="L"+newop(a);temp=temp->Lfalse;}L *temp1;temp1=new L;temp1->op="J";temp1->op1=" ";temp1->op2=" ";temp1->next=NULL;temp1->result="L"+newop(id_while);add_L_four(temp1);//加一个四元式结点L_true_head->Ltrue=NULL;L_false_head->Lfalse=NULL;//回填并清空true链和false链}}string newop(int m)//数字变成字符串{int shang,yushu;string chuan,chuan1;shang=m;chuan="";while(1){yushu=shang%10;chuan=chuan+char(48+yushu);shang=shang/10;if(shang==0)break;}int i;char *ch;ch=&chuan[0];chuan1="";for(i=strlen(ch)-1;i>=0;i--)chuan1=chuan1+chuan[i];return(chuan1);}void add_L_four(L *temp)//加一个四元式结点{temp->k=L_four_tail->k+1;if(L_four_head->next == NULL){L_four_head->next=temp;L_four_tail->next=temp;}else{L_four_tail->next->next=temp;L_four_tail->next=temp;}L_four_tail->k=L_four_tail->next->k;}void add_L_true(L *temp)//加一个true链结点{temp->Ltrue=L_true_head->Ltrue;L_true_head->Ltrue=temp;}void add_L_false(L *temp)//加一个false链结点{temp->Lfalse=L_false_head->Lfalse;L_false_head->Lfalse=temp;}void add_symb(symb *temp)//加一个语义符号表链结点{if(symb_head->next == NULL){temp->addr=0;symb_head->next=temp;symb_tail->next=temp;}else{temp->addr=symb_tail->next->addr+4;symb_tail->next->next=temp;symb_tail->next=temp;}}void output_yuyi(){if(err==0)//语义分析正确时的输出{cout<<endl;system("pause");cout<<endl;cout<<"************************"<<endl;cout<<"* 第三部分:语义分析*"<<endl;cout<<"************************"<<endl;cout<<"中间代码如下:"<<endl;L *temp;temp=L_four_head->next;while(temp!=NULL){。