词法分析.docx

上传人:b****6 文档编号:3261409 上传时间:2022-11-21 格式:DOCX 页数:26 大小:21.58KB
下载 相关 举报
词法分析.docx_第1页
第1页 / 共26页
词法分析.docx_第2页
第2页 / 共26页
词法分析.docx_第3页
第3页 / 共26页
词法分析.docx_第4页
第4页 / 共26页
词法分析.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

词法分析.docx

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

词法分析.docx

词法分析

#include

#include

#include

#include

#include

usingnamespacestd;

ifstreamfp("source.txt",ios:

:

in);

charcbuffer;

char*key[13]={"if","else","for","while","do","return","break","continue","int","void"

"main","const","printf"};//关键字

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);

}

default:

cout<<"错误!

";

}

}

 

charalphaprocess(charbuffer)//字符处理过程

{

intatype;

inti=-1;

charalphatp[20];

while((isalpha(buffer))||(isdigit(buffer)))

//这两个函数分别是判字符和判数字函数位于ctype.h中

{

alphatp[++i]=buffer;

fp.get(buffer);

}

alphatp[i+1]='\0';//在末尾添加字符串结束标志

if(atype=search(alphatp,1))

cout<<"linenum:

"<

else

{

atype=search(alphatp,6);//标识符

cout<<"linenum:

"<

}

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<<"linenum:

"<

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<<"linenum:

"<

fp.get(buffer);

gotoout;

}

else//单字符逻辑运算符

{

othertp[1]='\0';

cout<<"linenum:

"<

gotoout;

}

}

if(otype=search(othertp,4))//关系运算符

{

fp.get(buffer);

othertp[1]=buffer;

othertp[2]='\0';

if(otypetp=search(othertp,4))//判断该关系运算符是否是

//由连续的两个字符组成的

{

cout<<"linenum:

"<

fp.get(buffer);

gotoout;

}

else//单字符逻辑运算符

{

othertp[1]='\0';

cout<<"linenum:

"<

gotoout;

}

}

if(buffer=='!

')//"=="的判断

{

fp.get(buffer);

if(buffer=='=')

//cout<<"!

=(2,2)\n";

fp.get(buffer);

gotoout;

}

else

{

if(otype=search(othertp,2))//分界符

{

cout<<"linenum:

"<

fp.get(buffer);

gotoout;

}

}

if((buffer!

='\n')&&(buffer!

=''))

cout<<"错误!

字符非法"<<"\t\t\t"<

fp.get(buffer);

out:

return(buffer);

}

voidmain()

{

inti;

for(i=0;i<=50;i++)

{

lableconst[i]="";//用于保存标识符

}

if(!

fp)

cout<<"文件打开错误!

"<

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(cbuffer);

}

}

cout<<"标识符个数是:

"<

i=0;

while(i

{

cout<

}

cout<

cout<<"完成\n";

getchar();

}

23

 

其他回答共1条

(一)Block子程序分析

procedureenter(k:

object1);//填写符号表

begin{enterobjectintotable}

tx:

=tx+1;//下标加1,tx的初始值为零,零下标不地址不填写标志符,用于查找失败使用

withtable[tx]do//填入内容,保存标志符名和类型

beginname:

=id;kind:

=k;

casekof//根据类型判断是否正确

constant:

beginifnum>amaxthen//如果是常量,判断是否大于最大值,若是则报30号错

beginerror(30);num:

=0end;

val:

=num//否则保存数值

end;

varible:

beginlevel:

=lev;adr:

=dx;dx:

=dx+1;//如果是变量,填写变量内部表示,LEVEl是变量的层次,adr为地址

end;

proc:

level:

=lev//如果是过程,保存过程的层次

end

end

end{enter};

 

//查找符号表的位置

functionposition(id:

alfa):

integer;

vari:

integer;

begin{findindentifieridintable}//从后向前查找

table[0].name:

=id;i:

=tx;//找到保存类型

whiletable[i].name<>iddoi:

=i-1;

position:

=i//返回标志符在符号表中的位置

end{position};

procedureblock(lev,tx:

integer;fsys:

symset);

vardx:

integer;{dataallocationindex}//数据分配索引

tx0:

integer;{initialtableindex}//初始符号表索引

cx0:

integer;{initialcodeindex}//初始代码索引

procedureenter(k:

object1);//填写符号表,下次分析

begin{enterobjectintotable}

tx:

=tx+1;

withtable[tx]do

beginname:

=id;kind:

=k;

casekof

constant:

beginifnum>amaxthen

beginerror(30);num:

=0end;

val:

=num

end;

varible:

beginlevel:

=lev;adr:

=dx;dx:

=dx+1;

end;

proc:

level:

=lev

end

end

end{enter};

functionposition(id:

alfa):

integer;//查找符号表,下次分析

vari:

integer;

begin{findindentifieridintable}

table[0].name:

=id;i:

=tx;

whiletable[i].name<>iddoi:

=i-1;

position:

=i

end{position};

procedureconstdeclaration;//常量声明

beginifsym=identthen//如果是标志符,读入一个TOKEN

