学习历程——词法分析器

从文件输入,保存到文件,结构体存放标识符和常数
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <ctype.h>
typedef struct
{
int typenum;//内码值
char *word;
}WORD;
typedef struct
{
int typenum;//内码值
char word[20];
}WORDR;
char input[200];//存放输入的字符
char token[200]="";//存放构成单词字符的字符串
int p_input;//input输入字符的位数
int p_token;//token中存放的字符个数
char ch;//存放每次读取的字符
char *key[]={"if","int","else","switch","case",_KEY_WORD_END};
WORD *analyse();
int rf=0,cot=0;
void inputs(){//读取字符
 int i=0;
FILE *fp;
if ((fp=fopen("d:\\input.txt","r"))==NULL)
{
printf("Can not open the file\n");
exit(0);
}
while(!feof(fp))//判断源文件是否读取结束
{
input[i]=fgetc(fp);
i++;
}
input[i-1]=' ';
fclose(fp);
}
/*void save(char word){
FILE *pp;
if ((pp=fopen("d:\\save.txt","w"))==NULL)
{
printf("Can not open the file\n");
exit(0);
}
fprintf(pp,"%s",&word);
fclose(pp);
//保存符号到文件
}*/
///////////////////////////////////////////////////////////
int main()
{
 int over=1;FILE *pp;WORDR rfword[20];WORDR cotword[20];int j;
 WORD *oneword=malloc(sizeof(WORD));//分配内存空间,oneword结构体类型的指针
 if ((pp=fopen("d:\\save.txt","w"))==NULL)
     {
      printf("Can not open the file\n");
      exit(0);
     }
 printf("Enter Your words:");
 inputs();//文件读取
 p_input=0;
 printf("Your words:\n%s\n",input);
 while (over<1000&&over!=-1)
  {
   oneword=analyse();//调用analyse函数
   if(oneword->typenum<1000)
    {
    if(oneword->typenum<6)
    {
     printf("<%d,%s,关键字>",oneword->typenum,oneword->word);
     fprintf(pp,"%d,%s\n",oneword->typenum,oneword->word);
    }
    else if(oneword->typenum==6)
    {
     for(j=0;j<rf;j++)
     {
      if(oneword->typenum==rfword[j].typenum)
       break;
     }
     if(j==rf)
     {
      rfword[rf].typenum=rf;strcpy(rfword[rf].word,oneword->word);//保存到标识符表中
      printf("<%d,%s,标识符>",oneword->typenum,oneword->word);//显示到屏幕上
      fprintf(pp,"%d,%s\n",oneword->typenum,oneword->word);//保存到文件
      rf++;
     }
     
     
    }
    else if(oneword->typenum==7)
    {
      for(j=0;j<rf;j++)
     {
      if(oneword->typenum==rfword[j].typenum)
       break;
     }
     if(j==rf)
     {
      cotword[cot].typenum=cot;strcpy(cotword[cot].word,oneword->word);
      printf("<%d,%s,常数>",oneword->typenum,oneword->word);
      fprintf(pp,"%d,%s\n",oneword->typenum,oneword->word);
      cot++;
     }
    }
    else if(oneword->typenum>7)
    {
     printf("<%d,%s,界符或运算符>",oneword->typenum,oneword->word);
     fprintf(pp,"%d,%s\n",oneword->typenum,oneword->word);//保存符号到文件
    }
    }      //strcmp(&word,oneword->word);
     //save(word);
   over=oneword->typenum;
  }
 fclose(pp);
 for(j=0;j<rf;j++)
 {
  printf("<%d,%s,标识符>",rfword[j].typenum,rfword[j].word);
 }
 printf("\n");
  for(j=0;j<cot;j++)
 {
  printf("<%d,%s,常数>",cotword[j].typenum,cotword[j].word);
 }
 system("pause");
 return 0;
}
//*********************
char m_getch(){
ch=input[p_input];
p_input=p_input+1;
return(ch);
}//得到字符
void getbc(){
while(isspace(ch)){
ch=input[p_input];
p_input=p_input+1;
}
}//去空格

