词法分析器实验Word文件下载.docx
- 文档编号:20598957
- 上传时间:2023-01-24
- 格式:DOCX
- 页数:15
- 大小:84.63KB
词法分析器实验Word文件下载.docx
《词法分析器实验Word文件下载.docx》由会员分享,可在线阅读,更多相关《词法分析器实验Word文件下载.docx(15页珍藏版)》请在冰豆网上搜索。
28
标识符
11
名字表地址
[
29
正整数
12
常数表地址
]
30
正实数
(
31
零
)
32
+
13
{
33
-
14
}
34
*
15
;
35
/
16
.
36
%
17
换行符
37
18
文件结束
38
3、测试报告
3.1测试数据:
首先在记事本中输入一个程序(最好存在D盘里方便读取):
3.2运行后在控制台上得到的结果如图所示:
3.3运行后得到的常数表与标识符表:
4、源代码
#include<
stdio.h>
stdlib.h>
#include"
stdio.h"
conio.h"
string.h"
#defineMAX100
charin[MAX];
//程序
charNameL[100][100];
//标识符表
intConstL[100][100];
//常数表
FILE*fin,*fout1,*fout2;
structa{
intclass;
charseman[10];
}token[80];
structerr{//记录错误信息的链表结点
intline1;
chardescribe[50];
structerr*next;
};
structerr*table;
//错误表头结点和尾结点
structerr*tail;
structerr*head;
inti,k=0,m=1,h=1,line=0,low=0,a=1,g=1;
//k每个字符串的下标,m,h表中的下标,line,low表中字符串总数,a为0报错,g标示头结点
intline1=1;
//记录行号
interrors=0;
//记录错误数
intisletter(charx)
if((x>
='
a'
x<
z'
)||(x>
A'
Z'
))
return1;
elsereturn0;
intisdigit(charx)
if(x>
0'
9'
)return1;
/*输出已识别的单词*/
voidprint_token(intk)
inti;
printf("
\ntokenlist:
"
);
for(i=0;
i<
k;
i++)
\n%3dtoken.class:
%3dtoken.seman:
%3s"
i+1,token[i].class,token[i].seman);
intnext_token()
charkeyword[100][100]={"
if"
"
else"
for"
while"
break"
return"
continue"
float"
int"
char"
printf"
//关键字表
charah,ch,name[10];
//ah标识正在进行字符的下一字符,用来判断该标识符是否包含符号
intstate,l,n,j,c=1,x=1,s=1,p=1;
//c用来判断是否关键字,x用来判断是否以数字开头,p判断有符号的字符串是不是关键字
ch=in[i];
state=0;
while(ch=='
'
||ch=='
\t'
\n'
{
if(ch=='
){state=37;
line1++;
break;
elsech=in[++i];
}
while
(1)
switch(state)
case0:
if(isletter(ch)){l=0;
name[l++]=ch;
state=40;
getA(ch);
}//标识符
elseif(isdigit(ch)){l=0;
state=41;
}//常数
elseif(ch=='
+'
)state=13;
-'
)state=14;
*'
)state=15;
/'
)state=16;
%'
)state=17;
'
)state=18;
//接着检查>
>
=,后赋值,错误
)state=20;
)state=28;
//接着检查==,=赋值和错误
)state=24;
)state=25;
|'
)state=26;
'
)state=27;
['
)state=29;
]'
)state=30;
('
)state=31;
)'
)state=32;
{'
)state=33;
}'
)state=34;
)state=35;
.'
)state=36;
)state=37;
#'
){i--;
return0;
else{a=0;
errA(4);
}break;
case40:
ch=in[++i];
ah=in[i+1];
if(isletter(ch)||isdigit(ch)){state=40;
elsestate=42;
case41:
if(isdigit(ch)){name[l++]=ch;
state=41;
elseif(isletter(ch))
if(s)
errA
(2);
a=0;
else{name[l++]=ch;
s=0;
else
if(s){state=43;
else{state=42;
}break;
case42:
name[l]='
\0'
strcpy(token[k].seman,name);
i--;
//判断该标识符是否为关键字
for(n=0;
n<
100;
n++)
if(strcmp(name,keyword[n])==0)
token[k++].class=n+1;
c=0;
break;
//判断该标识符是否存在标识符表中
if(c)
if(line!
=0)
intq=0;
while(q<
line)
if(strcmp(name,NameL[q++])==0)
token[k].class=11;
x=0;
if(x)
strcpy(NameL[line],name);
fprintf(fout1,"
%s\t(%d)\n"
token[k].seman,m++);
line++;
k++;
return0;
case43:
//判断该常数是否存在常数表中
if(low!
low)
if(strcmp(name,ConstL[q++])==0)
k++;
strcpy(ConstL[low],name);
fprintf(fout2,"
token[k].seman,h++);
token[k].class=12;
low++;
case13:
token[k].class=13;
strcpy(token[k].seman,"
+"
case14:
token[k].class=14;
-"
case15:
token[k].class=15;
*"
case16:
token[k].class=16;
/"
case17:
token[k].class=17;
%"
case18:
ch=in[i+1];
)state=62;
elseif(isletter(ch)||isdigit(ch)||ch=='
){state=63;
else{state=63;
a=0;
errA(5);
}break;
case62:
token[k].class=19;
="
i++;
case63:
token[k].class=18;
case20:
)state=21;
){state=64;
else{state=64;
case21:
token[k].class=21;
case64:
token[k].class=20;
case22:
token[k].class=22;
case28:
){state=61;
){state=67;
else{state=67;
case61:
token[k].class=23;
=="
case67:
token[k].class=28;
case24:
)state=22;
){state=65;
else{state=65;
case65:
token[k].class=24;
case25:
token[k].class=25;
ah=in[++i];
if(ah=='
){strcpy(token[k].seman,"
else{i--;
}return0;
case26:
token[k].class=26;
||"
|"
case27:
token[k].class=27;
case29:
token[k].class=29;
["
j=i;
if(ch)
ch=in[i++];
){i=j;
j=0;
if(j){a=0;
errA(3);
i=j;
case30:
token[k].class=30;
]"
while(ch)
case31:
token[k].class=31;
("
case32:
token[k].class=32;
)"
case33:
token[k].class=33;
{"
case34:
token[k].class=34;
}"
case35:
token[k].class=35;
case36:
token[k].class=36;
."
case37:
token[k].class=37;
换行符"
default:
voidgetA(charch)
line1++;
ch=in[++i];
voiderrA(inttype)
structerr*newerr=(structerr*)malloc(sizeof(structerr));
errors++;
newerr->
next=NULL;
line1=line1;
switch(type)
//case1:
strcpy(newerr->
describe,"
变量名要满足不能包括标点符号"
case2:
不能以数字开头的数字与字母的字符串"
case3:
括号要成对出现"
case4:
词法分析不出现该符号"
case5:
不满足比较规则"
if(g)
head=newerr;
head->
tail=head;
g=0;
tail->
next=newerr;
tail=newerr;
intmain()
intl=0;
charinput[100],output1[100],output2[100];
table=(structerr*)malloc(sizeof(structerr));
//定义错误链表结点
table->
tail=table;
******************c语言实现编译原理词法分析器******************\n\n"
//输入文件名的路径和文件名
请输入词法分析输入的文件名(包括路径):
scanf("
%s"
input);
请输入词法分析输出的标识符表文件名(包括路径):
output1);
请输入词法分析输出的常数表文件名(包括路径):
output2);
fin=fopen(input,"
r"
fout1=fopen(output1,"
w"
fout2=fopen(output2,"
if(fin==NULL)
词法分析输入文件有错\n"
return
(1);
\n词法分析结束\n"
while(!
feof(fin))
in[l++]=fgetc(fin);
in[l]='
i=0;
while(in[i]!
next_token();
i++;
if(a)
{token[k].class=38;
strcpy(token[k].seman,"
#"
\n\nscannerissuccend!
print_token(k);
\n\nscannerisfalse!
"
printf("
\n\n错误总数为%d个\n"
errors);
tail=head;
while(tail)
\n第%d行\t错误为:
%s\n"
tail->
line1,tail->
describe);
tail=tail->
next;
fclose(fin);
fclose(fout1);
fclose(fout2);
getch();
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 词法 分析器 实验