📄 语法分析.cpp
字号:
#include "string.h"
#include "stdio.h"
#include "ctype.h"
#include "dos.h"
#define SPACE 0
#define LETTER 1
#define DIGIT 2
#define OTHER 3
#define FOR 1000
#define TO 1001
#define DO 1002
#define THEN 1003
#define IF 1004
#define ELSE 1005
#define BEGIN 1006
#define END 1007
#define REPEAT 1008
#define UNTIL 1009
#define TRUE 1
#define FALSE 0
#define MAXANA 100
/*输入字串的最大长度*/
#define MAXRESVL 10
/*保留字的最大长度*/
#define MAXRESERVE 20 /*保留字个数*/
typedef struct{
char str[10];
}lastwd;
/* 保留字 标志符 常数 操作符 界符 */
int lastwdkeywd[MAXRESERVE],
flagwd[20],intwd[20],oprwd[20],jief[20],errwd[20];
int ckeywd=0,cflagwd=0,cintwd=0,coprwd=0,cjief=0,cerrwd=0;/*计数*/
int curpos=0; /* 搜索串当前位置*/
/*声明函数*/
char getachar(char *,int);
/*此函数用于从字串*的int取一字符*/
int analyse(char);
/*此函数用于分析字符*/
int analy(char *);
/*此函数用于分析字串(关键字还是其他)*/
int writefile(char *,char *);
/*写入分析结果:char *属于int类*/
int writech(char *,char );
char anawd[MAXRESVL];
struct date today;
struct time now;
/*-------main()--------------------*/
main()
{char anastr[MAXANA]; /* 放待分析串*/
FILE *ff;
char curch; /*当前字符*/
int count=0,kindch,kindwd;
/*count 用来记录已搜索字符个数,kindch用来返回字符类型*/
int writeok,i;
for(i=0;i<MAXRESVL;i++)
anawd[i]='';/*kindwd用来返回字串类型*/
printf("输入分析串:(<100 char)");
gets(anastr);
strcat(anastr,"$$");
printf("\n正在分析字符串:: ");
printf("\n%s,%d",anastr,strlen(anastr)); /*技巧:设置结束标志'$'*/
while(getachar(anastr,curpos)!='$'&&curpos<=strlen(anastr))/*如未结束,则进行分析*/
{nextch:
anawd[count]=getachar(anastr,curpos);
curch=getachar(anastr,curpos);
kindch=analyse(curch); /*对当前字符分析*/
switch(kindch)
{
case LETTER: /*为字母*/
curpos++;
count++;
curch=getachar(anastr,curpos);
kindch=analyse(curch); /*对当前字符分析*/
if(kindch==SPACE)
{kindwd=analy(anawd);
/*函数analy()对分离出的单词anawd分析*/
if(kindwd!=0)
{strcpy(keywd[ckeywd].str,anawd);
writeok=writefile("类型:关键字,",anawd);/*写入分析结果*/
if(writeok==0)/*如写失败,则现场显示*/
{
printf("类型:关键字,%s\n",kindwd,anawd);
}
ckeywd++;
for(i=0;i<MAXRESVL;i++)
anawd[i]='';
count=0;
}
else if(kindwd==0)
{strcpy(flagwd[cflagwd].str,anawd);
writeok=writefile("类型:变量,",anawd);/*写入分析结果*/
if(writeok==0)/*如写失败,则现场显示*/
{
printf("类型:变量,%s\n",kindwd,anawd);
}
cflagwd++;
for(i=0;i<MAXRESVL;i++)
anawd[i]='';
count=0;
}
} /*******SPACE***/
else if(kindch==OTHER) /*========i=========== */
{kindwd=analy(anawd); /*函数analy()对分离出的单词anawd分析*/
if(kindwd!=0)
{strcpy(keywd[ckeywd].str,anawd);
writeok=writefile("类型:关键字,",anawd);/*写入分析结果*/
if(writeok==0)/*如写失败,则现场显示*/
{
printf("类型:关键字,%s\n",kindwd,anawd);
}
ckeywd++;
}
if(kindwd==0)
{strcpy(flagwd[cflagwd].str,anawd);
writeok=writefile("类型:标志符,",anawd);/*写入分析结果*/
if(writeok==0)/*如写失败,则现场显示*/
{
printf("类型:标志符,%s\n",kindwd,anawd);
}
cflagwd++;
}
for(i=0;i<MAXRESVL;i++)
anawd[i]='';
count=0;
}
else if(kindch==DIGIT)
{
do{
curch=getachar(anastr,curpos);
anawd[count]=curch; /*x5 */
count++;
curpos++; /* curch='=' */
}while(analyse(getachar(anastr,curpos))!=SPACE&&analyse(getachar(anastr,curpos))!=OTHER);
writeok=writefile("类型:变量, ",anawd);/*写入分析结果*/
if(writeok==0)/*如写失败,则现场显示*/
{
printf("类型:变量, %s\n",anawd);
}
strcpy(flagwd[cflagwd].str,anawd);
cflagwd++;
for(i=0;i<MAXRESVL;i++)
anawd[i]='';
count=0;
}
else goto nextch;
/*case LETTER: */
break;
case DIGIT:/*数字*/
{curpos++;
count++;
curch=getachar(anastr,curpos);
kindch=analyse(curch); /*对当前字符分析*/
if(kindch==DIGIT||kindch==SPACE||kindch==OTHER)
{if(kindch==DIGIT)
do{curch=getachar(anastr,curpos);
anawd[count]=curch;
count++;
curpos++;
}while(analyse(getachar(anastr,curpos))==DIGIT);
writeok=writefile("类型:数字, ",anawd);/*写入分析结果*/
if(writeok==0)/*如写失败,则现场显示*/
{
printf("类型:数字, %s\n",anawd);
}
strcpy(intwd[cintwd].str,anawd);
cintwd++;
for(i=0;i<MAXRESVL;i++)
anawd[i]='';
count=0;
}
else
{printf("变量声明错误!(变量不能以数字开始)");
do{curch=getachar(anastr,curpos);
anawd[count]=curch;
count++;
curpos++;
}while(analyse(getachar(anastr,curpos++))!=OTHER);
strcpy(errwd[cerrwd].str,anawd);
writeok=writefile("类型:错误, ",anawd);/*写入分析结果*/
if(writeok==0)/*如写失败,则现场显示*/
{
printf("类型:错误, %s\n",anawd);
}
cerrwd++;
for(i=0;i<MAXRESVL;i++)
anawd[i]='';
curpos--;
count=0;
goto nextch;
}
} /*case 数字 */
break;
case SPACE:
curpos++;
break;
case OTHER:
/*其他,如:=,:=,{,},;,*,(,),+*/ if(curch=='{'||curch=='}'||curch=='('||curch==')'||curch==';'||curch=='['||curch==']')
{ strcpy(jief[cjief].str,anawd);
writeok=writech("类型:界符,",curch);
/*写入分析结果*/
if(writeok==0)/*如写失败,则现场显示*/
{
printf("类型:界符, %s\n",curch);
}
curpos++;
cjief++;
for(i=0;i<MAXRESVL;i++)
anawd[i]='';
count=0;
}
else
if(curch=='-'||curch=='+'||curch=='*'||curch=='/'||curch=='%'||curch=='<'||curch=='>')
{strcpy(oprwd[coprwd].str,anawd);
writeok=writech("类型:运算符,",curch);/*写入分析结果*/
if(writeok==0)/*如写失败,则现场显示*/
{
printf("类型:运算符, %s\n",curch);
}
curpos++;
coprwd++;
for(i=0;i<MAXRESVL;i++)
anawd[i]='';
count=0;
}
else if(curch=='=')
{curpos++;
curch=getachar(anastr,curpos);
if(curch=='=')
{strcpy(oprwd[coprwd].str,"==");
writeok=writefile("类型:比较符,","==");/*写入分析结果*/
if(writeok==0)
/*如写失败,则现场显示*/
{
printf("类型:比较符, ==\n");
}
curpos++;
coprwd++;
for(i=0;i<MAXRESVL;i++)
anawd[i]='';
count=0;
}
else
{strcpy(oprwd[coprwd].str,anawd);
writeok=writech("类型:赋值符",'=');/*写入分析结果*/
if(writeok==0)
/*如写失败,则现场显示*/
{ printf("类型:赋值符,=\n");
}
/*分析当前字符*/
coprwd++;
for(i=0;i<MAXRESVL;i++)
anawd[i]='';
count=0;
}
}
else if(curch==':')
{curpos++;
curch=getachar(anastr,curpos);
if(curch=='=')
{strcpy(oprwd[coprwd].str,":=");
writeok=writefile("类型:赋值符,",":=");/*写入分析结果*/
if(writeok==0)
/*如写失败,则现场显示*/
{
printf("类型:赋值符, :=\n");
}
curpos++;
coprwd++;
for(i=0;i<MAXRESVL;i++)
anawd[i]='';
count=0;
}
}
break;
default:Error();
}
}
if(!(ff=fopen("jieg.txt","a")))
{printf("不能写文件jieg.txt!");
}
else{
fprintf(ff,"\n-------------简单词法分析器--");
fprintf(ff,"\n\t\t\t设计:计本003 安文政 完成日期:2003/01/09");
getdate(&today);
gettime(&now);
fprintf(ff,"\n 测试日期: %d-%d-%d",today.da_year,today.da_mon,today.da_day);
fprintf(ff," 测试时间: %02d:%02d:%02d",now.ti_hour,now.ti_min,now.ti_sec);
fprintf(ff,"\n-------------------------------");
fprintf(ff,"\n\t\t分析结果:");
fprintf(ff,"\n 输入的语句:%s ",anastr);
fprintf(ff,"\n ('$$'为系统添加的结束标志)");
fprintf(ff,"\n 保留字:");
for(i=0;i<ckeywd;i++)
fprintf(ff," %s ",keywd[i].str);
fprintf(ff,"\n 标志符:");
for(i=0;i<cflagwd;i++)
fprintf(ff," %s ",flagwd[i].str);
fprintf(ff,"\n 常数:");
for(i=0;i<cintwd;i++)
fprintf(ff," %s ",intwd[i].str);
fprintf(ff,"\n 操作符:");
for(i=0;i<coprwd;i++)
fprintf(ff," %s ",oprwd[i].str);
fprintf(ff,"\n 界符:");
for(i=0;i<cjief;i++)
fprintf(ff," %s ",jief[i].str);
fprintf(ff,"\n 错误类型:");
if(cerrwd==0)
fprintf(ff," 无");
else
for(i=0;i<cerrwd;i++)
fprintf(ff," %s ",errwd[i].str);
fclose(ff);
}
printf("\n分析结果已保存于当前目录下的 jieguo.txt!");
printf("\n\t 计本003 安文政 2003/01/09");
}
Error(char *strin)
{
printf(" \n发现非法字符!!\n ");
strcpy(errwd[cerrwd].str,strin);
cerrwd++;
}
char getachar(char *anastr,int where) /*此函数从字串*anastr的where取一字符*/
{char ch;
ch=anastr[where];
/*printf("\n%d,%c in function getachar ",where,ch);*/
return ch;
}
int analyse(char ch) /*此函数用于分析字符*/
{if(isalpha(ch))
{
return LETTER;
}
else if(isdigit(ch))
{
return DIGIT;
}
else if(isspace(ch))
{
return SPACE;}
else return OTHER;
}
int writefile(char *kind,char *str)
{FILE *fp;
if(!(fp=fopen("jieguo.txt","a")))
{printf("不能写文件jieguo.txt!");
return 0;
}
fprintf(fp," %s %s\n",kind,str);
fclose(fp);
return 1;
}
int writech(char *kind,char str)
{FILE *fp;
if(!(fp=fopen("jieguo.txt","a")))
{printf("不能写文件jieguo.txt!");
return 0;
}
fprintf(fp," %s %c\n",kind,str);
fclose(fp);
return 1;
}
int analy(char *wd)
{if(!strcmp(wd,"for"))
return FOR;
else if(!strcmp(wd,"do"))
return DO;
else if(!strcmp(wd,"to"))
return TO;
else if(!strcmp(wd,"then"))
return THEN;
else if(!strcmp(wd,"if"))
return IF;
else if(!strcmp(wd,"else"))
return ELSE;
else if(!strcmp(wd,"begin"))
return BEGIN;
else if(!strcmp(wd,"end"))
return END;
else if(!strcmp(wd,"repeat"))
return REPEAT;
else if(!strcmp(wd,"until"))
return UNTIL;
else return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -