词法分析器
2013-02-25 18:33
190 查看
1 问题描述
对于如下文法所定义的PASCAL语言子集,试编写并上机调试一个词法分析程序:
<程序>→PROGRAM
<标识符>;<分程序>.
<分程序>→<变量说明>BEGIN<语句表>END
<变量说明>→VAR<变量表>:<类型>;|
<空>
<变量表>→<变量表>,<变量>
| <变量>
<类型>→INTEGER
<语句表>→<语句表>;<语句>
| <语句>
<语句>→<赋值语句>
| <条件语句> |
<WHILE语句> |
<复合语句> |
<过程定义>
<赋值语句>→<变量>:=<算术表达式>
<条件语句>→IF<关系表达式>THEN<语句>ELSE<语句>
<WHILE语句>→WHILE<关系表达式>DO<语句>
<复合语句>→BEGIN<语句表>END
<过程定义>→PROCEDURE<标识符><参数表>;
BEGIN<语句表>END
<参数表>→(<标识符表>)|
<空>
<标识符表>→<标识符表>,<标识符>
| <标识符>
<算术表达式>→<算术表达式>+<项>
| <项>
<项>→<项>*<初等量>
| <初等量>
<初等量>→(<算术表达式>)|
<变量> |
<无符号数>
<关系表达式>→<算术表达式><关系符><算术表达式>
<变量>→<标识符>
<标识符>→<标识符><字母>
|
<标识符><数学>
| <字母>
<无符号数>→<无符号数><数字>
| <数字>
<关系符>→= | < |
<= | > | >= |
<>
<字母>→A | B | C | ··· | X | Y |
Z
<数字>→0 | 1 | 2 | ··· | 8 | 9
<空>→
要求和提示:
(1)
单词的分类。
可将所有标识符归为一类;将常数归为另一类;保留字和分隔符则采取一词一类。
(2)
符号表的建立。
可事先建立一保留字表,以备在识别保留字时进行查询。变量名表及常数表则在词法分析过程中建立。
(3)
单词串的输出形式。
所输出的每一单词,均按形如(CLASS,VALUE)的二元式编码。对于变量标识符和常数,CLASS字段为相应的类别码,VALUE字段则是该标识符、常数在其符号表中登记项的序号(要求在变量名表登记项中存放该标识符的字符串,其最大长度为四个字符;常数表登记项中则存放该整数的二进制形式。)。对于保留字和分隔号,由于采用一词一类的编码方式,所以仅需在二元式的CLASS字段上放置相应的单词的类别码,VALUE字段则为“空”。不过,为便于查看由词法分析程序所输出的单词串,也可以在CLASS字段上直接放置单词符号串本身。
2 C源代码
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define num 32
char *keysign[num]={
"auto","break","case","char",
"const","continue","default","do",
"double","else","enum","extern",
"float","for","goto","if",
"int","long","regist","return",
"short","signed","sizeof","static",
"struct","switch","typedef","union",
"unsigned","void","volatile","while"};
FILE *fpin,*fpout,*outa,*outb,*outc;
char token[40];
int j=0;
int lookup()
{
int
i,k=0;
for(i=0;i<=31;i++)
{
if(strcmp(token,keysign[i])==0)
{
k=1;
return(1);
}
}
if(k!=1)
return(0);
}
void cltoken()
{
j=0;
strcpy(token," ");
}
int scanner(void)
{
char ch,in[40],out[40];
char aa[40],bb[40],cc[40];
int id=0;
printf("please input the Source document
name:");
scanf("%s",in);
printf("please input the document name which
will be saved:");
scanf("%s",out);
printf("please input the aa document name which
will be saved:");
scanf("%s",aa);
printf("please input the bb document name which
will be saved:");
scanf("%s",bb);
printf("please input the cc document name which
will be saved:");
scanf("%s",cc);
if((fpin=fopen(in,"rt"))==NULL)
{
printf("\nSource document file
can't be found");
return(1);
}
fpout=fopen(out,"wt");
outa=fopen(aa,"wt");
outb=fopen(bb,"wt");
outc=fopen(cc,"wt");
ch=fgetc(fpin);
while(ch!=EOF)
{
if(isspace(ch))
ch=fgetc(fpin);
else if(isalpha(ch))
{
token[j]=ch;
for(ch=fgetc(fpin);isalnum(ch)||ch=='_';ch=fgetc(fpin))
token[++j]=ch;
token[++j]='\0';
id=lookup();
printf("%d--->%s\n",id,token);
fprintf(outa,"%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
cltoken();
}
else if(isdigit(ch))
{
token[j]=ch;
for(ch=fgetc(fpin);isdigit(ch);ch=fgetc(fpin))
token[++j]=ch;
token[++j]='\0';
id=2;
printf("%d--->%s\n",id,token);
fprintf(outb,"%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
cltoken();
}
else if(ch=='!' || ch=='{' ||
ch=='*' || ch=='/' || ch=='%'|| ch=='}' || ch=='[' ||
ch==']'||ch=='(' ||ch==')'|| ch=='?')
{
id=3;
printf("%d--->%c\n",id,ch);
fprintf(outc,"%d--->%s\n",id,ch);
fprintf(fpout,"%d--->%c\n",id,ch);
ch=fgetc(fpin);
}
else
if(ch=='=')
{
token[j]=ch;
ch=fgetc(fpin);
if(ch=='=')
{token[++j]=ch;id=4;ch=fgetc(fpin);}
else id=5;
token[++j]='\0';
printf("%d--->%s\n",id,token);
fprintf(outc,"%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
cltoken();
}
else
if(ch=='&')
{
token[j]=ch;
ch=fgetc(fpin);
if(ch=='&')
{token[++j]=ch;id=6;ch=fgetc(fpin);}
else id=7;
token[++j]='\0';
printf("%d--->%s\n",id,token);
fprintf(outc,"%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
cltoken();
}
else
if(ch=='>')
{
token[j]=ch;
ch=fgetc(fpin);
if(ch=='=')
{token[++j]=ch;id=8;ch=fgetc(fpin);}
else id=9;
token[++j]='\0';
printf("%d--->%s\n",id,token);
fprintf(outc,"%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
cltoken();
}
else
if(ch=='<')
{
token[j]=ch;
ch=fgetc(fpin);
if(ch=='=') {token[++j]=ch;id=10;}
else id=11;
token[++j]='\0';
printf("%d--->%s\n",id,token);
fprintf(outc,"%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
cltoken();
}
else
if(ch=='+')
{
token[j]=ch;
ch=fgetc(fpin);
if(ch=='+')
{token[++j]=ch;id=12;ch=fgetc(fpin);}
else id=13;
token[++j]='\0';
printf("%d--->%s\n",id,token);
fprintf(outc,"%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
cltoken();
}
else
if(ch=='-')
{
token[j]=ch;
ch=fgetc(fpin);
if(ch=='-')
{token[++j]=ch;id=14;ch=fgetc(fpin);}
else id=15;
token[++j]='\0';
printf("%d--->%s\n",id,token);
fprintf(outc,"%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
cltoken();
}
else
{
token[0]=ch;
token[1]='\0';
printf("%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
ch=fgetc(fpin);
}
}
fclose(fpin);
fclose(fpout);
fclose(outa);
fclose(outb);
fclose(outc);
return(1);
}
void main(void)
{
scanner();
printf("The lexical analysis has been completed
successfully!");
}
对于如下文法所定义的PASCAL语言子集,试编写并上机调试一个词法分析程序:
<程序>→PROGRAM
<标识符>;<分程序>.
<分程序>→<变量说明>BEGIN<语句表>END
<变量说明>→VAR<变量表>:<类型>;|
<空>
<变量表>→<变量表>,<变量>
| <变量>
<类型>→INTEGER
<语句表>→<语句表>;<语句>
| <语句>
<语句>→<赋值语句>
| <条件语句> |
<WHILE语句> |
<复合语句> |
<过程定义>
<赋值语句>→<变量>:=<算术表达式>
<条件语句>→IF<关系表达式>THEN<语句>ELSE<语句>
<WHILE语句>→WHILE<关系表达式>DO<语句>
<复合语句>→BEGIN<语句表>END
<过程定义>→PROCEDURE<标识符><参数表>;
BEGIN<语句表>END
<参数表>→(<标识符表>)|
<空>
<标识符表>→<标识符表>,<标识符>
| <标识符>
<算术表达式>→<算术表达式>+<项>
| <项>
<项>→<项>*<初等量>
| <初等量>
<初等量>→(<算术表达式>)|
<变量> |
<无符号数>
<关系表达式>→<算术表达式><关系符><算术表达式>
<变量>→<标识符>
<标识符>→<标识符><字母>
|
<标识符><数学>
| <字母>
<无符号数>→<无符号数><数字>
| <数字>
<关系符>→= | < |
<= | > | >= |
<>
<字母>→A | B | C | ··· | X | Y |
Z
<数字>→0 | 1 | 2 | ··· | 8 | 9
<空>→
要求和提示:
(1)
单词的分类。
可将所有标识符归为一类;将常数归为另一类;保留字和分隔符则采取一词一类。
(2)
符号表的建立。
可事先建立一保留字表,以备在识别保留字时进行查询。变量名表及常数表则在词法分析过程中建立。
(3)
单词串的输出形式。
所输出的每一单词,均按形如(CLASS,VALUE)的二元式编码。对于变量标识符和常数,CLASS字段为相应的类别码,VALUE字段则是该标识符、常数在其符号表中登记项的序号(要求在变量名表登记项中存放该标识符的字符串,其最大长度为四个字符;常数表登记项中则存放该整数的二进制形式。)。对于保留字和分隔号,由于采用一词一类的编码方式,所以仅需在二元式的CLASS字段上放置相应的单词的类别码,VALUE字段则为“空”。不过,为便于查看由词法分析程序所输出的单词串,也可以在CLASS字段上直接放置单词符号串本身。
2 C源代码
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define num 32
char *keysign[num]={
"auto","break","case","char",
"const","continue","default","do",
"double","else","enum","extern",
"float","for","goto","if",
"int","long","regist","return",
"short","signed","sizeof","static",
"struct","switch","typedef","union",
"unsigned","void","volatile","while"};
FILE *fpin,*fpout,*outa,*outb,*outc;
char token[40];
int j=0;
int lookup()
{
int
i,k=0;
for(i=0;i<=31;i++)
{
if(strcmp(token,keysign[i])==0)
{
k=1;
return(1);
}
}
if(k!=1)
return(0);
}
void cltoken()
{
j=0;
strcpy(token," ");
}
int scanner(void)
{
char ch,in[40],out[40];
char aa[40],bb[40],cc[40];
int id=0;
printf("please input the Source document
name:");
scanf("%s",in);
printf("please input the document name which
will be saved:");
scanf("%s",out);
printf("please input the aa document name which
will be saved:");
scanf("%s",aa);
printf("please input the bb document name which
will be saved:");
scanf("%s",bb);
printf("please input the cc document name which
will be saved:");
scanf("%s",cc);
if((fpin=fopen(in,"rt"))==NULL)
{
printf("\nSource document file
can't be found");
return(1);
}
fpout=fopen(out,"wt");
outa=fopen(aa,"wt");
outb=fopen(bb,"wt");
outc=fopen(cc,"wt");
ch=fgetc(fpin);
while(ch!=EOF)
{
if(isspace(ch))
ch=fgetc(fpin);
else if(isalpha(ch))
{
token[j]=ch;
for(ch=fgetc(fpin);isalnum(ch)||ch=='_';ch=fgetc(fpin))
token[++j]=ch;
token[++j]='\0';
id=lookup();
printf("%d--->%s\n",id,token);
fprintf(outa,"%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
cltoken();
}
else if(isdigit(ch))
{
token[j]=ch;
for(ch=fgetc(fpin);isdigit(ch);ch=fgetc(fpin))
token[++j]=ch;
token[++j]='\0';
id=2;
printf("%d--->%s\n",id,token);
fprintf(outb,"%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
cltoken();
}
else if(ch=='!' || ch=='{' ||
ch=='*' || ch=='/' || ch=='%'|| ch=='}' || ch=='[' ||
ch==']'||ch=='(' ||ch==')'|| ch=='?')
{
id=3;
printf("%d--->%c\n",id,ch);
fprintf(outc,"%d--->%s\n",id,ch);
fprintf(fpout,"%d--->%c\n",id,ch);
ch=fgetc(fpin);
}
else
if(ch=='=')
{
token[j]=ch;
ch=fgetc(fpin);
if(ch=='=')
{token[++j]=ch;id=4;ch=fgetc(fpin);}
else id=5;
token[++j]='\0';
printf("%d--->%s\n",id,token);
fprintf(outc,"%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
cltoken();
}
else
if(ch=='&')
{
token[j]=ch;
ch=fgetc(fpin);
if(ch=='&')
{token[++j]=ch;id=6;ch=fgetc(fpin);}
else id=7;
token[++j]='\0';
printf("%d--->%s\n",id,token);
fprintf(outc,"%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
cltoken();
}
else
if(ch=='>')
{
token[j]=ch;
ch=fgetc(fpin);
if(ch=='=')
{token[++j]=ch;id=8;ch=fgetc(fpin);}
else id=9;
token[++j]='\0';
printf("%d--->%s\n",id,token);
fprintf(outc,"%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
cltoken();
}
else
if(ch=='<')
{
token[j]=ch;
ch=fgetc(fpin);
if(ch=='=') {token[++j]=ch;id=10;}
else id=11;
token[++j]='\0';
printf("%d--->%s\n",id,token);
fprintf(outc,"%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
cltoken();
}
else
if(ch=='+')
{
token[j]=ch;
ch=fgetc(fpin);
if(ch=='+')
{token[++j]=ch;id=12;ch=fgetc(fpin);}
else id=13;
token[++j]='\0';
printf("%d--->%s\n",id,token);
fprintf(outc,"%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
cltoken();
}
else
if(ch=='-')
{
token[j]=ch;
ch=fgetc(fpin);
if(ch=='-')
{token[++j]=ch;id=14;ch=fgetc(fpin);}
else id=15;
token[++j]='\0';
printf("%d--->%s\n",id,token);
fprintf(outc,"%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
cltoken();
}
else
{
token[0]=ch;
token[1]='\0';
printf("%d--->%s\n",id,token);
fprintf(fpout,"%d--->%s\n",id,token);
ch=fgetc(fpin);
}
}
fclose(fpin);
fclose(fpout);
fclose(outa);
fclose(outb);
fclose(outc);
return(1);
}
void main(void)
{
scanner();
printf("The lexical analysis has been completed
successfully!");
}
相关文章推荐