词法分析Word文档格式.docx
《词法分析Word文档格式.docx》由会员分享,可在线阅读,更多相关《词法分析Word文档格式.docx(26页珍藏版)》请在冰豆网上搜索。
![词法分析Word文档格式.docx](https://file1.bdocx.com/fileroot1/2022-11/20/b9053592-7074-4276-9500-009910065554/b9053592-7074-4276-9500-0099100655541.gif)
-"
*"
/"
++"
--"
//运算符
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;
=6;
i++)//分界符
if(strcmp(border[i],searchchar)==0)
}
case3:
=5;
i++)//运算符
if(strcmp(arithmetic[i],searchchar)==0)
case4:
i++)//关系运算符
if(strcmp(relation[i],searchchar)==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:
=lableconstnum;
i++)
if(strcmp(searchchar,lableconst[i])==0)//判断标识符是否已出现过
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:
"
linenum<
String="
alphatp<
\t\t\t"
关键字"
endl;
else
atype=search(alphatp,6);
标识符"
return(buffer);
chardigitprocess(charbuffer)//数字处理过程
chardigittp[20];
intdtype;
while((isdigit(buffer)))
digittp[++i]=buffer;
digittp[i+1]='
dtype=search(digittp,5);
digittp<
数据"
charotherprocess(charbuffer)//分界符、运算符、逻辑运算符、等
charothertp[20];
intotype,otypetp;
othertp[0]=buffer;
othertp[1]='
if(otype=search(othertp,3))
othertp[1]=buffer;
othertp[2]='
if(otypetp=search(othertp,3))//判断该运算符是否是
//由连续的两个字符组成的
othertp<
运算符"
gotoout;
else//单字符逻辑运算符
逻辑运算符"
if(otype=search(othertp,4))//关系运算符
if(otypetp=search(othertp,4))//判断该关系运算符是否是
关系运算符"
逻辑运算"
if(buffer=='
'
)//"
的判断
='
)
//cout<
=(2,2)\n"
if(otype=search(othertp,2))//分界符
分界符"
if((buffer!
\n'
)&
&
(buffer!
'
))
字符非法"
buffer<
out:
voidmain()
inti;
=50;
lableconst[i]="
//用于保存标识符
if(!
fp)
文件打开错误!
!
{
fp.get(cbuffer);
while(!
fp.eof())
if(cbuffer=='
linenum++;
fp.get(cbuffer);
elseif(isalpha(cbuffer))
cbuffer=alphaprocess(cbuffer);
elseif(isdigit(cbuffer))
cbuffer=digitprocess(cbuffer);
else
cbuffer=otherprocess(cbuffer);
标识符个数是:
lableconstnum<
分别是"
i=0;
while(i<
lableconstnum)
lableconst[i++]<
完成\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为地址
proc:
level:
=lev//如果是过程,保存过程的层次
end
end{enter};
//查找符号表的位置
functionposition(id:
alfa):
integer;
vari:
begin{findindentifieridintable}//从后向前查找
table[0].name:
i:
=tx;
//找到保存类型
whiletable[i].name<
iddoi:
=i-1;
position:
=i//返回标志符在符号表中的位置
end{position};
procedureblock(lev,tx:
fsys:
symset);
vardx:
{dataallocationindex}//数据分配索引
tx0:
{initialtableindex}//初始符号表索引
cx0:
{initialcodeindex}//初始代码索引
//填写符号表,下次分析
withtable[tx]do
casekof
amaxthen
=num
=lev
//查找符号表,下次分析
begin{findindentifieridintable}
=i
procedureconstdeclaration;
//常量声明
beginifsym=identthen//如果是标志符,读入一个TOKEN
begingetsym;
ifsymin[eql,becomes]then//读入的是等号或符值号继续判断
beginifsym=becomesthenerror
(1);
//如果是“=”报1号错
getsym;
//读入下一个TOKEN
ifsym=numberthen//读入的是数字,填写符号表
beginenter(constant);
getsym
elseerror
(2)//如果不是数字,报2号错
endelseerror(3)//不是等号或符值号,报3号错
endelseerror(4)//如果不是标志符,报4号错
end{constdeclaration};
procedurevardeclaration;
//变量声明
beginifsym=identthen//读入的是标志符,填写符号表
beginenter(varible);
getsym
endelseerror(4)//不是标志符,报4号错
end{vardeclaration};
procedurelistcode;
begin{listcodegeneratedforthisblock}
fori:
=cx0tocx-1do
withcode[i]do
writeln(i:
5,mnemonic[f]:
5,1:
3,a:
5)
end{listcode};
procedurestatement(fsys:
vari,cx1,cx2:
procedureexpression(fsys:
//表达式分析
varaddop:
symbol;
procedureterm(fsys:
//项分析
varmulop:
procedurefactor(fsys:
//因子分析
begintest(facbegsys,fsys,24);
//读入的是“(”,标志符或数字
whilesyminfacbegsysdo
begin
ifsym=identthen//是标志符,查表
begini:
=position(id);
ifi=0thenerror(11)else//未找到,报11号错
withtable[i]do//找到,读入标志符类型
casekindof
gen(lit,0,val);
//写常量命令
gen(lod,lev-level,adr);
//写变量命令
error(21)//过程名,报21号错
getsym//读入下一个TOKEN
endelse
ifsym=numberthen//读入的是数字
amaxthen//如果数字大于最大数,报30号错误
=0
gen(lit,0,num);
getsym//调用数字命令,读入下一个TOKEN
ifsym=lparenthen//读入的是“(”
expression([rparen]+fsys);
//调用表达式分析函数
ifsym=rparenthengetsymelseerror(22)//如果“(”后无“)”,报22号错
test(fsys,[lparen],23)
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{term};
begin{expression}
ifsymin[plus,minus]then//如果是加减号
beginaddop:
=sym;
term(fsys+[plus,minus]);
//记录符号,调用项分析程序
ifaddop=minusthengen(opr,0,1)//写加减指令
endelseterm(fsys+[plus,minus]);
whilesymin[plus,minus]do//如果是加减号循环
ifaddop=plusthengen(opr,0,2)elsegen(opr,0,3)
end{expression};
//条件过程
procedurecondition(fsys:
varrelop:
ifsym=oddsymthen//如果是判奇符
expression(fsys);
gen(opr,0,6)//取下一个TOKEN,调用expression,填指令
beginexpression([eql,neq,lss,gtr,leq,geq]+fsys);
ifnot(symin[eql,neq,lss,leq,gtr,geq])then//如果不是取到逻辑判断符号,出错.20
error(20)else
beginrelop:
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{condition};
begin{statement}
ifsym=identthen//如果是标识符
begini:
//查找符号表
ifi=0thenerror(11)else//未找到,标识符未定义,报11号错
iftable[i].kind<
variblethen//如果标识符不是变量,报12号错
begin{assignmenttonon-varible}error(12);
=0
ifsym=becomesthengetsymelseerror(13);
//如果是变量读入下一个TOKEN,不是赋值号,报13好错;
是则读入一个TOKEN
//调用表达是过程
ifi<
0then//写指令
withtable[i]dogen(sto,lev-level,adr)
ifsym=callsymthen//如果是过程调用保留字,读入下一个TOKEN
ifsym<
identthenerror(14)else//不是标识符报14号错
ifi=0thenerror(11)else//是标识符,未定义,报13号错
withtable[i]do/