编译原理词法分析器代码.docx

上传人:b****5 文档编号:7176332 上传时间:2023-01-21 格式:DOCX 页数:18 大小:18.54KB
下载 相关 举报
编译原理词法分析器代码.docx_第1页
第1页 / 共18页
编译原理词法分析器代码.docx_第2页
第2页 / 共18页
编译原理词法分析器代码.docx_第3页
第3页 / 共18页
编译原理词法分析器代码.docx_第4页
第4页 / 共18页
编译原理词法分析器代码.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

编译原理词法分析器代码.docx

《编译原理词法分析器代码.docx》由会员分享,可在线阅读,更多相关《编译原理词法分析器代码.docx(18页珍藏版)》请在冰豆网上搜索。

编译原理词法分析器代码.docx

编译原理词法分析器代码

#include

#include

#include

#include

#include

#defineKEYWORD_LEN32//保留字个数

#defineSTR_MAX_LEN300//标识符最大长度

#definePRO_MAX_LEN20480//源程序最大长度

#defineSTB_MAX_LEN1000//符号表最大容量

#defineCTB_MAX_LEN1000//常数表最大容量

#defineERROR0//错误

#defineID(KEYWORD_LEN+1)//标识符

#defineCONST(KEYWORD_LEN+2)//常量

#defineOPERAT(KEYWORD_LEN+3)//运算符

#defineDIVIDE(KEYWORD_LEN+4)//界符

interrorLine=0;charproBuffer[PRO_MAX_LEN]="";//存储程序代码的全局缓冲区

charch;//读出来的当前字符

charwordget[STR_MAX_LEN];//标识符或常量

intpoint=0;//源程序当前位置指针

charsignTab[STB_MAX_LEN][STR_MAX_LEN];//符号表

intpointSTB=0;//符号表指针

charconstTab[CTB_MAX_LEN][STR_MAX_LEN];//常量表

intpointCTB=0;//常数表指针

charkwTab[KEYWORD_LEN][10]={//保留字表C语言一共有32个保留字[关键字]

"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","void","volatile","while"};

charerrorTab[][50]={//错误代码表

/*0*/"未知错误",/*1*/"非法的字符",/*2*/"不正确的字符常量表达",

/*3*/"不正确的字符串表达",/*4*/"不正确的数字表达",/*5*/"注释丢失'*/'"};

typedefstructsignDuality

{

intkind;

intvalue;

}*pDualistic,Dualistic;

voidpretreatment();//预处理

voidProcError(intid);//错误

boolGetChar();//获得一个字符不包括结束标记

boolGetBC();//获得一个非空白字符

voidConcat(char*str);//将ch连接到str后

intReserve(char*str);//对str字符串查找保留字表若是一个保留字-返回其编码否则返回0

voidRetract();//将搜索指示器回调一个字符位置

intInsertId(char*str);//将str串以标识符插入符号表,并返回符号表指针

intInsertConst(char*str);//将str串以常数插入符号表,并返回常数表指针

boolwordAnalyse(pDualisticpDu);//词法分析true正常

//预处理将缓冲区内的源代码去掉注释和无效空格

voidpretreatment()

{

intlines=0;

chartmp[PRO_MAX_LEN];//先将处理结果保存到临时空间

inttmpp=0;//这个临时空间的末尾指针

boolflg;

chartmpc;//去掉注释先//注释有两种一种是//另一种是/**/

point=0;

do

{

flg=GetChar();

if(ch=='/')

{

flg=GetChar();

switch(ch)

{

case'/':

do

{

flg=GetChar();

}while(!

(ch=='\n'||flg==false));//注释一直到行尾或文件结束

if(ch=='\n')

Retract();//归还换行

break;

case'*':

do

{

flg=GetChar();

tmpc=ch;

//为了保证出错处理程序能正确定位出错位置保留注释中的换行

if(tmpc=='\n')

tmp[tmpp++]=tmpc;

flg=GetChar();

Retract();//归还一个字符

}while(flg&&!

(flg&&tmpc=='*'&&ch=='/'));

flg=GetChar();

if(!

flg)

{

ProcError(5);

}

break;

default:

//不是任何一种注释

Retract();

Retract();

GetChar();

tmp[tmpp++]=ch;

flg=GetChar();

tmp[tmpp++]=ch;

}

}

else

{

tmp[tmpp++]=ch;

}

}while(flg);

tmp[tmpp]='\0';

strcpy(proBuffer,tmp);

}

//错误

voidProcError(intid)

