编译原理课程设计词法分析
编译原理课程设计说明书--词法分析,语法分析,语义分析
编译原理课程设计说明书题目:编译器原型设计与开发院(系):计算机科学与工程学院专业:计算机科学与技术目录1 引言 (1)1.1 设计概述 (1)1.2 设计目标 (2)1.3 小组分工 (3)2 开发过程 (3)2.1 词法分析 (3)2.1.1 消除白空格以及注释 (3)2.1.2 词法分析 (6)2.2 .语法分析 (8)2.2.1 递归下降手工编码 (8)2.2.2 first集合的计算 (8)2.2.3 左递归消除 (9)2.2.4 selection表自动生成 (10)2.2.5 LL(1)手工编码 (11)2.3 语义分析 (11)2.3.1 表达式求值LR(1) (11)2.3.2 四元式 (13)3 测试过程 (14)4 总结 (19)5 参考文献 (20)6 代码附录 (20)1引言编译程序是现代计算机系统的基本组成部分之一,而且多数计算机系统都配有不止一个高级语言的编译程序,对有些高级语言甚至配置了几个不同性能的编译程序。
从功能上看,一个编译程序就是一个语言翻译程序。
语言翻译程序把一种语言(称作源语言)书写的程序翻译成另一种语言(称作目标语言)的等价程序。
一个编译程序的重要性体现在它使得多数计算机用户不必考虑与机器有关的繁琐细节,使程序员和程序设计专家独立于机器,这对于当今机器的数量和种类持续不断地增长的年代尤为重要。
编译程序完成从源程序到目标程序的翻译工作,是一个复杂的整体的过程。
将编译过程划分成词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成六个阶段。
1.1设计概述编译原理程序结构框图词法分析词法分析是编译过程的第一个阶段。
这个阶段的任务是从左到右有一个字符一个字符地读入源程序,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词(也称单词符号或符号)。
这里所谓的单词是指逻辑上紧密相连的一组字符,这些字符基友具体含义。
比如标识符是由字母字符开头,后跟字母、数字字符的字符序列组成的一种单词。
编译原理词法分析课程设计
DONGFANG COLLEGE,FUJIAN AGRICULTURE AND FORESTRY UNIVERSITY课程名称:编译原理词法分析系别:计算机科学系年级专业: 2013级计算机科学与技术学号: 1350303059姓名:张清鉴任课教师:朱均燕成绩:2015 年12 月31 日目录前言 (1)一、课程设计的目的 (1)二、课程设计的要求 (1)1.待分析的简单语言的词法 (1)2.各种单词符号对应的种别码 (2)3. 此法分析程序功能 (3)三、课程设计报告内容 (3)3.1课程设计的环境 (3)3.2系统技术分析: (3)3.3 系统流程图及各模块 (4)3.4源程序代码清单 (4)3.5程序调试情况 (9)四、总结 (10)参考文献 (11)前言词法分析(英语:lexical analysis)是计算机科学中将字符序列转换为单词(Token)序列的过程。
进行词法分析的程序或者函数叫作词法分析器(Lexical analyzer,简称Lexer),也叫扫描器(Scanner)。
词法分析器一般以函数的形式存在,供语法分析器调用。
词法分析阶段是编译过程的第一个阶段,是编译的基础。
这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。
词法分析程序实现这个任务。
词法分析程序可以使用Lex等工具自动生成。
词法分析是编译程序的第一个阶段且是必要阶段;词法分析的核心任务是扫描、识别单词且对识别出的单词给出定性、定长的处理;实现词法分析程序的常用途径:自动生成,手工生成.词法分析一、课程设计的目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。
二、课程设计的要求1.待分析的简单语言的词法(1)关键字:begin if then while do end所有的关键字都是小写。
(2)运算符和界符::= + - * / <<=<>>>==:()#(3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:(4)空格由空白\制表符\和换行符组成。
编译原理词法分析实验报告
编译原理词法分析实验报告实验名称:词法分析器的设计与实现一、实验目的:1.熟悉编译原理中词法分析的基本概念和原理;2.掌握正则表达式的使用方法;3.实现一个简单的词法分析器。
二、实验内容:1.设计一个简单的编程语言,包含如下几种类型的词法单元:关键字、标识符、常量、运算符和界符。
2.使用正则表达式定义每种词法单元的模式。
3.设计一个词法分析器,将源代码中的每个词法单元识别出来并输出。
三、实验步骤:1. 确定编程语言的词法单元类型和正则表达式模式,定义相应的单词类型(如 TokenType)和模式(如 regex)。
2. 实现一个词法分析器的类 Lexer,包含以下方法:(1)一个构造方法,用于初始化词法分析器的输入源代码。
(2) 一个getNextToken方法,用于获取源代码中的下一个词法单元。
3. 在getNextToken方法中,使用正则表达式逐个识别源代码中的词法单元,并返回相应的Token对象。
4. 设计一个Token类,包含以下属性:词法单元类型、词法单元的值和位置信息等。
5.在主程序中使用词法分析器,将源代码中的每个词法单元识别出来并输出。
四、实验结果:1.设计一个简单的编程语言,包含如下词法单元类型(示例):(1) 关键字:if、else、while、for等;(2)标识符:变量名等;(3)常量:整数、浮点数、字符串等;(4)运算符:+、-、*、/、=等;(5)界符:(、)、{、}、;等。
2. 实现一个词法分析器,识别出源代码中的每个词法单元,并输出相应的Token对象。
五、实验总结:通过本次实验,我熟悉了编译原理中词法分析的基本概念和原理,并掌握了正则表达式的使用方法。
我成功完成了一个简单的词法分析器的设计与实现,实现了源代码中每个词法单元的识别与输出。
这次实验对我深化了对编译原理中词法分析的理解,并提高了我的编程能力。
编译原理课程设计—词法分析器
编译原理课程设计(一)——词法分析器1、题目编写程序实现一个简易的词法分析器。
2、实验目的对一段程序代码进行词法分析,将程序段中的关键字、标识符、常数、运算符、界符按照一定的种别编码分析出来。
3、环境及工具操作系统:windows XP ;使用工具:Microsoft Visual C++ 6.0; 编程语言:C 语言;4、分析程序输入:从文件中读入程序段;程序输出:由单词种别和单词符号的属性值组成的二元式;单词种别通常使用整数编码,编码方式可以有多种,在设计词法分析器之前应确定一种程序处理起来较方便的编码方式。
当一个种别中含有多个单词符号时,在分析出其属于哪个种别的时候应同时给出其单词符号属性,本程序为方便起见,采用单词符号本身来作为其属性,以标识同种别种的不同单词符号。
标识符及关键字的识别:字母开头的字母和数字组成的串是多数编程语言的标识符,所以我们的简易词法分析器中,将标识符定义为这种字母数字串。
当第一个字母为字母且紧接着的字符为数字或字母时,应将其串接在一起为一个单词,直到紧跟着的不在是字母数字时。
由于关键字通常为一个单词,则这样得到的串可能是标识符也可能是关键字,又因为一种语言的关键字通常是有限个,则我们可以构造一个存放所有关键字的表,查询关键字表,可以判断得到的串是否为关键字。
界符和运算符的识别:它们多为当个字符,建立两个分别存放界符合运算符的表,读取字符后,进行查表便可以得出它们的类型。
为方便词法分析器的设计,可以使用状态转换图,根据一种特定的编程语言先设计出其状态转换图才能更好将其用代码实现。
典型状态转换图结构如下:(a)有不含回路含分支的状态节点:对应if …else if …else …语句;(b)有含回路的状态节点:对应while …if …语句。
(b )5、状态转换图6、程序框架描述程序中编写了以下函数,各个函数实现的作用如下:1. GetChar():将下一输入的字符读入到全局变量ch中,搜素指示器前移一个字符的位置。
编译原理课程设计(词法分析,语法分析,语义分析,代码生成)
#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)1.1设计题目 (2)1.2 设计目的 (3)1.3 设计任务内容: (3)1.4 设计时间 (3)2 设计环境与工具 (3)3设计要求 (3)4分析与概要设计 (4)5算法描述与框图 (4)6 源程序清单 (6)7 软件测试 (10)7.1 设计的测试题目 (10)7.2测试结果截图 (10)8 总结 (10)8 参考文献 (11)1设计概述1.1设计题目词法分析器的设计与实现。
1.2 设计目的词法分析是编译程序第一个阶段的工作,它的任务是对输入的字符串形式的源程序进行扫描,在扫描的同时,根据源语言的词法规则识别具有独立意义的单词。
本设计是C++高级程序语言,数据结构和变异原理中词法分析原理等知识的综合运用。
掌握生成词法分析器的方法,加深对词法分析原理的理解,掌握设计,编制并调试词法分析程序的思想和方法。
1.3 设计任务内容:1、格式输入:将C++语言的源代码从文本文档中读入。
处理:对输入框中的代码进行词法分析,分离出关键字、标示符、数值、运算符和界符。
输出:在文本文档中输出每个单词对应的编码和值。
2、编译对象声明和其他标记赋值语句分支结构语句循环语句1.4 设计时间2012年12月23日至2012年12月28日2 设计环境与工具Windows7环境下使用 C++语言。
3设计要求1、使用任何一种编程语言编制一个词法分析程序。
2、该程序能够识别的单词有5类:(1)关键字:"long", "float", "static", "char", "short", "switch", "int", "const", "if", "then", "else", "for", "while", "break"。
编译原理课程设计词法分析器文档
2011—2012学年第一学期《编译原理》课程设计报告专业:计算机科学与技术学生姓名:张金荣指导教师:孔繁茹完成时间:2017年8月15日目录第 1 节课程设计目的 (1)第 2 节课程设计要求 (1)第 3 节课程设计内容 (2)第 4 节状态转换图 (4)第 5 节实现工具 (4)第 6 节实现函数 (4)第7 节测试结果 (5)第8 节实验源代码 (6)第9 节参考文献 (9)致谢感设计目的①理解词法分析器的基本功能。
词法分析的任务是:从左至右逐个字符地对源程序进行扫描,产生一个个的单词符号(token),把作为字符串的源程序改造成单词符号串的中间程序。
因此,词法分析是编译的基础。
②理解词法规则的描述方法。
程序设计语言一般可以用标识符、关键字、运算符、分隔符、常量、字符串和注释符来描述④理解状态转换图及其实现。
一个状态转换图可用于识别(或接受)一定的字符。
大多数程序语言的单词符号都可以用转换图予以识别。
转换图非常易于用程序实现,最简单的办法是让每个状态结对应一小段程序。
④能够编写简单的词法分析器。
2.课程设计的要求手工构造一个简单的词法分析程序, 能够识别标识符、整数、关键字、算符、界符。
①画出识别单词的状态转换图。
(若状态转换图过于复杂,可以只画出主要部分;若依旧复杂,可只识别标识符和整数)②根据状态转换图手工构造词法分析程序。
从以下方法中选一:✧词法分析器作为独立的一遍。
词法分析结果输出到屏幕上或存入文件。
✧词法分析器作为一个子程序被语法分析器调用。
每次调用返回一个单词同时将单词及属性存入符号表③实现状态转换图。
从以下方法中选一:✧直接转向法✧表驱动法四、选做实验☻使用缓冲技术3.课程设计内容程序语言的单词符号一般可分为下列五种。
(1)关键字是由程序语言定义的具有固定意义的标志符。
本程序定义char,short,int,unsigned,long,float,double,struct,union,void,enum,cons t,typedef,auto,static,break,case,continue,default,do,else,for,if,retu rn,switch,while,sizeof,printf,FILE,fopen,NULL,fclose,exit,read,closef ,printf为关键字。
编译原理词法分析器语法分析课程设计范本
《编译原理词法分析器语法分析课程设计-《编译原理》课程设计院系信息科学与技术学院专业软件工程年级级学号 2723姓名林苾湲西南交通大学信息科学与技术学院12月目录课程设计1 词法分析器 (2)设计题目 (2)设计内容 (2)设计目的 (2)设计环境 (2)需求分析 (2)概要设计 (2)详细设计 (4)编程调试 (5)测试 (11)结束语 (13)课程设计2 赋值语句的解释程序设计 (14)设计题目 (14)设计内容 (14)设计目的 (14)设计环境 (14)需求分析 (15)概要设计 (16)详细设计 (16)编程调试 (24)测试 (24)结束语 (25)课程设计一词法分析器设计一、设计题目手工设计c语言的词法分析器(能够是c语言的子集)。
二、设计内容处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。
三、设计目的了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程。
四、设计环境该课程设计包括的硬件和软件条件如下:.硬件(1)Intel Core Duo CPU P8700(2)内存4G.软件(1)Window 7 32位操作系统(2)Microsoft Visual Studio c#开发平台.编程语言C#语言五、需求分析.源程序的预处理:源程序中,存在许多编辑用的符号,她们对程序逻辑功能无任何影响。
例如:回车,换行,多余空白符,注释行等。
在词法分析之前,首先要先剔除掉这些符号,使得词法分析更为简单。
.单词符号的识别并判断单词的合法性:将每个单词符号进行不同类别的划分。
单词符号能够划分成5中。
(1)标识符:用户自己定义的名字,常量名,变量名和过程名。
(2)常数:各种类型的常数。
(3) 保留字(关键字):如if、else、while、int、float 等。
(4) 运算符:如+、-、*、<、>、=等。
编译原理词法分析实验
编译原理词法分析实验编译原理是计算机科学中的重要课程,它研究的是如何将高级语言翻译成机器语言的过程。
而词法分析则是编译原理中的一个重要环节,它负责将源程序中的字符序列转换成有意义的词素序列。
本文将介绍编译原理词法分析实验的相关内容。
1. 实验背景。
编译原理词法分析实验是计算机相关专业的重要实践环节,通过实验可以加深对编译原理词法分析相关知识的理解,提高学生的实际动手能力和解决问题的能力。
2. 实验内容。
编译原理词法分析实验通常包括以下内容:(1)词法分析器的设计与实现,学生需要设计并实现一个简单的词法分析器,能够识别出源程序中的各种词素,并进行相应的处理。
(2)正规表达式的应用,学生需要掌握正规表达式的基本语法和应用,用于描述词法分析中的各种词素模式。
(3)有限自动机的构建,学生需要学习有限自动机的基本原理和构建方法,用于实现词法分析器中的词素识别过程。
3. 实验步骤。
编译原理词法分析实验的具体步骤如下:(1)分析源程序,学生需要先对给定的源程序进行分析,了解其中包含的各种词素类型和相应的识别规则。
(2)设计词法分析器,学生根据源程序的特点,设计词法分析器的识别模式和处理方法,通常采用正规表达式描述词素的模式,再将其转换为有限自动机。
(3)实现词法分析器,学生根据设计的词法分析器,使用编程语言实现相应的词法分析器程序。
(4)测试与调试,学生需要对实现的词法分析器进行测试和调试,确保其能够正确识别源程序中的各种词素,并进行相应的处理。
4. 实验意义。
编译原理词法分析实验对于学生的意义在于:(1)加深理论知识,通过实验,学生能够更加深入地理解编译原理词法分析的相关理论知识,巩固课堂学习成果。
(2)提高实践能力,实验能够提高学生的实际动手能力和解决问题的能力,培养学生的编程思维和实践能力。
(3)促进团队合作,在实验过程中,学生通常需要分组合作完成词法分析器的设计与实现,促进了学生之间的团队合作能力。
5. 实验总结。
词法分析java编译原理课程设计
词法分析java编译原理课程设计一、教学目标本课程旨在让学生掌握词法分析在Java编译原理中的应用,理解并能够运用Java的基本词法规则,包括关键字、标识符、常量、运算符等。
通过本课程的学习,学生应能熟练使用Java编译器进行程序的编译和调试,理解编译过程中词法分析的原理和实现。
具体来说,知识目标包括:1.掌握Java语言的基本词法规则。
2.理解词法分析在编译过程中的作用和重要性。
3.熟悉Java编译器的使用方法和技巧。
技能目标包括:1.能够使用Java编译器进行程序的编译和调试。
2.能够分析并解决Java程序中的词法错误。
3.能够理解和编写简单的词法分析器。
情感态度价值观目标包括:1.培养学生对编译原理的兴趣和好奇心。
2.培养学生解决问题的能力和团队合作的精神。
3.培养学生对编程语言和计算机科学的热爱。
二、教学内容本课程的教学内容主要包括Java的基本词法规则、词法分析的原理和实现、以及Java编译器的使用方法。
具体的教学大纲如下:1.第一章:Java语言概述–Java语言的历史和发展–Java语言的特点和优势–Java语言的应用领域2.第二章:Java的基本词法规则–关键字和保留字–标识符的命名规则–常量的分类和声明–运算符的分类和用法3.第三章:词法分析原理–词法分析在编译过程中的作用–词法分析器的实现方法–词法分析器的测试和优化4.第四章:Java编译器使用–Java编译器的安装和配置–编译和运行Java程序的基本步骤–分析并解决编译过程中的词法错误5.第五章:实战演练–编写简单的Java程序–使用Java编译器进行编译和调试–分析并解决程序中的词法错误三、教学方法为了提高学生的学习兴趣和主动性,本课程将采用多种教学方法相结合的方式。
包括:1.讲授法:通过讲解和演示,让学生掌握Java的基本词法规则和词法分析的原理。
2.讨论法:学生进行小组讨论,培养团队合作的精神,并促进学生对问题的深入思考。
编译原理课程设计报告——词法分析器
精选课程设计任务书引言 (4)第一章概述 (5)1.1设计内容 (5)1.2设计要求 (5)第二章设计的基本原理 (6)2.1 (6)2.2 (6)第三章程序设计 (7)3.1 总体方案设计 (7)3.2 各模块设计 (8)第四章程序测试 (9)4.1一般测试4.2出错处理测试第五章结论 (10)参考文献 (10)附录程序清单 (11)引言《编译原理》是国内外各高等院校计算机科学技术类专业,特别是计算机软件专业的一门重要专业课程。
该课程系统地向学生介绍编译程序的结构、工作流程及编译程序各组成部分的设计原理和实现技术。
由于该课程理论性和实践性都比较强,内容较为抽象复杂,涉及到大量的软件设计算法,因此,一直是一门比较难学的课程。
为了使学生更好地理解和掌握编译技术的基本概念、基本原理和实现方法,实践环节非常重要,只有通过上机进行程序设计,才能使学生对比较抽象的教学内容产生具体的感性认识,增强学生综合分析问题、解决问题的能力,并对提高学生软件设计水平大有益处。
编译原理涉及词法分析,语法分析,语义分析及优化设计等各方面。
词法分析阶段是编译过程的第一个阶段,是编译的基础。
这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。
词法分析程序实现这个任务。
词法分析程序可以使用 Lex 等工具自动生成。
从左到右逐个字符对构成源程序的字符串进行扫描,依据词法规则,识别出一个一个的标记(token ),把源程序变为等价的标记串序列。
执行词法分析的程序称为词法分析器,也称为扫描器。
词法分析是所有分析优化的基础,涉及的知识较少,如状态转换图等,易于实现。
本次课程设计,我的选题是词法分析, C++ 代码实现。
第一章概述1.1 设计内容对 C 语言的一个子集设计并实现一个简单的词法分析器,掌握利用状态转换图设计词法分析器的基本方法。
1.2设计要求利用该词法分析器完成对源程序字符串的词法分析。
编译原理课程设计方案词法分析
目录一、实验题目3二、实验目的3三、实验要求4四、实验步骤4基本设计思路4流程框图5算法设计6函数相关说明6输入与输出8程序运行结果9五、实验方案设计实现9六、实验程序亮点描述10七、实验程序使用说明10八、实验心得体会10九、源程序清单10一、实验题目设计、编制、调试一个识别一简单语言单词的词法分析程序。
程序能够识别基本字、标识符、无符号整数、浮点数、运算符和界符)。
单词符号及种别表如下:二、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。
三、实验要求词法分析程序需具备词法分析的功能:输入:所给文法的源程序字符串。
(字符串以“#”号结束)输出:二元组(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)……四、实验步骤基本设计思路➢基本字作为一类特殊的标识符来处理:识别出标识符,差基本字表,给出相应种别码。
基本字表置初值:char *rwtab[6]={"begin","if","then","while","do","end"}。
(字符指针的数组)➢识别无符号整数是将数字串转换为无符号整数。
我们在getchar()的时候是把数字当做字符从外部输出读取的。
将数字串345#转换为整数:(3*10+4)*10+5=345送到sum中➢程序主要由2个函数组成,主函数main()和扫描子函数scanner()。
扫描程序每次读取1个独立意义的单词符号,并判断单词类型。
主程序做相应处理后做控制台输出。
编译原理课程设计报告词法分析器
一.课程设计题目:词法分析器的实现二.课程设计成员三.课程设计内容和要求设计一个程序,调试、编译,实现词法分析的功能,识别各单词或字符所属类别,并显示在屏幕上。
词法分析器:逐个读入源程序字符并按照构词规则切分成一系列单词。
单词是语言中具有独立意义的最小单位,包括保留字、标识符、运算符、标点符号和常量等。
词法分析是编译过程中的一个阶段,在语法分析前进行。
也可以和语法分析结合在一起作为一遍,由语法分析程序调用词法分析程序来获得当前单词供语法分析使用。
要求:通过词法分析器能够实现以下五种类型如单词等的识别。
(1)关键字"begin","end","if","then","else","while","write","read"等,"do", "call","const","char","until","procedure","repeat"等(2)运算符:"+","-","*","/","="等(3)界符:"{","}","[","]",";",",",".","(",")",":"等(4)标识符(5)常量四.操作要求首先建立一个或多个文档,此处新建了两个文档,例:07196133.txt文本文档和zhaoxiaodong.txt文本文档,以供选择,各文本文档中都输入有不同的内容,运行程序,出现提示,输入文本文档的名称,即可对文本文档中的内容进行分析,并把分析结果输出显示在屏幕上。
编译原理课程设计报告——词法分析器
int begin=0,end=0;
vector<string> array;
do
{
begin=DeleteNull(fileline,begin);
string nowString;
nowString=GetWord(fileline,begin,end);
单词符号
种别编码
单词符号
种别编码
main
1
[
28
int
2
]
29
char
3
{
30
if
4
}
31
else
5
,
32
for
6
:
33
while
7
;
34
标识符ID
10
>
35
整型常数NUM
20
<
36
=
21
>=
37
+
22
<=
38
-
23
==
39
*
24
!=
40
/
25
&
41
(
26
&&
42)27||43(2)关键字main int char if elseforwhile都是小写并都是保留字。
int DeleteNull(string str,int i);
/*判断i当前所指的字符是否为一个分界符,是的话返回真,反之假*/
bool IsBoundary(string str,int i);
/*判断i当前所指的字符是否为一个运算符,是的话返回真,反之假*/
编译原理课程设计-词法分析器(附含源代码)精选.
编译原理-词法分析器的设计一.设计说明及设计要求一般来说,编译程序的整个过程可以划分为五个阶段:词法分析、语法分析、中间代码生成、优化和目标代码生成。
本课程设计即为词法分析阶段。
词法分析阶段是编译过程的第一个阶段。
这个阶段的任务是从左到右一个字符一个字符地读入源程序,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词(也称单词符号或符号)。
如保留字(关键字或基本字)、标志符、常数、算符和界符等等。
二.设计中相关关键字说明1.基本字:也称关键字,如C语言中的if , else , while , do ,for,case,break,return 等。
2.标志符:用来表示各种名字,如常量名、变量名和过程名等。
3.常数:各种类型的常数,如12,6.88,和“ABC”等。
4.运算符:如+ ,- , * , / ,%, < , > ,<= , >= 等。
5.界符,如逗点,冒号,分号,括号,# ,〈〈,〉〉等。
三、程序分析词法分析是编译的第一个阶段,它的主要任务是从左到右逐个字符地对源程序进行扫描,产生一个个单词序列,用以语法分析。
词法分析工作可以是独立的一遍,把字符流的源程序变为单词序列,输出在一个中间文件上,这个文件做为语法分析程序的输入而继续编译过程。
然而,更一般的情况,常将词法分析程序设计成一个子程序,每当语法分析程序需要一个单词时,则调用该子程序。
词法分析程序每得到一次调用,便从源程序文件中读入一些字符,直到识别出一个单词,或说直到下一个单词的第一个字符为止。
四、模块设计下面是程序的流程图五、程序介绍在程序当前目录里建立一个文本文档,取名为infile.txt,所有需要分析的程序都写在此文本文档里,程序的结尾必须以“@”标志符结束。
程序结果输出在同一个目录下,文件名为outfile.txt,此文件为自动生成。
本程序所输出的单词符号采用以下二元式表示:(单词种别,单词自身的值)如程序输出结果(57,"#")(33,"include")(52,"<")(33,"iostream") 等。
编译原理课程设计报告-词法分析器
一.课程设计题目:词法分析器的实现二.课程设计成员三.课程设计内容和要求设计一个程序,调试、编译,实现词法分析的功能,识别各单词或字符所属类别,并显示在屏幕上。
词法分析器:逐个读入源程序字符并按照构词规则切分成一系列单词。
单词是语言中具有独立意义的最小单位,包括保留字、标识符、运算符、标点符号和常量等。
词法分析是编译过程中的一个阶段,在语法分析前进行。
也可以和语法分析结合在一起作为一遍,由语法分析程序调用词法分析程序来获得当前单词供语法分析使用。
要求:通过词法分析器能够实现以下五种类型如单词等的识别。
(1)关键字"begin","end","if","then","else","while","write","r ead"等,"do", "call","const","char","until","procedure","repeat"等(2)运算符:"+","-","*","/","="等(3)界符:"{","}","[","]",";",",",".","(",")",":"等(4)标识符(5)常量四.操作要求首先建立一个或多个文档,此处新建了两个文档,例:07196133.txt文本文档和zhaoxiaodong.txt文本文档,以供选择,各文本文档中都输入有不同的内容,运行程序,出现提示,输入文本文档的名称,即可对文本文档中的内容进行分析,并把分析结果输出显示在屏幕上。
编译原理实验报告 词法分析
编译原理实验一·词法分析一、实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。
同时增强编写和调试程序的能力。
二、实验内容及要求对某特定语言A ,构造其词法规则。
该语言的单词符号包括:保留字(见左下表)、标识符(字母大小写不敏感)、整型常数、界符及运算符(见右下表) 。
功能要求如下所示:·按单词符号出现的顺序,返回二元组序列,并输出。
·出现的标识符存放在标识符表,整型常数存放在常数表,并输出这两个表格。
·如果出现词法错误,报出:错误类型,位置(行,列)。
·处理段注释(/* */),行注释(//)。
·有段注释时仍可以正确指出词法错误位置(行,列)。
三、实验过程1、词法形式化描述使用正则文法进行描述,则可以得到如下的正规式:其中ID表示标识符,NUM表示整型常量,RES表示保留字,DEL表示界符,OPR表示运算符。
A→(ID | NUM | RES | DEL | OPR) *ID→letter(letter | didit)*NUM→digit digit*letter→a | …| z | A | …| Zdigit→0 | …| 9RES→program | begin | end | var | int | and | or | not | if | then | else | while | doDEL→( | ) | . | ; | ,OPR→+ | * | := | > | < | = | >= | <= | <>如果关键字、标识符和常数之间没有确定的算符或界符作间隔,则至少用一个空格作间隔。
空格由空白、制表符和换行符组成。
2、单词种别定义;3、状态转换图;语言A的词法分析的状态转换图如下所示:空格符,制表符或回车符字母或数字4、运行环境介绍;本次实验采用win-tc进行代码的编写和编译及运行程序的运行环境为windows5、关键算法的流程图及文字解释;程序中用到的函数列表:变量ch储存当前最新读进的字符的地址strToken存放当前字符串voidmain() //主函数struct binary *lexicalAnalyze(); //词法分析的主函数,返回一个二元组的指针void GetBC(); //检查ch指向的字符是否为空格、制表或回车符,如果是则调用GetChar()直至不是上述字符void GetChar(); //ch前移一个地址单元int ConCat(); //将ch指向的字符连接到strToken之后int isLetter(); //判断ch指向的字符是否字母int isDigit(); //判断ch指向的字符是否数字int insertId(); //向标识符表中插入当前strToken的字符串int insertConst(); //将strToken的常数插入常数表中int Reserved(); //检测当前strToken中的字符串是否保留字,若是,则返回编码,否则返回0int isId(); //检测当前strToken中的字符串是否在标识符表中已存在,若是,则返回其编号,否则返回0int isConst(); //检测当前strToken中的字符串是否在常数表中已存在,若是,则返回其编号,否则返回0void errProc(int errType); //出错处理过程,errType是错误类型,将错误信息加入错误表中main()函数的流程图如下:lexicalAnalyze()函数的流程图如下所示:Reserved()、isId()和isConst()函数均采用了对链表的遍历算法,errProc()函数通过识别不同的错误编号,向错误链表中添加相应的错误信息。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{
while((ch>='0')&&(ch<='9'))
{
sum=sum*10+ch-'0'; //ch中数字本身是当做字符存放的
ch=prog[p++];
}
if(ch=='.')
{
isDecimal=1;
ch=prog[p++];
while((ch>='0')&&(ch<='9'))
if(strcmp(token,rwtab[n])==0)
{
syn=n+1;
break;
}
}
elseif((ch>='0')&&(ch<='9'))
{
IsNum:
if(isSignal==1)
{
//token[m++]='-';
}
while((ch>='0')&&(ch<='9'))
{
sum=sum*10+ch-'0'; //ch中数字本身是当做字符存放的
sum为整型常数。
例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:
(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……
四、
基本设计思路
基本字作为一类特殊的标识符来处理:识别出标识符,差基本字表,给出相应种别码。基本字表置初值:char *rwtab[6]={"begin","if","then","while","do","end"};(字符指针的数组)
>
23
>=
24
=
25
;
26
(
27
)
28
#
0
二、
设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。
三、
词法分析程序需具备词法分析的功能:
输入:所给文法的源程序字符串。(字符串以“#”号结束)
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;
token为存放的单词自身字符串;
ch=prog[p++];
}
sum=sum+decimal;
}
if(ch=='e'||ch=='E')
{
isExp=1;
ch=prog[p++];
if(ch=='-')
{
isNegative=1;
ch=prog[p++];
}
while((ch>='0')&&(ch<='9'))
{
//指数
index=index*10+ch-'0';
参考文献
[1] 张素琴,吕映芝等.编译原理[M].第2版.北京:清华大学出版社,2005.2
[2] 王雷,刘志成等.编译原理课程设计[M].北京:电子工业出版社,2002
[3] 何炎祥等.编译程序构造[M].武汉:武汉大学出版社,1988
[4] Holub piler Design in C[M].Prentice-Hall,1990
if(ch=='-')
{
isNegative=1;
ch=prog[p++];
}
while((ch>='0')&&(ch<='9'))
{
//指数
index=index*10+ch-'0';
ch=prog[p++];
}
if(isNegative)
sum=sum*pow(0.1,index);
else
sum=sum*pow(10,index);
{
//pow(x,y)计算x的y次幂
temp=(ch-'0')*pow(0.1,++count);
decimal=decimal+temp;
//AddToDec();
ch=prog[p++];
}
sum=sum+decimal;
}
if(ch=='e'||ch=='E')
{
isExp=1;
ch=prog[p++];
源程序代码
#include<stdio.h>
#include<string.h>
#include<math.h>
char prog[80]; //存放所有输入字符
char token[8]; //存放词组
char ch; //单个字符
int syn,p,m,n; //syn:种别编码
double sum;
}
p--;
syn=11;
}
输入与输出
词法分析程序需具备词法分析的功能:
输入:所给文法的源程序字符串。(字符串以“#”号结束)
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;
token为存放的单词自Βιβλιοθήκη 字符串;sum为整型常数。
程序运行结果
五、
用C语言实现。
六、
浮点数处理部分:
isDecimal=0;
break;
}
case -1:
printf("input error\n");
break;
default:
printf("(%2d,%8s)\n",syn,token);
}
}while(syn!=0);
3.浮点数的识别,先识别数字,再识别.,再识别数字,再识别E或e,再识别-,再识别数字。
int count;
int isSignal; //是否带正负号(0不带,1负号,2正号)
int isDecimal; //是否是小数
double decimal; //小数
int isExp; //是否是指数
int index; //指数幂
int isNegative; //是否带负号
double temp;
do{
ch=getchar();
prog[p++]=ch;
}while(ch!='#'); //输入以#号键结束
p=0;
do{
scanner(); //扫描,单词
switch(syn)
{
case 11:
if(isDecimal==0)
{
//加了1个强制类型转换
printf("(%2d,%8d)\n",syn,(int)sum);
do{
ch=getchar();
prog[p++]=ch;
}while(ch!='#'); //输入以#号键结束
2.输出到控制台:do…while循环中,扫描出单词后(扫描程序还会判断种别码syn)输出。
do{
scanner(); //扫描,单词
switch(syn)
{
case 11:
if(isDecimal==0)
{
printf("(%2d,%8d)\n",syn,(int)sum);
break;
}
else if(isExp==1)
{
printf("(%2d,%10.5e)\n",syn,sum);
isExp=0;
isDecimal=0;
break;
}
else if(isDecimal==1)
{
printf("(%2d,%8.4f)\n",syn,sum);
识别无符号整数是将数字串转换为无符号整数。我们在getchar()的时候是把数字当做字符从外部输出读取的。将数字串345#转换为整数:
(3*10+4)*10+5=345送到sum中
程序主要由2个函数组成,主函数main()和扫描子函数scanner()。扫描程序每次读取1个独立意义的单词符号,并判断单词类型。主程序做相应处理后做控制台输出。
break;
}
else if(isExp==1)
{
printf("(%2d,%10.5e)\n",syn,sum);
isExp=0;
isDecimal=0;
break;
}
else if(isDecimal==1)
{
printf("(%2d,%8.4f)\n",syn,sum);
isDecimal=0;
ch=prog[p++];
}
if(ch=='.')
{
isDecimal=1;
ch=prog[p++];