📄 scanner.cpp
字号:
{
*Tail=Word[j];
Tail++;
c1++;
}
ENTRY=i+1;
}
}
//取出一个字符
char Getch()
{
int i;
ch=Buffer[column];
if(ch=='\n')//读入下一行
{
for(i=0;i<1000;i++) //清空缓冲区
Buffer[i]='#';
fgets(Buffer,n,fp1);
row++;
column=0;
}
else
{
if(!feof(fp1))//文件还没结束
column++;
else return -1;
}
return ch;
}
//查找标识符
void checksign()
{
int k=0,p=0,j=0;
char *w;
if(c==0)
{
c++;
Tab[0].head=Tail;
Tab[0].len=idlen+1;
fprintf(fp3,"%d\t%d\t_\t_\t_\t_\t\n",c1,Tab[0].len);//fp3指向符号表
for(k=0;k<=idlen;k++)
{*Tail=Word[k];
Tail++;
c1++;
}
Tab[0].type[0]=Tab[0].kind[0]='v';
ENTRY=1;
return;
}
else
{ //查找是否有同名项
for(p=0;p<c;p++)
{
if(Tab[p].type[0]=='v')
{
w=Tab[p].head;
for(j=0;j<=idlen;j++)
{
if(Word[j]==*w)
w++;
else break;
}
}
if(j==idlen+1)
break;
}
if(j==idlen+1)
{
ENTRY=p+1;
return;
}
else
{//没有同名项
while(Tab[p].type[0]!='#')
p++;
c++;
Tab[p].len=idlen+1;
Tab[p].head=Tail;
fprintf(fp3,"%d\t%d\t_\t_\t_\t_\n",c1,Tab[p].len);
Tab[p].type[0]=Tab[p].kind[0]='v';
for(j=0;j<=idlen;j++)
{
*Tail=Word[j];
c1++;
Tail++;
}
ENTRY=p+1;
}
// return;
}
}
//查找是否为关键字
int Checktab()
{
int k=0,i;
bool flag=false;
while(k<33) //种别码关键字最后一个为33
{i=0;
while (Word[i]!='#' && tolower(Word[i])==Simple[k].word[i])
{
i++;
}
if(i==idlen+1 && Simple[k].word[i]=='#' )
{
flag=true;
break;
}
else k++;
}
if(flag==true)
{
for(i=0;i<=idlen;i++)
{
fprintf(fp2,"%c",Word[i]);
}
token.code=Simple[k].kindcode;
token.addr=NULL;
fprintf(fp2,"\t\t(%d\t_)\n",token.code);
return OK;
//break;
}
else return ERROR;
}
//查添符号表
void Lookup()
{
int i;
switch(kind)
{
case 1: checksign();//查找标识符
for(i=0;i<=idlen;i++)
fprintf(fp2,"%c",Word[i]);
token.code=34;
token.addr=ENTRY;
fprintf(fp2,"\t\t(%d\t%d)\n",token.code,token.addr);
break;
case 2: checknum();break;//查找数字
case 3: checkch();//查找字符常数
for(i=0;i<=idlen;i++)
fprintf(fp2,"%c",Word[i]);
token.code=37; //字符常数种别码为37
token.addr=ENTRY; //entry
fprintf(fp2,"\t\t(%d\t%d)\n",token.code,token.addr);
break;
default:break;
}
}
//识别标识符
void RECOGID()
{
int i,k=0;
for(i=0;i<80;i++)//初始化
Word[i]='#';
idlen=0;
Word[idlen]=ch; //ch字符常量或变量
Getch();
while(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z'||ch>='0'&&ch<='9'&&ch!='\n')
{
idlen++;
Word[idlen]=ch;
Getch();
if(ch=='\n')
break;
}
if(ch!='\n')
column--;
if(Checktab()==ERROR)//如果不是关键字查添符号表
{
kind=1;
Lookup();
}
}
//识别数字
void RECODIG(){
int j=0,count=0,a[10],k,x1=0,column1=0;
for(k=0;k<80;k++)
Num[k]=0;
column1=column;
numlen=0;
Num[numlen]=ch-48;//将字符的ASCII码转化为数字
Getch();
while(ch>='0'&&ch<='9'||ch=='.'){
numlen++;
if(ch=='.'){
Num[numlen]=ch;
count++;
a[j]=numlen;
j++;}//if
else
Num[numlen]=ch-48;
Getch();
}//while
if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')//若出现字母,则打印错误信息
fprintf(fp5,"%d行%d列:出现非数字的字符\n",row,(column-1));
column--;
kind=2;
if(count==0){ //若是整数
token.code=35;
Lookup();
fprintf(fp2,"%d",int(num1));
token.addr=ENTRY;
fprintf(fp2,"\t\t(%d\t%d)\n",token.code,token.addr);
return;
}//if
else{//若是实数
if(count==1){
token.code=36;
Lookup();
fprintf(fp2,"%f",num1);
token.addr=ENTRY;
fprintf(fp2,"\t(%d\t%d)\n",token.code,token.addr);
return;
}//if
else{//若出现多个小数点,则打印错误信息
fprintf(fp5,"%d 行 %d 列:有多余小数点\n",row,(column1+a[1]-1));
for(k=0;k<=numlen;k++){
if(Num[k]==46)
fprintf(fp2,".");
else
fprintf(fp2,"%d",Num[k]);
}//for
//处理错误数字
token.code=36;
Lookup();
token.addr=ENTRY;
fprintf(fp2,"\t(%d\t%d)\n",token.code,token.addr);
T=false;
return;
}//else1;
}//else2;
}//
//识别注释
void HANDLECOM()
{
char ch1;
ch1=ch;
Getch();
if(ch!='*') //是除号
{
column--;
token.code=48;
token.addr=NULL;
fprintf(fp2,"%c",ch1);
fprintf(fp2,"\t\t(%d\t_)\n",token.code);
return;
}
else //是注释
token.code =-1;
token.addr =NULL;
Getch();
while(ch!='\n')
{
ch1=ch;
Getch();
if(ch1=='*'&&ch=='/')
token.code =0;
//break;
}
if(token.code !=0)
{
fprintf(fp5,"%d 行:注释未完\n",row-1);
T=false;
//return;
}
token.code =0;
token.addr =NULL;
}
//识别字符常数
void RECOGSTR()
{
int i;
for(i=0;i<80;i++)//初始化
{
Word[i]='#';
}
idlen=-1;
while(Getch()!=39) //39 为ASCii “‘”,字符常数为‘a’
{ idlen++;
Word[idlen]=ch;
if(idlen+1>=80)
{
fprintf(fp5,"%d行:字符常数没有封闭\n",row-1);
T=false;
column--;
break;
}
}
kind=3;
Lookup();
}
//识别其它界符
void RECOGDEL()
{
bool flag=false;//标记是否为双界符
switch(ch)
{
case'+':token.code=43;token.addr=NULL;break;
case'-':token.code=45;token.addr=NULL;break;
case'*':token.code=41;token.addr=NULL;break;
case')':token.code=40;token.addr=NULL;break;
case'(':token.code=39;token.addr=NULL;break;
case',':token.code=44;token.addr=NULL;break;
case'[':token.code=59;token.addr=NULL;break;
case']':token.code=60;token.addr=NULL;break;
case'=':token.code=56;token.addr=NULL;break;
case';':token.code =52;token.addr=NULL;break;
case'.':
fprintf(fp2,"%c",ch);
flag=true;
Getch();
if(ch=='.')
{
token.code=47;
token.addr=NULL;
fprintf(fp2,"%c",ch);
}
else
{
column--;token.code=46;
token.addr=NULL;
}
break;
case':':
fprintf(fp2,"%c",ch);
flag=true;
Getch();
if(ch=='=')
{
token.code=51;
token.addr=NULL;
fprintf(fp2,"%c",ch);
}
else
{
column--;
token.code=50;
token.addr=NULL;
}
break;
case'<':
fprintf(fp2,"%c",ch);
flag=true;
Getch();
if(ch=='=')
{
token.code=54;
token.addr=NULL;
fprintf(fp2,"%c",ch);
}
else if(ch=='>')
{
token.code=55;
token.addr=NULL;
fprintf(fp2,"%c",ch);
}
else
{
column--;
token.code=53;
token.addr=NULL;
}
break;
case '>':
fprintf(fp2,"%c",ch);
flag=true;
Getch();
if(ch=='=')
{
token.code=58;token.addr=NULL;
fprintf(fp2,"%c",ch);
}
else
{
column--;
token.code=57;token.addr=NULL;
}
break;
default:if(ch==' ')
{//若是空格,继续读入
do Getch();
while (ch==' ');
column--;
return;
}
else
{
if(ch=='\n')
return;
else
{
fprintf(fp5,"%d 行 %d 列:有非法字符\n",row,column);
T=false;
return;
}
}
// break;
}
if(flag==false)
{
fprintf(fp2,"%c",ch);
}
fprintf(fp2,"\t\t(%d\t_)\n",token.code);
//break;
}
//单词分类模块
void Sort()
{
if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')
RECOGID();//识别标识符
else if(ch>='0'&&ch<='9')
RECODIG();//识别数字
else if(ch=='/')
HANDLECOM();//识别注释
else if(ch==39)
RECOGSTR();//识别字符常数
else
RECOGDEL();//识别其它界符
}
void main()
{
int i;
char file[20];
printf("请输入源文件名,包括后缀名:\n");
scanf("%s",&file);
if((fp1=fopen(file,"r"))==NULL)
{
printf("不能打开file文件\n");
return;
}
if((fp2=fopen("token串.txt","w+"))==NULL)
{
printf("不能建立token串文件");
return;
}
if((fp3=fopen("符号表.txt","w+"))==NULL)
{
printf("不能建立符号表文件");
return ;
}
if((fp4=fopen("源程序清单.txt","w+"))==NULL)
{
printf("不能建立字符串表");
return;
}
if((fp5=fopen("错误信息.txt", "w+"))==NULL)
{
printf("不能建立错误信息表");
return ;
}
fprintf(fp2,"\t\t\t\ttoken串\t\t\t\t\n\n\n");
fprintf(fp3,"head\tlength\ttype\tkind\tval\taddr\n");
unit();
fgets(Buffer,n,fp1);//从文件中读入一行到缓冲区
row++;
while(Getch()!=-1)
Sort();
fprintf(fp3,"\n\n\n");
fprintf(fp3,"\t\t\t字符串表\n");
for(i=0;String[i]!='#';i++)
fprintf(fp3,"%c",String[i]);
fclose(fp1);
fclose(fp2);
fclose(fp3);
fclose(fp4);
fclose(fp5);
if (T==true)
{
printf("\n\n\n");
printf("恭喜你,你的程序没有出错,请查看符号表文件,字符串表文件,token串文件\n");
}
else
{
printf("\n\n\n");
printf("你的程序中有错误,请查看错误信息表\n");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -