词法分析器C语言版文档格式.docx
《词法分析器C语言版文档格式.docx》由会员分享,可在线阅读,更多相关《词法分析器C语言版文档格式.docx(16页珍藏版)》请在冰豆网上搜索。
,
("
)"
["
]"
{"
}"
&
||"
;
."
:
\"
%"
#"
\'
};
//keywordtable
char*k[]={"
for"
while"
do"
go"
to"
switch"
if"
else"
int"
float"
char"
static"
break"
exit"
continu"
error"
//标识符结构体
typedefstruct
{
char*I[256];
//标识符数组
intlen;
//标识符数量
}identifier;
//常量结构体
typedefstruct{
intcont[300];
//存放常量的数组
//常量的数目
}constnumber;
//读入一个字符,从输入流中读入一个字符到变量character中。
voidgetNextChar(FILE*ifp)
if((character=getc(ifp))==EOF)
exit
(1);
}
//读入非空白字符,检查变量character中的字符是否为空白字符或回车或换行符。
若是,
//则调用getNextChar()读入下一个字符,直到character中的字符满足条件.
voidgetnbc(FILE*ifp)
{
while(character=='
'
||character=='
\n'
||character==9)
{
getNextChar(ifp);
}
//连接字符串,把character中的字符连接到token数组的结尾。
voidconcat()
char*ct=&
character;
strcat(token,ct);
//判断是否为字母。
intletter()
returnisalpha(character);
//判断是否为数字
intdigit()
returnisdigit(character);
//回退字符,将刚读入的character中的字符回退到输入流中。
并把character中的值置为空。
voidretract(FILE*ifp)
(ifp->
_cnt)++;
_ptr)--;
character='
//处理保留字,对存放在token中的字符串查保留字,若查到,则返回该保留字的类别编码,否则返回0.
intreserve(char**k)
inti;
for(i=0;
i<
LENGTH1;
i++)
if(strcmp(token,k[i])==0)
returni+1;
return0;
//处理标识符,对存放在token中的字符串查找符号表,若查到,则返回它在符号表的位置,
//存入常数表中,并返回它在常数表中的位置编号。
intsymbol(identifier*id)
id->
len;
if(strcmp(token,id->
I[i])==0)
if(id->
len>
256)
assert(0);
id->
I[id->
len]=token;
len++;
returnid->
//将数字字符串转化为整数。
intstrtonumber()
intsum=0;
strlen(token);
sum=10*sum+(token[i]-'
0'
);
}
returnsum;
//常数存入常数表的函数,将token中的数字串(实际上是字符串),转化成标准的二进制值(整数值)
intconstant(constnumber*con)
con->
cont[con->
len]=strtonumber();
returncon->
//将整数值转化为字符串
char*numbertoString(intnum)
chars[3];
inti=num/10;
while(i>
0)
charc=i+'
strcat(s,&
c);
returns;
//将结果写入到文件并且输出到屏幕。
voidreturntofile(intnum,intval,identifier*id,constnumber*con)
int_num=num;
charc;
c='
('
putc(c,fw);
printf("
%c"
c);
i=_num/10;
_num=_num-10*i;
c=(i+'
printf("
putc(c,fw);
i=_num/10;
c=_num+'
putc('
'
fw);
//如果是标识符或常数则放入括号内。
if(num==1)//处理标识符
%s"
id->
I[val-1]);
\n"
fputs(id->
I[val-1],fw);
putc('
)'
if(num==2)//处理常数
_num=con->
cont[val-1];
while(i>
{
_num=_num-10*i;
c=(i+'
printf("
putc(c,fw);
i=_num/10;
}
c=_num+'
if(num==3)//保留字
"
|"
k[val-1]);
|"
-'
fputs("
#'
fputs(k[val-1],fw);
if(num>
3)//处理界符
CODE[num-1]);
fputs(CODE[num-1],fw);
//将错误写入到文件或输出到屏幕
voiderror()
(ERROR,"
character);
fputs("
putc(character,fw);
//词法分析函数
voidLexAnalyze(char**k,char**CODE,identifier*id,constnumber*con,FILE*fp,FILE*fw)
intnum,val;
strcpy(token,"
getNextChar(fp);
getnbc(fp);
switch(character)
case'
a'
b'
c'
d'
e'
f'
g'
h'
i'
j'
k'
l'
m'
n'
o'
p'
q'
r'
s'
t'
u'
v'
w'
x'
y'
z'
A'
B'
C'
D'
E'
F'
G'
H'
I'
J'
K'
L'
M'
N'
O'
P'
Q'
R'
S'
T'
U'
V'
W'
X'
Y'
Z'
while(letter()||digit())
concat();
getNextChar(fp);
retract(fp);
num=reserve(k);
//保留字
if(num!
=0)
returntofile(3,num,id,con);
else
val=symbol(id);
returntofile(1,val,id,con);
break;
1'
2'
3'
4'
5'
6'
7'
8'
9'
while(digit())
val=constant(con);
returntofile(2,val,id,con);
'
getNextChar(fp);
if(character=='
='
)
returntofile(9,0,id,con);
retract(fp);
returntofile(8,0,id,con);
returntofile(11,0,id,con);
else
returntofile(10,0,id,con);
returntofile(13,0,id,con);
returntofile(14,0,id,con);
returntofile(12,0,id,con);
error();
+'
returntofile(4,0,id,con);
returntofile(5,0,id,con);
*'
returntofile(6,0,id,con);
/'
returntofile(7,0,id,con);
returntofile(15,0,id,con);
returntofile(16,0,id,con);
returntofile(17,0,id,con);
returntofile(18,0,id,con);
returntofile(19,0,id,con);
{'
returntofile(20,0,id,con);
}'
returntofile(21,0,id,con);
case'
returntofile(22,0,id,con);
\\'
returntofile(23,0,id,con);
returntofile(25,0,id,con);
%'
returntofile(26,0,id,con);
|'
returntofile(27,0,id,con);
returntofile(28,0,id,con);
.'
returntofile(29,0,id,con);
=='
returntofile(32,0,id,con);
returntofile(33,0,id,con);
['
returntofile(34,0,id,con);
]'
returntofile(35,0,id,con);
default:
error();
main(intargc,char*argv[])
//初始化标识符和常数结构体
identifier*id=(identifier*)malloc(sizeof(identifier));
constnumber*con=(constnumber*)malloc(sizeof(constnumber));
len=0;
argc=3;
argv[1]="
E:
\\file1.txt"
//待分析的文件
argv[2]="
\\file2.txt"
//保存分析结果的文件
//从打开目标文件流
if((fp=fopen(argv[1],"
r"
))==NULL)
cat:
can'
topen%s\n"
*argv);
return1;
//打开要写二元式的文件流
if((fw=fopen(argv[2],"
w"
can'
argv[2]);
while(!
feof(fp))
LexAnalyze(k,CODE,id,con,fp,fw);
//执行词法分析
//关闭流
fclose(fp);
fclose(fw);