{

printf("\nError:

第%d行,%s\n",errorLine,errorTab[id]);

}

//获得一个字符

boolGetChar()

{

if(point

='\0')

{

//如果当前下标合法且当前字符为结束标记则取字符增游标

ch=proBuffer[point++];

if(ch=='\n')

errorLine++;

returntrue;

}

ch='\0';

returnfalse;

}

//获得一个非空白字符

boolGetBC()

{

do

{

if(!

GetChar())//获取字符失败

{

ch='\0';

returnfalse;

}

}while(isspace(ch));//直到获得一个非空白字符

returntrue;

}

//将ch连接到str后

voidConcat(char*str)

{

inti;

for(i=0;str[i];++i)

;

str[i]=ch;

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

}

//对str字符串查找保留字表若是一个保留字-返回其编码否则返回0

intReserve(char*str)

{

inti;

for(i=0;i

{

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

returni+1;//注意,这里加一原因是0值被错误标记占用

}

return0;

}

//将搜索指示器回调一个字符位置

voidRetract()///char*ch

{

if(proBuffer[point]=='\n'&&errorLine>0)

errorLine--;

point--;

}

//将str串以标识符插入符号表,并返回符号表指针

intInsertId(char*str)

{

inti;

for(i=0;i

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

returni;

strcpy(signTab[pointSTB++],str);

return(pointSTB-1);

}

//将str串以常数插入常量表,并返回常数表指针

intInsertConst(char*str)

{

inti;

for(i=0;i

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

returni;

strcpy(constTab[pointCTB++],str);

return(pointCTB-1);

}

//词法分析false--分析结束

boolwordAnalyse(pDualisticpDu)

{

intcode,value;

charjudge;//这里有个技巧借用此变量巧妙的运用SWITCH结构

inti=0;//辅助

GetBC();

judge=ch;

if(isalpha(ch)||ch=='_')

judge='L';

if(isdigit(ch))

judge='D';

switch(judge)

{

case'L':

while(isalnum(ch)||ch=='_')

{//标识符

wordget[i++]=ch;

GetChar();

}

wordget[i]='\0';

Retract();//回退一个字符

code=Reserve(wordget);

if(code==0)

{

value=InsertId(wordget);

pDu->kind=ID;

pDu->value=value;

}

else

{

pDu->kind=code;

pDu->value=-1;

}

returntrue;

case'D':

while(isdigit(ch))

{

wordget[i++]=ch;

GetChar();

}

wordget[i]='\0';

Retract();

value=InsertConst(wordget);

pDu->kind=CONST;

pDu->value=value;

returntrue;

//()[].,!

!

=~sizeof<<<<=>>>>====&&&&=||||=?

:

++++=

//-->---=**=//=%%=>>=<<=^^=

case'"':

//字符串常量

do

{

wordget[i++]=ch;

GetChar();

}while(ch!

='"'&&ch!

='\0');

wordget[i++]=ch;

wordget[i]='\0';

if(ch=='\0')

{

printf("%s",wordget);

ProcError(3);

pDu->kind=ERROR;

pDu->value=0;

}

else

{

value=InsertConst(wordget);

pDu->kind=CONST;

pDu->value=value;

}

returntrue;//字符常量

case'\'':

wordget[i++]=ch;//'

GetChar();

wordget[i++]=ch;

if(ch=='\\')//'\n'

{

//如果是转义字符则要多接收一个字符

GetChar();//ch='

wordget[i++]=ch;

}

GetChar();

wordget[i++]=ch;

wordget[i]='\0';

if(ch!

='\'')

{//'\b'

printf("%s",wordget);

ProcError

(2);

pDu->kind=ERROR;

pDu->value=0;

}

else

{

value=InsertConst(wordget);

pDu->kind=CONST;

pDu->value=value;

}

returntrue;

case'(':

case')':

case'[':

case']':

case'.':

case',':

case'~':

case'?

':

case':

':

case';':

case'{':

case'}':

case'#':

wordget[i++]=ch;

wordget[i]='\0';

pDu->kind=DIVIDE;//界符

pDu->value=-1;

returntrue;

case'!

':

//!

=

wordget[i++]=ch;

GetChar();

if(ch=='=')

wordget[i++]=ch;

else

Retract();

wordget[i]='\0';

break;

case'<':

//<<<=

wordget[i++]=ch;

GetChar();

if(ch=='<'||ch=='=')

wordget[i++]=ch;

else

Retract();

wordget[i]='\0';

break;

case'>':

//>>>=

wordget[i++]=ch;

GetChar();

if(ch=='>'||ch=='=')

wordget[i++]=ch;

else

Retract();

wordget[i]='\0';

break;

case'=':

//==

wordget[i++]=ch;

GetChar();

if(ch=='=')

wordget[i++]=ch;

else

Retract();

wordget[i]='\0';

break;

case'&':

//&&&=

wordget[i++]=ch;

GetChar();

if(ch=='&'||ch=='=')

wordget[i++]=ch;

else

Retract();

wordget[i]='\0';

break;case'|':

//|||=

wordget[i++]=ch;

GetChar();

if(ch=='|'||ch=='=')

wordget[i++]=ch;

else

Retract();

wordget[i]='\0';

break;

case'+':

//+++=

wordget[i++]=ch;

GetChar();

if(ch=='+'||ch=='=')

wordget[i++]=ch;

elseRetract();

wordget[i]='\0';

break;

case'-':

//---=->

wordget[i++]=ch;

GetChar();

if(ch=='-'||ch=='='||ch=='>')

wordget[i++]=ch;

else

Retract();

wordget[i]='\0';

break;

case'*':

//***=

wordget[i++]=ch;

GetChar();

if(ch=='*'||ch=='=')

wordget[i++]=ch;

else

Retract();

wordget[i]='\0';

break;

case'/':

///=

wordget[i++]=ch;

GetChar();

if(ch=='=')

wordget[i++]=ch;

else

Retract();

wordget[i]='\0';

break;

case'%':

//%=

wordget[i++]=ch;

GetChar();

if(ch=='=')

wordget[i++]=ch;

else

Retract();

wordget[i]='\0';

break;

case'^':

//^=

wordget[i++]=ch;

GetChar();

if(ch=='=')

wordget[i++]=ch;

else

Retract();

wordget[i]='\0';

break;

case'\0':

returnfalse;

default:

ProcError

(1);

returnfalse;

}

pDu->kind=OPERAT;

returntrue;

}

//主函数

intmain()

{

Dualistictmp;

pDualisticptmp=&tmp;

FILE*fin,*fout;

inti;

charc;

char[20];

printf("源代码读入\n");

//scanf("%s",);

//将源程序读入缓冲区

if((fin=fopen("Test.txt","r"))==NULL)

{

printf("Cannotopeninfile\n");

return0;

}

i=0;

//c=fgetc(fin);

while((c=fgetc(fin))!

=EOF)

{

if(i>=PRO_MAX_LEN-1)

{

printf("\n程序代码太长,无法处理\a");

return0;

}

proBuffer[i++]=c;

}

fclose(fin);//关闭文件

proBuffer[i++]='\0';

printf("\n***************************\n源代码读入成功,源代码如下:

\n%s",proBuffer);

printf("\n按任意键继续\n");

getch();//预处理

printf("\n预处理\n");

pretreatment();

printf("\n***************************\n预处理成功,去掉注释后的源代码为:

\n%s*",proBuffer);

printf("\n按任意键继续\n");

getch();

printf("\n词法分析\n");

point=0;

//词法分析

if((fout=fopen("Result.txt","wb"))==NULL)

{

printf("建立文件Result.txt失败。

\n");

return0;

}

i=0;

errorLine=0;//错误行归零

do

{

if(i++>PRO_MAX_LEN)//防止遇到BUG导致程序死循环无限写文件

break;

if(!

wordAnalyse(ptmp))

{

break;

}

if(ptmp->value==-1)

fprintf(fout,"<%3d,->\t",ptmp->kind);

else

fprintf(fout,"<%3d,%3d>\t",ptmp->kind,ptmp->value);

switch(ptmp->kind)

{

caseERROR:

fprintf(fout,"(出错:

%s)",wordget);

break;

caseID:

fprintf(fout,"(标识符:

%s)",wordget);

break;

caseCONST:

fprintf(fout,"(常量:

%s)",wordget);

break;

caseOPERAT:

fprintf(fout,"(运算符:

%s)",wordget);

break;caseDIVIDE:

fprintf(fout,"(界符:

%s)",wordget);

break;

default:

;

}

if(ptmp->kind>=1&&ptmp->kind<=KEYWORD_LEN)

fprintf(fout,"(关键字:

%s)",kwTab[ptmp->kind-1]);

fprintf(fout,"\r\n");

}while

(1);

fclose(fout);

printf("写回常量表和标识符表\n");//常量表

if((fout=fopen("Const.txt","wb"))==NULL)

{

printf("建立文件Const.txt失败。

\n");

return0;

}

for(i=0;i

fprintf(fout,"

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

当前位置:首页 > 法律文书 > 判决书

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

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