void concat(){
token[p_token]=ch;
p_token=p_token+1;
token[p_token]='\0';
}//连接单词
int letter(){
if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')
return 1;
else return 0;
}//判断字母
int digit(){
if(ch>='0'&&ch<='9')
return 1;
else
return 0;
}//判断数字
int reserve(){
int i=0;
while(strcmp(key[i],_KEY_WORD_END)){//将
  if(!strcmp(key[i],token))
   {
    return i+1;
   }
  i++;
}
return 6;
}//找关键字
void retract(){
p_input-=1;
}//回退字符
//*****************************************************************************
WORD *analyse()
{
 int p_key=0;
 WORD *myword=malloc(sizeof(WORD));
myword->typenum=1;
myword->word="";
/*
WORD *keyword=(WORD *)malloc(5,sizeof(WORD));
for(int i=0;i<5;i++)
{
keyword[i].typenum=(int *)calloc(1,sizeof(int));
keyword[i].word=(char *)calloc(1,sizeof(char));
}
WORD *rfword[20]=malloc(sizeof(WORD));
int p_rf=0;
rfword[p_rf]->typenum=1;
rfword[p_rf]->word="";
WORD *cotword=malloc(sizeof(WORD));
int p_cot=0;
cotword[p_cot]->typenum=1;
cotword[p_cot]->word="";
*/
p_token=0;
m_getch();
getbc();
if(letter())
 {
  while(letter()||digit())
   {
    concat();
    m_getch();
    //getbc();
   }
 retract();
 myword->typenum=reserve();//判断是标识符还是关键字
 myword->word=token;
 printf("\n");
 return(myword);
}
else if(digit())
{
while(digit())
{
concat();
m_getch();
getbc();
}
retract();
myword->typenum=7;//常数
myword->word=token;
printf("\n");
return(myword);
}
else switch(ch)
{
case'=':
 m_getch();
 if(ch=='=')
{
myword->typenum=8;
myword->word="==";
printf("\n");
return(myword);
}
retract();
myword->typenum=9;
myword->word="=";
printf("\n");
return(myword);
break;
case'+':
myword->typenum=10;
myword->word="+";
printf("\n");
return(myword);
break;
case'-':
myword->typenum=11;
myword->word="-";
printf("\n");
return(myword);
break;
case'*':
myword->typenum=12;
myword->word="*";
printf("\n");
return(myword);
break;
case'/':
myword->typenum=13;
myword->word="/";
printf("\n");
return(myword);
break;
case '(' :
myword->typenum=14;
myword->word="(";
printf("\n");
return(myword);
break;
case ')' :
myword->typenum=15;
myword->word=")";
printf("\n");
return(myword);
break;
case'[':
myword->typenum=16;
myword->word="[";
printf("\n");
return(myword);
break;
case']':
myword->typenum=17;
myword->word="]";
printf("\n");
return(myword);
break;
case'{':
myword->typenum=18;
myword->word="{";
printf("\n");
return(myword);
break;
case'}':
myword->typenum=19;
myword->word="}";
printf("\n");
return(myword);
break;
case',':
myword->typenum=20;
myword->word=",";
printf("\n");
return(myword);
break;
case':':
myword->typenum=21;
myword->word=":";
printf("\n");
return(myword);
break;
case';':
myword->typenum=22;myword->word=";";
printf("\n");return(myword);
break;
case'>':
 m_getch();
 if(ch=='=')
{
myword->typenum=23;myword->word=">=";
printf("\n");return(myword);
}retract();
myword->typenum=24;myword->word=">";
printf("\n");return(myword);
break;
case'<':
 m_getch();
 if(ch=='=')
  {
   myword->typenum=25;myword->word="<=";
   printf("\n");return(myword);
  }
 retract();
 myword->typenum=26;
 myword->word="<";
 printf("\n");return(myword);
 break;
case'!':
 m_getch();
 if(ch=='=')
{
myword->typenum=27;
myword->word="!=";
printf("\n");
return(myword);
}retract();
myword->typenum=-1;myword->word="ERROR";
printf("\n");return(myword);
break;
case'\0':
myword->typenum=1000;
myword->word="OVER";
printf("\n");return(myword);
break;
case'#':
myword->typenum=28;myword->word="#";
printf("\n");return(myword);
break;
case'"':
myword->typenum=29;myword->word="\"";
printf("\n");return(myword);break;
case'%':
myword->typenum=30;myword->word="%";
printf("\n");return(myword);break;
default:
myword->typenum=-1;myword->word="ERROR";
printf("\n");
return(myword);}}

猜你喜欢

转载自blog.csdn.net/qq_37423714/article/details/80271020