begingetsym;

ifsymin[eql,becomes]then//读入的是等号或符值号继续判断

beginifsym=becomesthenerror

(1);//如果是“=”报1号错

getsym;//读入下一个TOKEN

ifsym=numberthen//读入的是数字,填写符号表

beginenter(constant);getsym

end

elseerror

(2)//如果不是数字,报2号错

endelseerror(3)//不是等号或符值号,报3号错

endelseerror(4)//如果不是标志符,报4号错

end{constdeclaration};

procedurevardeclaration;//变量声明

beginifsym=identthen//读入的是标志符,填写符号表

beginenter(varible);getsym

endelseerror(4)//不是标志符,报4号错

end{vardeclaration};

procedurelistcode;

vari:

integer;

begin{listcodegeneratedforthisblock}

fori:

=cx0tocx-1do

withcode[i]do

writeln(i:

5,mnemonic[f]:

5,1:

3,a:

5)

end{listcode};

procedurestatement(fsys:

symset);

vari,cx1,cx2:

integer;

procedureexpression(fsys:

symset);//表达式分析

varaddop:

symbol;

procedureterm(fsys:

symset);//项分析

varmulop:

symbol;

procedurefactor(fsys:

symset);//因子分析

vari:

integer;

begintest(facbegsys,fsys,24);//读入的是“(”,标志符或数字

whilesyminfacbegsysdo

begin

ifsym=identthen//是标志符,查表

begini:

=position(id);

ifi=0thenerror(11)else//未找到,报11号错

withtable[i]do//找到,读入标志符类型

casekindof

constant:

gen(lit,0,val);//写常量命令

varible:

gen(lod,lev-level,adr);//写变量命令

proc:

error(21)//过程名,报21号错

end;

getsym//读入下一个TOKEN

endelse

ifsym=numberthen//读入的是数字

beginifnum>amaxthen//如果数字大于最大数,报30号错误

beginerror(30);num:

=0

end;

gen(lit,0,num);getsym//调用数字命令,读入下一个TOKEN

endelse

ifsym=lparenthen//读入的是“(”

begingetsym;expression([rparen]+fsys);//调用表达式分析函数

ifsym=rparenthengetsymelseerror(22)//如果“(”后无“)”,报22号错

end;

test(fsys,[lparen],23)

end

end{factor};//因子分析结束

//项分析

begin{term}factor(fsys+[times,slash]);//调用因子分析程序

whilesymin[times,slash]do//取得是乘、除号循环

beginmulop:

=sym;getsym;factor(fsys+[times,slash]);//记录符号,调用因子分析

ifmulop=timesthengen(opr,0,4)elsegen(opr,0,5)//写乘除指令

end

end{term};

begin{expression}

ifsymin[plus,minus]then//如果是加减号

beginaddop:

=sym;getsym;term(fsys+[plus,minus]);//记录符号,调用项分析程序

ifaddop=minusthengen(opr,0,1)//写加减指令

endelseterm(fsys+[plus,minus]);

whilesymin[plus,minus]do//如果是加减号循环

beginaddop:

=sym;getsym;term(fsys+[plus,minus]);

ifaddop=plusthengen(opr,0,2)elsegen(opr,0,3)

end

end{expression};

//条件过程

procedurecondition(fsys:

symset);

varrelop:

symbol;

begin

ifsym=oddsymthen//如果是判奇符

begingetsym;expression(fsys);gen(opr,0,6)//取下一个TOKEN,调用expression,填指令

endelse

beginexpression([eql,neq,lss,gtr,leq,geq]+fsys);

ifnot(symin[eql,neq,lss,leq,gtr,geq])then//如果不是取到逻辑判断符号,出错.20

error(20)else

beginrelop:

=sym;getsym;expression(fsys);

caserelopof

eql:

gen(opr,0,8);//=,相等

neq:

gen(opr,0,9);//#,不相等

lss:

gen(opr,0,10);//<,小于

geq:

gen(opr,0,11);//],大于等于

gtr:

gen(opr,0,12);//>,大于

leq:

gen(opr,0,13);//[,小于等于

end

end

end

end{condition};

begin{statement}

ifsym=identthen//如果是标识符

begini:

=position(id);//查找符号表

ifi=0thenerror(11)else//未找到,标识符未定义,报11号错

iftable[i].kind<>variblethen//如果标识符不是变量,报12号错

begin{assignmenttonon-varible}error(12);i:

=0

end;

getsym;ifsym=becomesthengetsymelseerror(13);//如果是变量读入下一个TOKEN,不是赋值号,报13好错;是则读入一个TOKEN

expression(fsys);//调用表达是过程

ifi<>0then//写指令

withtable[i]dogen(sto,lev-level,adr)

endelse

ifsym=callsymthen//如果是过程调用保留字,读入下一个TOKEN

begingetsym;

ifsym<>identthenerror(14)else//不是标识符报14号错

begini:

=position(id);

ifi=0thenerror(11)else//是标识符,未定义,报13号错

withtable[i]do/

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

当前位置:首页 > 小学教育 > 语文

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

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