?? scanner.cpp
字號:
/***************************************************/
#include "scanner.h"
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);
}
printf("打開文件%s.\n",filename);
if((TokenFout=fopen("token.txt","wt+"))==NULL)
{
printf("無法打開文件token.txt\n");
exit(1);
}
printf("打開文件token.txt\n");
fprintf(TokenFout," label name code addr\n");
if((SymbleFout=fopen("symble.txt","wt+"))==NULL)
{
printf("無法打開文件symble.txt\n");
exit(1);
}
printf("打開文件symble.txt\n");
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("dm.txt","rt"))==NULL)
{
printf("cannot open dm.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=35;
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=36;
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=34;
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=48;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
}
/***p200*************字符串處理*******************/
void IsChar()
{
int i=0;
for(;;)
{
ch=fgetc(SourceFin);
CurrentToken.code=37;
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=39;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case ')':
CurrentToken.name[0]=')';
CurrentToken.code=40;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '*':
CurrentToken.name[0]='*';
CurrentToken.code=41;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '+':
CurrentToken.name[0]='+';
CurrentToken.code=43;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case ',':
CurrentToken.name[0]=',';
CurrentToken.code=44;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '-':
CurrentToken.name[0]='-';
CurrentToken.code=45;
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=47;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch1=fgetc(SourceFin);
}
else{
CurrentToken.name[0]='.';
CurrentToken.code=46;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
ch=ch1;
break;
case ':':
ch1=ch;
ch=fgetc(SourceFin);
if(ch!='=')
{
CurrentToken.name[0]=':';
CurrentToken.code=50;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
else
{
CurrentToken.name[0]=':';
CurrentToken.name[1]='=';
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);//you forget fgetc() :p
break;
case '<':
ch1=fgetc(SourceFin);
if(ch1=='=')
{
CurrentToken.name[0]='<';
CurrentToken.name[1]='=';
CurrentToken.code=54;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch1=fgetc(SourceFin);
}
else
{
if(ch1=='>'){
CurrentToken.name[0]='<';
CurrentToken.name[1]='>';
CurrentToken.code=55;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch1=fgetc(SourceFin);
}
else{
CurrentToken.name[0]='<';
CurrentToken.code=53;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();}
}
ch=ch1;
break;
case'=':CurrentToken.name[0]='=';
CurrentToken.code=56;
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=58;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch1=fgetc(SourceFin);
}
else{
CurrentToken.name[0]='>';
CurrentToken.code=57;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
ch=ch1;
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=60;
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;//modfiyed by webboyvc s--->3 :P
if((CurrentToken.code==34)||(CurrentToken.code=37)||(CurrentToken.code==35)||(CurrentToken.code==36))
{
CurrentSimble.number=CurrentToken.addr;
CurrentSimble.type=CurrentToken.code;
strcpy(CurrentSimble.name,CurrentToken.name);
flag=WordHave();
if(((CurrentToken.code==34)&&(flag==1))||(CurrentToken.code==37)||(CurrentToken.code==35)||(CurrentToken.code==36))
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 + -