📄 词法分析器.cpp
字号:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_CODE 1000
#define MAX_SYMBOL 32
int i,j,k,sign,number,flag;/*把类号内码等定义成全局变量*/
char ch;
int line;
char words[MAX_SYMBOL]={" "};/*定义一个符号表*/
char program[MAX_CODE]; //用于保存源程序的字符数组
int scan(char program[]) /*扫描器*/
{ /*定义程序可以处理的关键字*/
char*keywords[]={"auto","break","case","char","const","continue",
"default","do","double","else", "enum","extern","float","for",
"goto", "if","int","long","register","return","short","signed",
"sizeof","static","struct","switch","typedef","union","unsigned",
"void", "volatile","while"
};
number=0; flag=0; j=0; ch=program[i++];
/*处理空格与制表符回车*/
while((ch==' ')||(ch=='\n')||(ch== '\t')||(ch=='\r'))
{
if(ch=='\n')
line++;
ch=program[i++];
}
/*处理字母*/
if((ch>='a')&&(ch<='z')||(ch>='A')&&(ch<='Z')||ch=='_')
{
while(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))||((ch>='0')&&(ch<='9'))||ch=='_')
{
words[j++]=ch;
ch=program[i++];
}
words[j++]='\0';
for(k=0;k<32;k++)
if(strcmp(words,keywords[k])==0)
switch(k) //处理相应的字母并生成相应的类号或内码并加到符号表中
{
case 0:
sign=1;flag=1;break; //设置类号与内码的值在下面的程序中用
case 1:
sign=2;flag=1;break;
case 2:
sign=3;flag=1;break;
case 3:
sign=4;flag=1;break;
case 4:
sign=5;flag=1;break;
case 5:
sign=6;flag=1;break;
case 6:
sign=7;flag=1;break;
case 7:
sign=8;flag=1;break;
case 8:
sign=9;flag=1;break;
case 9:
sign=10;flag=1;break;
case 10:
sign=11;flag=1;break;
case 11:
sign=12;flag=1;break;
case 12:
sign=13;flag=1;break;
case 13:
sign=14;flag=1;break;
case 14:
sign=15;flag=1;break;
case 15:
sign=16;flag=1;break;
case 16:
sign=17;flag=1;break;
case 17:
sign=18;flag=1;break;
case 18:
sign=19;flag=1;break;
case 19:
sign=20;flag=1;break;
case 20:
sign=21;flag=1;break;
case 21:
sign=22;flag=1;break;
case 22:
sign=23;flag=1;break;
case 23:
sign=24;flag=1;break;
case 24:
sign=25;flag=1;break;
case 25:
sign=26;flag=1;break;
case 26:
sign=27;flag=1;break;
case 28:
sign=29;flag=1;break;
case 29:
sign=30;flag=1;break;
case 30:
sign=31;flag=1;break;
case 31:
sign=32;flag=1;break;
}
if (flag==0)
{
i--;sign=100;
}
}
/*处理常数*/
else if((ch>='0')&&(ch<='9'))
{
number=0;
sign = -1;
while((ch>='0')&&(ch<='9'))
{
number=number*10+(ch-'0');
ch=program[i++]; //把识别出的常数并加到符号表中
}
if(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))||ch=='_')
{
sign=-1;
do{ //酌情处理
ch=program[i++];
}while(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))||((ch>='0')&&(ch<='9'))||ch=='_');
i--;
return sign;
}
sign=200;i--; //数字的类号设置为200
}
/*处理运算符号*/
else switch(ch)
{
case'=':
words[j++]=ch;
ch=program[i++];
if(ch=='=') // '=='
{
words[j++]=ch;
sign=401;
}
else
{
i--;
sign=402;
}
break;
case'>':
words[j++]=ch;
ch=program[i++];
if(ch=='=') // '>='
{
words[j++]=ch;
sign=403;
}
else
{
i--;
sign=404;
}
break;
case'<':
words[j++]=ch;
ch=program[i++];
if(ch=='=') // '<='
{
words[j++]=ch;
sign=405;
}
else
{
i--;
sign=406;
}
break;
case'!':
words[j++]=ch;
ch=program[i++];
if(ch=='=') // '!='
{
words[j++]=ch;
sign=407;
}
else
{
i--;
sign=408;
}
break;
case'+':
words[j++]=ch;
ch=program[i++];
if(ch=='=') // '+='
{
words[j++]=ch;
sign=409;
}
if(ch=='+') // '++'
{
words[j++]=ch;
sign=410;
}
else
{
i--;
sign=411;
}
break;
case'-':
words[j++]=ch;
ch=program[i++];
if(ch=='=') // '-='
{
words[j++]=ch;
sign=412;
}
else if(ch=='-') // '--'
{
words[j++]=ch;
sign=413;
}
else if(ch=='>')
{
words[j++]=ch;
sign=414;
}
else
{
i--;
sign=415;
}
break;
case'*':
words[j++]=ch;
ch=program[i++];
if(ch=='/') // '*/'
{
words[j++]=ch;
sign=416;
}
else if(ch=='=') // '*='
{
words[j++]=ch;
sign=417;
}
else
{
i--;
sign=418;
}
break;
case'/':
words[j++]=ch;
ch=program[i++];
if(ch=='*' || ch=='/') // '/*' '//'
{
words[j++]=ch;
sign=419;
}
else if(ch=='=') // '/='
{
words[j++]=ch;
sign=420;
}
else
{
i--;
sign=421;
}
break;
case';':
words[j++]=ch;
sign=501;
break;
case'(':
words[j++]=ch;
sign=502;
break;
case')':
words[j++]=ch;
sign=503;
break;
case'[':
words[j++]=ch;
sign=504;
break;
case']':
words[j++]=ch;
sign=505;
break;
case'{':
words[j++]=ch;
sign=506;
break;
case'}':
words[j++]=ch;
sign=507;
break;
case':':
words[j++]=ch;
sign=508;
break;
case'"':
words[j++]=ch;
sign=509;
break;
case'%':
words[j++]=ch;
sign=510;
break;
case',':
words[j++]=ch;
sign=511;
break;
case'#':
words[j++]=ch;
sign=512;
break;
case'^':
words[j++]=ch;
sign=513;
break;
case'?':
words[j++]=ch;
sign=514;
break;
case'.':
words[j++]=ch;
sign=515;
break;
case'|':
words[j++]=ch;
ch=program[i++];
if(ch=='|')
{
words[j++]=ch;
sign=516;
}
else
{
i--;
sign=517;
}
break;
case'&':
words[j++]=ch;
ch=program[i++];
if(ch=='&')
{
words[j++]=ch;
sign=518;
}
else
{
i--;
sign=519;
}
break;
case'\'':
words[j++]=ch;
sign=520;
break;
case'\\':
words[j++]=ch;
ch=program[i++];
if(ch=='0') // '\0'
{
words[j++]=ch;
sign=521;
}
else if(ch=='b') // '\b'
{
words[j++]=ch;
sign=522;
}
else if(ch=='f') // '\f'
{
words[j++]=ch;
sign=523;
}
else if(ch=='n') // '\n'
{
words[j++]=ch;
sign=524;
}
else if(ch=='r') // '\r'
{
words[j++]=ch;
sign=525;
}
else if(ch=='t') // '\t'
{
words[j++]=ch;
sign=526;
}
else if(ch=='d') // '\ddd'
{
words[j++]=ch;
ch=program[i++];
if(ch=='d')
{
words[j++]=ch;
ch=program[i++];
if(ch=='d')
{
words[j++]=ch;
sign=527;
}
}
}
else if(ch=='x') // '\xhh'
{
words[j++]=ch;
ch=program[i++];
if(ch=='h')
{
words[j++]=ch;
ch=program[i++];
if(ch=='h')
{
words[j++]=ch;
sign=528;
}
}
}
break;
default:
sign=-1;
}
words[j]='\0';
if(program[i]=='\0') //程序扫描结束,置sign为0
sign=0;
return sign;
return number;
}
int main(void) /*主函数*/
{
FILE *fp;
char filename[20];
printf("请输入源程序的完整路径和名称:\n");
scanf("%s",filename);
if((fp=fopen(filename,"r"))==NULL)
{
printf("cannot open file\n");
exit(0);
}
i=0;
do
{
ch=fgetc(fp); program[i++]=ch;
}while(!feof(fp));
fclose(fp);
i=0;line=1;
printf("......词法分析开始......\n\n\n");
if((fp=fopen("token.txt","w"))==NULL)
{
printf("cannot creat file 'token'\n");
exit(0);
}
fprintf(fp,"(词素,词素代码,第 行)\n\n");
do
{
sign=scan(program); //对源程序进行扫描
if(sign==200) //常量扫描
{
printf("(词素 %4d , 词素代码为:%2d,在第 %2d 行)\n",number,sign,line);
fprintf(fp," %4d , %2d, %2d \n\n",number,sign,line);
}
else if(sign==-1) //出错信息
{
printf("(CODE %d,error in line %d)\n",sign,line);
fprintf(fp,"Waring:CODE %d,error in line %d\n\n",sign,line);
}
else
{
if(sign==0) //程序结束标志不是词素
break;
printf("(词素 %4s , 词素代码为:%2d 在第 %2d 行)\n",words,sign,line); //输出符号表
fprintf(fp," %4s , %2d, %2d \n\n",words,sign,line);
}
} while(sign!=0);
fclose(fp);
printf("\n\n\n......词法分析结束......\n\n");
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -