天津理工大学编译原理实验一.docx

上传人:b****3 文档编号:3769752 上传时间:2022-11-25 格式:DOCX 页数:33 大小:56.36KB
下载 相关 举报
天津理工大学编译原理实验一.docx_第1页
第1页 / 共33页
天津理工大学编译原理实验一.docx_第2页
第2页 / 共33页
天津理工大学编译原理实验一.docx_第3页
第3页 / 共33页
天津理工大学编译原理实验一.docx_第4页
第4页 / 共33页
天津理工大学编译原理实验一.docx_第5页
第5页 / 共33页
点击查看更多>>
下载资源
资源描述

天津理工大学编译原理实验一.docx

《天津理工大学编译原理实验一.docx》由会员分享,可在线阅读,更多相关《天津理工大学编译原理实验一.docx(33页珍藏版)》请在冰豆网上搜索。

天津理工大学编译原理实验一.docx

天津理工大学编译原理实验一

实验报告

学院(系)名称:

计算机与通信工程学院

姓名

学号

专业

计算机科学与技术

班级

实验项目

实验一:

词法分析

课程名称

编译原理

课程代码

实验时间

2016/03/17

2016/03/22

实验地点

软件实验室7-219

批改意见

成绩

 

教师签字:

实验内容:

实现标准C语言词法分析器。

实验要求:

(1)单词种别编码要求

基本字、运算符、界符:

一符一种

标识符:

统一为一种;

常量:

按类型编码;

(2)词法分析工作过程中建立符号表、常量表。

并以文本文件形式输出。

(3)词法分析的最后结果以文本文件形式输出。

 

实验源代码和心得体会

#include

#include

#include

#definebufsize1024

//关键字

#defineINCLUDE256

#defineAUTO257

#defineBREAK258

#defineCASE259

#defineCHAR260

#defineCONST261

#defineCONTINUE262

#defineDEFAULT263

#defineDO264

#defineDOUBLE265

#defineELSE266

#defineENUM267

#defineEXTERN268

#defineFLOAT269

#defineFOR270

#defineGOTO271

#defineIF272

#defineINT273

#defineLONG274

#defineREGISTER275

#defineRETURN276

#defineSHORT277

#defineSIGNED278

#defineSIZEOF279

#defineSTATIC280

#defineSTRUCT281

#defineSWITCH282

#defineTYPEDEF283

#defineUNION284

#defineUNSIGNED285

#defineVOLATILE286

#defineWHILE287

//运算符

#definePLUS288//+

#defineMINUS289//-

#defineMUL290//*

#defineDIV291///

#defineREMAIN292//%

#defineGREATER293//>

#defineLESS294//<

#defineEQUAL295//=

#defineMISTAKE296//!

#defineAND297//&

#defineOR298//|

#definePP299//++

#defineMM300//--

#defineEE301//==

#defineGE302//>=

#defineLE303//<=

#defineMISE304//!

=

#defineAA305//&&

#defineOO306//||

#definePE307//+=

#defineMINUSE308//-=

#defineMULE309//*=

#defineDIVE310///=

#definePOW311//^

//界符

#defineSEMIC312//;

#defineCOMMA313//,

#defineMULANNO_L314///*

#defineMULANNO_R315//*/

#defineBRACE_L316//{

#defineBRACE_R317//}

#defineBRAKET_L318//(

#defineBRAKET_R319//)

#defineMIDBRA_L320//[

#defineMIDBRA_R321//]

#defineONE_ANNO322////

//标识符和常量符

#defineTAG400

#defineCONINT401

#defineCONFLOAT402

#defineCONCHAR403

#defineCONSTRING404

//转义字符和字符串

#defineCA500

#defineCB501

#defineCF502

#defineCN503

#defineCR504

#defineCT505

#defineCV506

#defineCBSL507

#defineCQUE508

#defineCDQM509

#defineCQM510

#defineZERO511

usingnamespacestd;

typedefstructVariate{//变量标识符

intid;

charname[50];

}Variate;

typedefstructConstant{//常量

intid;

charname[50];

}Constant;

typedefstructSign{

charname[100];

intsym;

charattr[100];

}Sign;

constchar*keywordTable[]={"include","auto","break","case","char","const","continue",

"default","do","double","else","enum","extern","float","for",

"goto","if","int","long","register","return","short","signed",

"sizeof","static","struct","switch","typedef","union","unsigned",

"volatile","while","","##"};//##作用是判断是否结束

