实验一 编译原理词法分析_第1页
实验一 编译原理词法分析_第2页
实验一 编译原理词法分析_第3页
实验一 编译原理词法分析_第4页
实验一 编译原理词法分析_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

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

文档简介

实验一词法分析本节进行词法分析程序的编程与调试。1.实验要求(1)从源程序文件中读取有效字符和并将其转换成二元组内部表示形式输出。(2)掌握词法分析的实现方法。(3)实验时间4学时。(4)实验完成后,要上交实验报告(包括源程序清单)。2.实验内容2.1主程序设计考虑:主程序的说明部分为各种表格和变量安排空间(关键字和特殊符号表)。id和ci数组分别存放标识符和常数;还有一些为造表填表设置的变量。主程序的工作部分建议设计成便于调试的循环结构。每个循环处理一个单词;调用词法分析过程;输出每个单词的内部码(种别编码,属性值)。建议从文件中读取要分析的符号串。2.2词法分析过程考虑该过程根据输入单词的第一个有效字符(有时还需读第二个字符),判断单词种别,产生种别编码。对于标识符和常数,需分别与标识符表和常数表中已登记的元素相比较,如表中已有该元素,则记录其在表中的位置,如未出现过,将标识符按顺序填入数组id中,将常数存入数组中ci中,并记录其在表中的位置。注:所有识别出的单词都用二元组表示。第一个表示单词的种别编码。例如:关键字的t=1;标识符的t=2;常数t=3;运算符t=4;界符t=5。第二个为该单词在各自表中的指针或内部码值(常数表和标识符表是在编译过程中建立起来的。其i值是根据它们在源程序中出现的顺序确定的)。关键字和特殊符号如下(表中数字只是标记,不代表种别编码,种别编码自己定义):编号12345678910名字intcharfloatvoidconstifelsedowhilescanf编号11121314151617181920名字printfreturnmainread+–*/%=编号21222324252627282930名字==><!=>=<=&&||!<>编号31323334353637383940名字(){};,“‘++--将词法分析程序设计成独立一遍扫描源程序的结构。其主流程图如下:图1词法分析程序流程图3.实验代码:#include"stdafx.h"#include<iostream>#include<ctype.h>#include<fstream>#include<string.h>#include<malloc.h>usingnamespacestd;ifstreamfp("source.txt",ios::in);charcbuffer;char*key[14]={"int","char","float","void","const","if","else","do","while","scanf","print","return","main","read"};//关键字char*border[7]={",",";","{","}","(",")","//"};//分界符char*arithmetic[6]={"+","-","*","/","++","--"};//运算符char*relation[7]={"<","<=","=",">",">=","==","!="};//关系运算符char*lableconst[80];//标识符intconstnum=40;intlableconstnum=0;intlinenum=1;//统计常数和标识符数量intsearch(charsearchchar[],intwordtype){ inti=0,t=0; switch(wordtype) { case1: {for(i=0;i<=12;i++)//关键字 { if(strcmp(key[i],searchchar)==0) return(i+1); } return(0);} case2: { for(i=0;i<=6;i++)//分界符 { if(strcmp(border[i],searchchar)==0) return(i+1); } return(0); } case3: { for(i=0;i<=5;i++)//运算符 { if(strcmp(arithmetic[i],searchchar)==0) return(i+1); } return(0); } case4: { for(i=0;i<=6;i++)//关系运算符 { if(strcmp(relation[i],searchchar)==0) return(i+1); } return(0); } case5: { for(t=40;t<=constnum;t++)//常数 { if(strcmp(searchchar,lableconst[t])==0)//判断该常数是否已出现过 return(t+1); } lableconst[t-1]=(char*)malloc(sizeof(searchchar));//为新的元素分配内存空间 strcpy(lableconst[t-1],searchchar);//为数组赋值lableconst指针数组名 constnum++;//常数个数自加 return(t); } case6: { for(i=0;i<=lableconstnum;i++) { if(strcmp(searchchar,lableconst[i])==0)//判断标识符是否已出现过 return(i+1); } lableconst[i-1]=(char*)malloc(sizeof(searchchar)); strcpy(lableconst[i-1],searchchar); lableconstnum++;//标识符个数自加 return(i); } } }charalphaprocess(charbuffer)//字符处理过程{ intatype; inti=-1; charalphatp[20]; while((isalpha(buffer))||(isdigit(buffer))) { alphatp[++i]=buffer; fp.get(buffer); } alphatp[i+1]='\0';//在末尾添加字符串结束标志 if(atype=search(alphatp,1)) cout<<alphatp<<"\t"<<"种间编码:t=1"<<",内部编码:"<<atype<<"\t"<<"关键字"<<endl; else { atype=search(alphatp,6);//标识符 cout<<alphatp<<"\t"<<"种间编码:t=2"<<",内部编码:"<<atype<<"\t"<<"标识符"<<endl; } return(buffer);}chardigitprocess(charbuffer)//数字处理过程{ inti=-1; chardigittp[20]; intdtype; while((isdigit(buffer))) { digittp[++i]=buffer; fp.get(buffer); } digittp[i+1]='\0'; dtype=search(digittp,5); cout<<digittp<<"\t"<<"种间编码:t=3"<<",内部编码:"<<dtype<<"\t"<<"数字"<<endl; return(buffer);}charotherprocess(charbuffer)//分界符、运算符、逻辑运算符、等{ inti=-1; charothertp[20]; intotype,otypetp; othertp[0]=buffer; othertp[1]='\0'; if(otype=search(othertp,3)) { fp.get(buffer); othertp[1]=buffer; othertp[2]='\0'; if(otypetp=search(othertp,3))//判断该运算符是否是 //由连续的两个字符组成的 { cout<<othertp<<"\t"<<"种间编码:t=4"<<",内部编码:"<<otypetp<<"\t"<<"运算符"<<endl; fp.get(buffer); gotoout; } else//单字符逻辑运算符 { othertp[1]='\0'; cout<<othertp<<"\t"<<"种间编码:t=4"<<",内部编码:"<<otypetp<<"\t"<<"单字符逻辑运算符"<<endl; gotoout; } } if(otype=search(othertp,4))//关系运算符 { fp.get(buffer); othertp[1]=buffer; othertp[2]='\0'; if(otypetp=search(othertp,4))//判断该关系运算符是否是 //由连续的两个字符组成的 { cout<<othertp<<"\t"<<"种间编码:t=4"<<",内部编码:"<<otypetp<<"\t"<<"关系运算符"<<endl; fp.get(buffer); gotoout; } else//单字符逻辑运算符 { othertp[1]='\0'; cout<<othertp<<"\t"<<"种间编码:t=4"<<",内部编码:"<<otypetp<<"\t"<<"运算符"<<endl; gotoout; } } if(buffer=='!')//"=="的判断 { fp.get(buffer); if(buffer=='=') //cout<<"!=(2,2)\n"; fp.get(buffer); gotoout; } else { if(otype=search(othertp,2))//分界符 { cout<<othertp<<"\t"<<"种间编码:t=5"<<",内部编码:"<<otype<<"\t"<<"分界符"<<endl; fp.get(buffer); gotoout; } } if((buffer!='\n')&&(buffer!='')) cout<<"错误!,字符非法"<<"\t\t\t"<<buffer<<endl; fp.get(buffer); out:return(buffer);}voidmain(){ inti; for(i=0;i<=40;i++) { lableconst[i]=""; } if(!fp) cout<<"文件打开错误!!"<<endl; else { fp.get(cbuffer); while(!fp.eof()) { if(cbuffer=='\n') { linenum++; fp.get(cbuffer); } elseif(isalpha(cbuffer)) { cbuffer=alphaprocess(cbuffer); } elseif(isdigit(cbuffer)) { cbuffer=digitprocess(cbuffer); } else cbuffer=otherprocess(c

温馨提示

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

最新文档

评论

0/150

提交评论