📄 cpp.cpp
字号:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//modify by webboyvc
#define LENGTH 61
#define N 100
/********************/
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 *SourceFout;
FILE *TokenFout;
FILE *SymbleFout;
KeyWord key[LENGTH];
token CurrentToken;
symble CurrentSimble;
symble SymbleList[N];
/***************************************************/
void Scanner();
void ScannerInit();
void IsAlpha();
void IsNumber();
void IsAnotation();
void IsChar();
void IsOther();
void OutPut();
void Error(int a);
int WordHave();
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("*S语言词法分析器\n");
printf("******************\n");
printf("输入源文件名");
for(;;)
{
scanf("%c",&filename[i]);
if(filename[i]==10)
break;
i++;
}
filename[i]='\0';
if((SourceFin=fopen(filename,"rt"))==NULL)
{
printf("无法打开文件%s.\n",filename);
exit(1);
}
if((TokenFout=fopen("token.txt","wt+"))==NULL)
{
printf("无法打开文件token.txt\n");
exit(1);
}
fprintf(TokenFout," label name code addr\n");
if((SymbleFout=fopen("symble.txt","wt+"))==NULL)
{
printf("无法打开文件symble.txt\n");
exit(1);
}
fprintf(SymbleFout," number type name \n");
ch=fgetc(SourceFin);
while(ch!=EOF)// read symbole ; became no end
{
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("ni.txt","rt"))==NULL)
{
printf("cannot open ni.txt.\n");
exit(1);
}
else{
for(i=1;i<60;i++)
for(k=1;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=52;
CurrentToken.addr=addr_count++;
CurrentToken.label=label_count++;
if(flag)
{
ch1=fgetc(SourceFin);
if((ch1>47)&&(ch1<58))
CurrentToken.name[k++]=ch;
else
Error(2);
ch=ch1;
while((ch>47)&&(ch<58))
{
CurrentToken.name[k++]=ch;
ch=fgetc(SourceFin);
}
CurrentToken.code=53;
if(ch=='.')
{
Error(2);
ch=fgetc(SourceFin);
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,h;
h=0;
i=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=51;
CurrentToken.addr=addr_count++;
}
CurrentToken.label=addr_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=63;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
}
/***p200*************字符串处理*******************/
void IsChar()
{
int i=0;
for(;;)
{
ch=fgetc(SourceFin);
CurrentToken.code=54;
if(ch!='\'')
CurrentToken.name[i++]=ch;
else
break;
}
CurrentToken.addr=addr_count++;
CurrentToken.label=label_count++;
OutPut();
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=56;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case ')':
CurrentToken.name[0]=')';
CurrentToken.code=57;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '*':
CurrentToken.name[0]='*';
CurrentToken.code=58;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '+':
CurrentToken.name[0]='+';
CurrentToken.code=59;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case ',':
CurrentToken.name[0]=',';
CurrentToken.code=61;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '-':
CurrentToken.name[0]='-';
CurrentToken.code=60;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '.':
CurrentToken.name[0]='.';
CurrentToken.code=62;
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=64;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
else
{
CurrentToken.name[0]=':';
CurrentToken.name[1]='=';
CurrentToken.code=65;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
}
break;
case ';':CurrentToken.name[0]=';';
CurrentToken.code=66;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);//you forget fgetc() :p
break;
case '<':
ch1=fgetc(SourceFin);
if(ch=='=')
{
CurrentToken.name[0]='<';
CurrentToken.name[1]='=';
CurrentToken.code=67;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch1=fgetc(SourceFin);
}
else
{
if(ch1=='>'){
CurrentToken.name[0]='<';
CurrentToken.name[1]='>';
CurrentToken.code=68;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch1=fgetc(SourceFin);
}
else{
CurrentToken.name[0]='<';
CurrentToken.code=69;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();}
}
ch=ch1;
break;
case'=':CurrentToken.name[0]='=';
CurrentToken.code=70;
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=71;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch1=fgetc(SourceFin);
}
else{
CurrentToken.name[0]='>';
CurrentToken.code=72;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
ch=ch1;
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;//modfiyed by webboyvc s--->3 :P
if((CurrentToken.code==51)||(CurrentToken.code=54)||(CurrentToken.code==52)||(CurrentToken.code==53))
{
CurrentSimble.number=CurrentToken.addr;
CurrentSimble.type=CurrentToken.code;
strcpy(CurrentSimble.name,CurrentToken.name);
flag=WordHave();
if(((CurrentToken.code==51)&&(flag==1))||(CurrentToken.code==54)||(CurrentToken.code==52)||(CurrentToken.code==53))
fprintf(SymbleFout,"%4d %4d %s\n",CurrentSimble.number,CurrentSimble.type,CurrentSimble.name);
}
for(;;)
if(CurrentToken.name[i++]=='\0')//modified by webboyvc
break;
fprintf(TokenFout,"%3d %s",CurrentToken.label,CurrentToken.name);
printf("%4d %s",CurrentToken.label,CurrentToken.name);
for(k=20-i;k>0;k--)
{
fprintf(TokenFout," ");
printf(" ");
}
fprintf(TokenFout,"%3d %3d\n",CurrentToken.code,CurrentToken.addr);//modfiyed by webboyvc s--->3 :P
printf("%4d %4d\n",CurrentToken.code,CurrentToken.addr);
}
void Error(int a)
{
error_count++;
switch(a){
case 1: printf("error %2d 非法字符于 %3d 行.\n",
error_count,LineOfPro+1);break;
case 2: printf("error %2d 实常数出错于 %sd 行.\n",
error_count,LineOfPro+1);break;
case 3: printf("error %2d 没有匹配的注释符 '*/' \n",error_count);break;
case 4: printf("error %2d 非正常结束!\n",error_count);break;
default:
break;
}
return;
}
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 + -