📄 my.cpp
字号:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define LENGTH 61
#define N 100
void Scanner();
void ScannerInit();
void IsAlpha();
void IsNumber();
void IsAnotation();
void IsChar();
void IsOther();
void OutPut();
void Error(int a);
int WordHave();
typedef struct token
{int label;
char name[30];
int code;
int addr;
}token;
typedef struct KeyWord
{char name[30];
int code;
}KeyWord;
typedef struct symble
{int number;
int type;
char name[30];
}symble;
char ch;
int var_count;
int error_count;
int label_count;
int code_count;
int addr_count;
int LineOfPro;
char filename[30];
FILE *KeyFin;
FILE *SourceFin;
FILE *TokenFout;
FILE *SymbleFout;
KeyWord key[LENGTH];
token CurrentToken;
symble CurrentSimble;
symble SymbleList[N];
int strcmp(char *s,char *t)
{for(;*s==*t;s++,t++)
if(*s==0)
return 0;
return 1;
}
int main()
{
int i=0,j=0;
code_count=0;
LineOfPro=0;
var_count=0;
addr_count=1;
label_count=1;
for(i=0;i<N;i++){SymbleList[i].number=0;
SymbleList[i].type=0;
for(j=0;j<30;j++)SymbleList[i].name[j]='\0';
}
Scanner();
return 0;
}
void Scanner()
{
int i=0;
error_count=0;
ScannerInit();
printf(" -----------------------------------\n");
printf(" | 词法分析器 |\n");
printf(" -----------------------------------\n");
printf("输入源文件名:\n");
for(;;){scanf("%c",&filename[i]);
if(filename[i]==10)
break;
i++;
}
filename[i]='\0';
if((SourceFin=fopen(filename,"r"))==NULL)
{printf("the source can not open!%s.\n",filename);
exit(1);
}
if((TokenFout=fopen("token.txt","w+"))==NULL)
{printf("token.txt can not open!");
exit(1);
}
if((SymbleFout=fopen("symble.txt","w+"))==NULL)
{printf("symble.txt can not open!");
exit(1);
}
ch=fgetc(SourceFin);
while(ch!=EOF)
{ for(i=0;i<30;i++)CurrentToken.name[i]='\0';
if((ch>47)&&(ch<58))IsNumber();
else{
if(((ch>64)&&(ch<90))||((ch>96)&&(ch<123))||ch=='_')IsAlpha();
else {if(ch=='/')IsAnotation();
else if(ch=='\'')IsChar();
else IsOther();
}
}
}
fclose(SourceFin);
fclose(TokenFout);
fclose(SymbleFout);
printf("分析完毕。\n");
}
void ScannerInit()
{
int i=1;
int k=0;
if((KeyFin=fopen("source.txt","r"))==NULL)
{printf("ni.txt cannot open.\n");
exit(1);
}
for(i=0;i<60;i++)for(k=0;k<30;k++)key[i].name[k]='\0';
for(i=1;i<60;i++){fscanf(KeyFin,"%s%d",key[i].name,&key[i].code);
fclose(KeyFin);
}
}
void IsNumber()
{ int k=0;
int flag=0;
char ch1;
while((ch>47)&&(ch<58))
{ CurrentToken.name[k++]=ch;
ch=fgetc(SourceFin);
if(ch=='.'){flag=1;break;}
}
CurrentToken.code=28;
CurrentToken.addr=addr_count++;
CurrentToken.label=label_count++;
if(flag)
{ ch1=fgetc(SourceFin);
if((ch1>47)&&(ch<58)) CurrentToken.name[k++]=ch;
else Error(2);
ch=ch1;
while((ch>47)&&(ch<58))
{ CurrentToken.name[k++]=ch;
ch=fgetc(SourceFin);
}
CurrentToken.code=29;
if(ch=='.')
{Error(2);
while((ch>47)&&(ch<58))ch=fgetc(SourceFin);
}
}
if(((ch>64)&&(ch<90))||((ch>96)&&(ch<123)))
{Error(2);
while(((ch>64)&&(ch<90))||((ch>96)&&(ch<123)))
{ ch=fgetc(SourceFin);
while((ch>47)&&(ch<58))
ch=fgetc(SourceFin);
}
}
OutPut();
}
void IsAlpha()
{ int i=0,h=0;
while(((ch>64)&&(ch<90))||((ch>96)&&(ch<123))||ch=='_')
{ CurrentToken.name[i++]=ch;
ch=fgetc(SourceFin);
}
for(i=1;i<LENGTH;i++)
{ h=strcmp(CurrentToken.name,key[i].name);
if(!h)break;
}
if(!h){ CurrentToken.code=key[i].code;
CurrentToken.addr=-1;
}
else{ CurrentToken.code=27;
CurrentToken.addr=addr_count++;
}
CurrentToken.label=label_count++;
OutPut();
}
void IsAnotation()
{char ch1;
ch1=ch;
ch=fgetc(SourceFin);
if(ch=='*')for(;;){ ch=fgetc(SourceFin);
if(ch==EOF){Error(3);break;}
if(ch=='*')
{ ch1=ch;ch=fgetc(SourceFin);
if(ch=='/'){ ch=fgetc(SourceFin);break;}
}
}
else{ CurrentToken.name[0]='/';
CurrentToken.code=39;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
}
void IsChar()
{ int i=0;
for(;;){ ch=fgetc(SourceFin);
CurrentToken.code=30;
if(ch!='\'')CurrentToken.name[i++]=ch;
else break;
}
CurrentToken.addr=addr_count++;
CurrentToken.label=label_count++;
ch=fgetc(SourceFin);
}
void IsOther()
{ char ch1;
int i;
for(i=0;i<30;i++)
CurrentToken.name[i]='\0';
switch(ch){ case'(':CurrentToken.name[0]='(';
CurrentToken.code=32;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case')':CurrentToken.name[0]=')';
CurrentToken.code=33;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case'*':CurrentToken.name[0]='*';
CurrentToken.code=34;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case'+':CurrentToken.name[0]='+';
CurrentToken.code=35;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case',':CurrentToken.name[0]=',';
CurrentToken.code=37;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case'_':CurrentToken.name[0]='_';
CurrentToken.code=36;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case'.':CurrentToken.name[0]='.';
CurrentToken.code=38;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case':':ch1=ch;
ch=fgetc(SourceFin);
if(ch!='='){ CurrentToken.name[0]=':';
CurrentToken.code=40;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
else {CurrentToken.name[0]=':';
CurrentToken.name[1]='=';
CurrentToken.code=41;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
}
break;
case';':CurrentToken.name[0]=';';
CurrentToken.code=42;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case'<':ch1=fgetc(SourceFin);
if(ch1=='='){ CurrentToken.name[0]='<';
CurrentToken.name[1]='=';
CurrentToken.code=44;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch1=fgetc(SourceFin);
}
else{ if(ch1=='>')
{ CurrentToken.name[0]='<';
CurrentToken.name[1]='>';
CurrentToken.addr=45;
CurrentToken.label=label_count++;
OutPut();
ch1=fgetc(SourceFin);
}
else{ CurrentToken.name[0]='<';
CurrentToken.code=43;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
}
ch=ch1;
break;
case'=':CurrentToken.name[0]='=';
CurrentToken.code=46;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case'>':ch1=fgetc(SourceFin);
if(ch=='='){ CurrentToken.name[0]='>';
CurrentToken.name[1]='=';
CurrentToken.code=48;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch1=fgetc(SourceFin);
}
else{ CurrentToken.name[0]='>';
CurrentToken.code=47;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
ch=ch1;
break;
case'!':CurrentToken.name[0]='!';
CurrentToken.code=49;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case'%':CurrentToken.name[0]='%';
CurrentToken.code=50;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case'{':CurrentToken.name[0]='{';
CurrentToken.code=51;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case'}':CurrentToken.name[0]='}';
CurrentToken.code=52;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case'-':CurrentToken.name[0]='-';
CurrentToken.code=53;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case 10:LineOfPro++;
ch=fgetc(SourceFin);
break;
case 13:LineOfPro++;
ch=fgetc(SourceFin);
break;
case' ':ch=fgetc(SourceFin);
break;
case EOF:Error(4);
break;
default:Error(1);
ch=fgetc(SourceFin);
break;
}
}
void OutPut()
{ int flag,i=0;
int k;
if((CurrentToken.code==27)||(CurrentToken.code==30)||(CurrentToken.code==28)||(CurrentToken.code==29))
{ CurrentSimble.number=CurrentToken.addr;
CurrentSimble.type=CurrentToken.code;
strcpy(CurrentSimble.name,CurrentToken.name);
flag=WordHave();
if(((CurrentToken.code==27)&&(flag==1))||(CurrentToken.code==30)||(CurrentToken.code==28)||(CurrentToken.code==29))
fprintf(SymbleFout,"%3d %3d %s\n",CurrentSimble.number,CurrentSimble.type,CurrentSimble.name);
}
for(;;)if(CurrentToken.name[i++]=='\0')break;
fprintf(TokenFout,"%3d %s",CurrentToken.label,CurrentToken.name);
printf("%3d %s",CurrentToken.label,CurrentToken.name);
for(k=20-i;k>0;k--) { fprintf(TokenFout,"");
printf("");
}
fprintf(TokenFout,"%3d %3d\n",CurrentToken.code,CurrentToken.addr);
printf("%3d %3d\n",CurrentToken.code,CurrentToken.addr);
}
void Error(int a)
{ error_count++;
switch(a){ case 1: printf("error %2d 非法字符在 %3d行.\n",error_count,LineOfPro++);
break;
case 2: printf("error %2d实常数出错在 %3d行.\n",error_count,LineOfPro++);
break;
case 3: printf("error %2d没有匹配的注释符‘*/’.\n",error_count);
break;
case 4: printf("error %2d非正常结束!\n",error_count);
break;
default: break;
}
}
int WordHave()
{int flag,i=0;
for(i=0;i<var_count;i++)
{ flag=strcmp(CurrentSimble.name,SymbleList[i].name);
if(flag==0){ CurrentToken.addr=SymbleList[i].number;
return 0;
}
}
SymbleList[var_count].number=CurrentToken.addr;
SymbleList[var_count].type=CurrentToken.code;
strcpy(SymbleList[var_count].name,CurrentToken.name);
var_count++;
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -