实验目的实验要求及实验环境
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、实验目的,实验要求及实验环境
目的:掌握词法分析的基本方法。具有设计各种常见语言成分的目标结构的能力
要求:编写一个词法分析程序,对给出的程序段进行词法分析,要求输出以文件形式存放的TOKEN串和符号表
环境:Microsoft Visual C++6.0
二、实验用到的词类编码表
main 0
( 2
) 3
a 0
: 4
int 6
; 5
b 0
: 4
int 6
; 5
{ 6
if 4
a 0
> 8
0 1
and 5
c 0
> 8
0 1
then 7
a 0
= 9
0 1
else 3
a 0
= 9
1 1
; 5
while 8
a 0
< 10
5 1
do 2
a 0
= 9
a 0
+ 11
1 1
} 7
三、设计符号表的逻辑结构及存贮结构
实验中用到的关键字表,限界符、运算符表均存储在文件中,因此没用到结构。每次查询时只需打开文件查阅。
关键字表(keyword.txt):
do
else
if
and
int
then
while
运算符、限界符表(limit.txt):
(
)
:
;
{
}
>
=
<
+
四、词法分析程序中主要模块的算法
识别标识符的算法:
//以字母和下划线开头
if (((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z')) || (ch == '_')){
while(((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z')) || (ch == '_') || ((ch >= '0') && (ch <= '9'))){
array[i++]=ch;
ch = fgetc(fp);
}
word=(char*)malloc((i + 1) * sizeof(char));
memcpy(word, array, i);
word[i] = '\0';
intdeal(word);
if (ch != EOF){
fseek(fp, -1, SEEK_CUR);
}
}
识别特殊符号/的算法:
分三种情况:/=、/、 /*
//消除注释
else if (ch == '/'){
ch = fgetc(fp);
if (ch == '='){ //判断是否为‘/=’号
outputfp = fopen("token.txt", "a");
fprintf(outputfp, "/=\t4\t\t\t13\n");
fclose(outputfp);
}
else if (ch != '*'){ //若为除号,写入输出文件
outputfp = fopen("token.txt", "a");
fprintf(outputfp, "/\t4\t\t\t13\n");
fclose(outputfp);
fseek(fp, -1, SEEK_CUR);
}
else if (ch == '*'){ //若为注释的开始,则忽略注释内容
count=0;
ch = fgetc(fp);
while(count!=2){ //当扫描到‘*’且紧接着下一个字符为‘/’才是注释的结束
count=0;
while(ch != '*')
ch = fgetc(fp);
count++;
ch = fgetc(fp);
if(ch=='/')
count++;
else
ch = fgetc(fp);
}
}
}
识别界限符
//首字符为其它字符,即运算限界符或非法字符
else {
errorno = 0;
array[0] = ch;
ch = fgetc(fp); //再读入下一个字符,判断是否为双字符运算、限界符
if (ch != EOF){
array[1]=ch;
word = (char*)malloc(3 * sizeof(char));
memcpy(word, array, 2);
word[2] = '\0';
//先检索是否为双字符运算、限界符
result = search(word, 2, 1);
if (result == 0){ //若不是
word = (char*)malloc(2 * sizeof(char));
memcpy(word, array, 1);
word[1] = '\0';
result = search(word, 2, 1); //检索是否为单字符运算、限界符
if (result == 0){ //若还不是,则为非法字符
errordeal(array[0], line);
errorno++;
fseek(fp, -1, SEEK_CUR);
}
else { //若为单字符运算、限界符,写入输出文件并将扫描文件指针回退一个字符
outputfp = fopen("token.txt", "a");
fprintf(outputfp, "%d\n", result);
fclose(outputfp);
fseek(fp, -1, SEEK_CUR);
}
}
else { //若为双字符运算、限界符,写入输出文件
outputfp = fopen("token.txt", "a");
fprintf(outputfp, "%d\n", result);
fclose(outputfp);
}
}
else { //若读入的下一个字符为文件结束符
word = (char*)malloc(2 * sizeof(char));
memcpy(word, array, 1);
word[1] = '\0';
result = search(word, 2, 1); //只考虑是否为单字符运算、