constchar*operateTable[]={"+","-","*","/","%",">","<","=","!

","&","|","++","--",

"==",">=","<=","!

=","&&","||","+=","-=","*=","/=","^","##"};

constchar*borderTable[]={";",",","/*","*/","{","}","(",")","[","]","//","##"};

constcharchangeList[12]={'a','b','f','n','r','t','v','\\','?

','"','\'','0'};

FILE*in;

FILE*Out;

FILE*Error;

intline=1;//用于输出错误的行数或者其他情况。

默认值是从1开始,为第一行

charbuf[bufsize];//存储读取的一行的字符串

charfirchar;//头文件下第一个字符

charChar;

intstart=0;

intVariateNum=0;//记录变量的个数,减去1

intConstantNum=0;//记录常量的个数

intSignNum=0;//记录标记的个数

intnotation=1;//记录是否找到多行注释的另一半*/,默认值是1即为有另一半

intisNotation=0;//判断是否是在注释行内0不是,1单行注释2多行注释

boollast=false;

intlate=0;

Variatevar;

Constantcon;

Signsign;

VariateVarArr[bufsize];

ConstantConArr[bufsize];

SignSigArr[bufsize];

//获取读取的文件本行的第一个字符,直到找到一个非空格字符

chargetfirstc(FILE*in)

{

charch=fgetc(in);//fgetc()函数的作用是读取文件的当前行的一个字符,返回读取的字符

while(ch==''||ch=='\n'||ch=='\t')

{

if(ch=='\n')

{

line++;

fputc('\n',Out);//向输出的文本文件中打印换行

}

ch=fgetc(in);

}

returnch;

}

//处理读取的本行内容

voiddealhead(char*buf)

{

charch[10];

charcha;

charstr[bufsize];

inti=0;

intj=0;

inttemp=0;

while(i

{

if(buf[i]!

=''&&buf[i]!

='\0')

{

if(temp==0)

{

if(buf[i]=='i')

temp=1;

elseif(buf[i]=='d')

temp=2;

else

{

fprintf(Error,"Line:

%d\tformatiswrong!

Without'>'\n",line);

break;

}

}

if(temp==1)

{

ch[j]=buf[i];

j++;

if(buf[i]=='<')

{

ch[j]='\0';

break;

}

}

elseif(temp==2)

{

ch[j]=buf[i];

j++;

if(buf[i+1]=='')

{

ch[j]='\0';

i++;

break;

}

}

}

i++;

}

if(temp==1)

{

intindex=0;

fputc('#',Out);

while(buf[index]!

='\0')

{

if(buf[index]!

='')

fputc(buf[index],Out);

index++;

}

if(strcmp(ch,"include<")==0)

{

i++;//因为上面程序没进行++就直接break所以这里就需要加1到下一个角标

while((cha=buf[i])!

='>')

{

i++;

if(cha=='\n')

{

fprintf(Error,"Line:

%d\tincludeendwithout'>'\n",line);

break;

}

}

}

else

fprintf(Error,"Line:

%d\tincludeformatiswrong\n",line);

}

elseif(temp==2)

{

if(strcmp(ch,"define")!

=0)

{

i++;

while((cha=buf[i])=='')

{

if(cha=='\n')

{

//fprintf(Error,"Line:

%d\tincludeendwithout'>'\n",line);

break;

}

i++;

}

if(buf[i]!

='')

{

if(!

(isalpha(buf[i])))

fprintf(Error,"Line:

%d\tdefineformatiswrong\n",line);

//此处意思是define后必须有变量名称

}

}

else

{

//在上面的break之前已经进行过i++;所以这里可以直接用

while(!

isalpha(buf[i]))

{

if(buf[i]=='\0')

{

fprintf(Error,"Line:

%d\tdefinewithoutvatiateandname!

\n",line);

break;

}

i++;

}

intindex=0;

intspace=0;//计算在上一个字母之后第几次遇到空格

fputc('#',Out);

while(buf[index]!

='\0')

{

if(buf[index]!

='')

{

fputc(buf[index],Out);

space=0;

}

else

{

space++;

if(space==1&&index!

=0)

fputc('',Out);

}

index++;

}

}

}

}

//处理头文件

charhead(FILE*in)

{

charch;

if(late==0)

ch=getfirstc(in);

else

ch=firchar;//即为#

while(ch=='#')

{

fgets(buf,bufsize,in);//fgets()读取in文件当前一行的内容为bufsize-1个字符的内容

intlen=strlen(buf);

buf[len-1]='\0';

dealhead(buf);//这条语句执行完毕后且找到'>'就说明这行结束

line++;

ch=getfirstc(in);

if(ch=='#')

fputc('\n',Out);

}

returnch;

}

//判断关键字

intkeyword(char*str)

{

inti;

for(i=0;keywordTable[i]!

="##";i++)

if(strcmp(str,keywordTable[i])==0)

returni+256;//返回关键字对应的值

return-1;

}

//处理字母

voiddealAlpha()

{

charstr[50];

Variatevar;

Signsign;

inti;

intkey;//记录字符串str对应的值。

str[0]=firchar;

for(i=start;isalpha(buf[i])||isdigit(buf[i]);i++)

str[i-start+1]=buf[i];//将本行的第一个字符串赋值给str

str[i-start+1]='\0';

start=i;

firchar=buf[start];

key=keyword(str);

if(key==-1)

{//说明不是关键字,是标识符。

即为变量,函数名一类的

var.id=VariateNum;

strcpy(var.name,str);

VarArr[VariateNum]=var;

VariateNum++;

sign.sym=TAG;

sprintf(sign.attr,"%d",var.id);//暂时不知道什么用处

strcpy(sign.name,str);

SigArr[SignNum]=sign;

SignNum++;

}

else//说明是关键字

{

sign.sym=key;

strcpy(sign.name,str);

strcpy(sign.attr,"--");//sign.attr="--";是不正确的,attr的长度大,后面的不能忽略

SigArr[SignNum]=sign;

SignNum++;

}

}

//判断是否在常量表里

intInConTable(char*name)

{

inti;

for(i=0;i

if(strcmp(name,ConArr[i].name)==0)

returnConArr[i].id;

return-1;

}

//处理数字

voiddealDigit()

{

intsymbol;

intid;

charword[100];

Signsign;

Constantconstant;

inti;

word[0]=firchar;

for(i=start;isdigit(buf[i]);i++)

{

word[i-start+1]=buf[i];

}

if(buf[i]=='.')

{

i++;

if(!

isdigit(buf[i]))

{

start=i;

firchar=buf[start];

fprintf(Error,"Line:

%d\tunavailabefloat\n",line);

return;

}

word[i-start]='.';

for(;isdigit(buf[i]);i++)

word[i-start+1]=buf[i];

word[i-start+1]='\0';

start=i;

firchar=buf[start];

id=InConTable(word);

/**不在常量表里,新加项**/

if(id==-1)

{

constant.id=ConstantNum;

strcpy(constant.name,word);

ConArr[ConstantNum]=constant;

ConstantNum++;

id=constant.id;

}

sign.sym=CONFLOAT;

sprintf(sign.attr,"%d",id);//changeinttostring

strcpy(sign.name,word);

SigArr[SignNum]=sign;

SignNum++;

}

else

{

word[i-start+1]='\0';

start=i;

firchar=buf[start];

id=InConTable(word);

/**不在常量表里,新加项**/

if(id==-1)

{

constant.id=ConstantNum;

strcpy(constant.name,word);

ConArr[ConstantNum]=constant;

ConstantNum++;

id=constant.id;

}

sign.sym=CONINT;

sprintf(sign.attr,"%d",id);//changeinttostring

strcpy(sign.name,word);

SigArr[SignNum]=sign;

SignNum++;

}

}

//处理注释

voiddealNotation()

{

charstr[3];

str[0]='/';

str[2]='\0';

if(buf[start]=='/')//确定是单行注释。

{

isNotation=1;

Signsign;

str[1]='/';

inti;

for(i=0;borderTable[i]!

="##";i++)

if(strcmp(str,borderTable[i])==0)

{

sign.sym=i+288;

break;

}

strcpy(sign.name,str);

strcpy(sign.attr,"--");

SigArr[SignNum]=sign;

SignNum++;

}

else//多行注释

{

isNotation=2;

str[1]='*';

Signsign1,sign2;

inti;

intst;

for(i=0;borderTable[i]!

="##";i++)

if(strcmp(str,borderTable[i])==0)

{

sign1.sym=i+312;

break;

}

strcpy(sign1.name,str);

strcpy(sign1.attr,"--");

SigArr[SignNum]=sign1;

SignNum++;

fputc('\n',Out);

if(Char!

='/')

fputc(Char,Out);

intlen;

len=strlen(buf);

charc=Char;

for(start=0;start

{

if(c=='/'&&buf[start]=='*')

{

fputc('/',Out);

fputc('*',Out);

break;

}

else

{

fputc(buf[start],Out);

c=buf[start];

}

}

start++;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 笔试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1