⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 词法分析器.cpp

📁 词法分析器 自己写的 功能都可以实现 编译原理的实验 希望对大家有所帮助
💻 CPP
字号:
#include<iostream.h>
#include<fstream.h>
#include<string.h>
#include<stdlib.h>

#define MAXSIZE1 14       //定义保留字数目
#define MAXSIZE2 20
char end;                 //结尾判断标志
char line[100];           // 存储每次从源文件中读取的一行
char spelling[MAXSIZE2];  //记录正在读取字符的缓冲区
char *pline;              //行缓冲区指针
char ch='\0';             //ch的当前值为开始读文件的条件
int linenum=0;            //记录源文件行数
int misnum=0;              //记录错误数
int slength=0;               //标识符表记录数
int nlength=0;              //常数表记录数
int rlength=0;              //分析结果缓冲区记录数
ifstream openFile;          //定义打开文件类
ofstream saveFile;          //定义结果文件类
char *key[MAXSIZE1]={"int","char","float","void","const","for","if","else","then","which","switch","break","begin","end"};


typedef struct           //标识符表
{
  char name[MAXSIZE2];
  int type;
  char *address;
}signword;
signword sign[100];

typedef struct           //常数表
{
  char name[MAXSIZE2];
  int value;
}numword;
numword number[100];

typedef struct          //词法分析结果缓冲区结构
{
  char sig[MAXSIZE2];
  char val[MAXSIZE2];
}buffer;
buffer buf[1000];




                 
/*************初始化函数***************/
void init()       
{ 
  char c[2]="-";
  for(int i=0;i<1000;i++)
  {
    strcpy(buf[i].val,c);
  }
}

/*************从文件中读出一行放入缓冲区line[]中********************************/
void readline()
{
  char ch1;
  pline=line;         //将指针指向缓冲区的起始位置
  openFile.get(ch1);
  end=ch1;
  while(ch1!='\n'&&end!=EOF)
  {
    *pline=ch1;
    pline++;
    openFile.get(ch1);
  }
  *pline='\0';
  pline=line;
}

/***********************从缓冲区中读一个字符*********************************/
void readch()
{
  if(ch=='\0')
  {
    readline();
    linenum++;
  }
  ch=*pline;
  pline++;
}

/********************保留字查找函数******************************/
int keyfind(char arr[])
{
  int s=0,i=0;
  while((s==0)&&(i<MAXSIZE1))
  {
    if(!strcmp(arr,key[i])) s=1;
    i++;
  }
  if(s==1) return (i-1);
  return -1;
}


/******************识别保留字和标识符函数**********************************/
void isalpha()
{  
  int k=0,s=0,i=0;
  do
  {
    spelling[k]=ch;
    k++;
    readch();
  }while(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))||((ch>='0')&&(ch<='9')));
  pline--;                     //缓冲区指针减退一步
  spelling[k]='\0';
  int n=keyfind(spelling);
  if(n!=-1)                       //关键字匹配
  { 
    strcpy(buf[rlength].sig,spelling);
  }
  else
  { 
    buf[rlength].sig[0]='i';
    buf[rlength].sig[1]='d';
    buf[rlength].sig[2]='\0';
    while((s==0)&&(i<=slength))
    {
      if(!strcmp(sign[i].name,spelling)) s=1;
      i++;
    }
    if(s==0)
    {
      strcpy(sign[slength].name,spelling);
      itoa(slength,buf[rlength].val,10);
      slength++;
    }
    else
	  itoa(--i,buf[rlength].val,10);            
  }
  rlength++;
  for(k=0;k<MAXSIZE2;k++) spelling[k]=' ';
}


/*****************************识别数字函数*****************************/
void isnumber()
{ 
  int s=0,i=0,k=0;
  do
  { 
    spelling[k]=ch;
    k++;
    readch();
  }while((ch>='0')&&(ch<='9'));
  if(ch=='.')
  {
	  char c=ch;
	  readch();
	  if(ch<='0'||ch>='9')
	  {
        cout<<"错误"<<misnum<<":"<<"第"<<linenum<<"行.字符错误"<<endl;
		misnum++;
	  }
	  else
	  {
        spelling[k]=c;
        k++;
        while((ch>='0')&&(ch<='9'))
		{ 
          spelling[k]=ch;
          k++;
          readch();
		}
	  }
  }
  pline--;
  spelling[k]='\0';
  buf[rlength].sig[0]='n';
  buf[rlength].sig[1]='u';
  buf[rlength].sig[2]='m';
  buf[rlength].sig[3]='\0';
  while((s==0)&&(i<=nlength))
  {
    if(!strcmp(number[i].name,spelling)) s=1;
    i++;
  }
  if(s==0)
  {
    strcpy(number[nlength].name,spelling);
    itoa(nlength,buf[rlength].val,10);             
	nlength++;
  }
  else
    itoa(--i,buf[rlength].val,10);             
  rlength++;
  for(k=0;k<MAXSIZE2;k++) spelling[k]=' ';
}

/***************************处理除号和注释函数**************************/
void isanotation()
{ 
  int n=linenum;
  readch();
  switch(ch)
  {
    case '=':
      buf[rlength].sig[0]='/';
      buf[rlength].sig[1]='=';
      buf[rlength].sig[2]='\0';
      rlength++;
	  break;
    case '*':
      while(end!=EOF)
	  {
        do
		{
          readch();
		}while(ch!='*'&&end!=EOF);
		if(end!=EOF)
		{
		  readch();
          if(ch=='/')  break;
		}
	  }
      if(end==EOF)
	  {
	    cout<<"错误"<<misnum<<":"<<"第"<<n<<"行注释符没有结尾"<<endl;
        misnum++;
	  }
	  break;
    default:
      buf[rlength].sig[0]='/';
  	  buf[rlength].sig[1]='\0';
      rlength++;
      pline--;
	  break;
  }
}

/*****************识别函数*****************/
void scanner()
{
  while(end!=EOF)
  {
    switch(ch)
    {
	  case ' ': break;
	  case '\0': break;
      case '_':
      case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
      case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
      case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
      case 'v': case 'w': case 'x': case 'y': case 'z':
      case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
      case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
      case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
      case 'V': case 'W': case 'X': case 'Y': case 'Z':
        isalpha();
        break;
      case '0': case '1': case '2': case '3': case '4': case '5': case '6':
      case '7': case '8': case '9':
        isnumber();
        break;
      case '/':
        isanotation();
        break;
      case ';':
        buf[rlength].sig[0]=';';
	    buf[rlength].sig[1]='\0';
        rlength++;
        break;
      case '[':
        buf[rlength].sig[0]='[';
	    buf[rlength].sig[1]='\0';
        rlength++;
        break;
      case ']':
        buf[rlength].sig[0]=']';
	    buf[rlength].sig[1]='\0';
        rlength++;
        break;
      case '(':
        buf[rlength].sig[0]='(';
	    buf[rlength].sig[1]='\0';
        rlength++;
        break;
      case ')':
        buf[rlength].sig[0]=')';
    	buf[rlength].sig[1]='\0';
        rlength++;
        break;
      case '+':
        readch();
        if(ch=='=')
        {
          buf[rlength].sig[0]='+';
	      buf[rlength].sig[1]='=';
	      buf[rlength].sig[2]='\0';
        }
        else
        {
          buf[rlength].sig[0]='+';
	      buf[rlength].sig[1]='\0';
          pline--;
        }
	    rlength++;
        break;
      case '-':
        readch();
        if(ch=='=')
        {
          buf[rlength].sig[0]='-';
	      buf[rlength].sig[1]='=';
	      buf[rlength].sig[2]='\0';
        }
        else
        {
          buf[rlength].sig[0]='-';
	      buf[rlength].sig[1]='\0';
          pline--;
        }
   	    rlength++;
        break;
      case '*':
        readch();
        if(ch=='=')
        {
          buf[rlength].sig[0]='*';
	      buf[rlength].sig[1]='=';
	      buf[rlength].sig[2]='\0';
        }
        else
        {
          buf[rlength].sig[0]='*';
	      buf[rlength].sig[1]='\0';
          pline--;
        }
        rlength++;
        break;
      case '!':
        readch();
        if(ch=='=')
        {
          buf[rlength].sig[0]='r';
	      buf[rlength].sig[1]='l';
	      buf[rlength].sig[2]='o';
	      buf[rlength].sig[3]='p';
	      buf[rlength].sig[4]='\0';
          buf[rlength].val[0]='!';
	      buf[rlength].val[1]='=';
	      buf[rlength].val[2]='\0';
          rlength++;
        }
        else
        {
          buf[rlength].sig[0]='n';
	      buf[rlength].sig[1]='o';
	      buf[rlength].sig[2]='t';
	      buf[rlength].sig[3]='\0';
          rlength++;
          pline--;
        }
        break;
      case '<':
        readch();
	    buf[rlength].sig[0]='r';
	    buf[rlength].sig[1]='l';
    	buf[rlength].sig[2]='o';
	    buf[rlength].sig[3]='p';
    	buf[rlength].sig[4]='\0';
        if(ch=='=')
        {
          buf[rlength].val[0]='<';
	      buf[rlength].val[1]='=';
	      buf[rlength].val[2]='\0';
        }
        else
        {
          buf[rlength].val[0]='<';
          buf[rlength].val[1]='\0';
          pline--;
        }
		rlength++;
        break;
      case '>':
        readch();
    	buf[rlength].sig[0]='r';
    	buf[rlength].sig[1]='l';
	    buf[rlength].sig[2]='o';
	    buf[rlength].sig[3]='p';
	    buf[rlength].sig[4]='\0';
        if(ch=='=')
        {
          buf[rlength].val[0]='>';
	      buf[rlength].val[1]='=';
          buf[rlength].val[2]='\0';
        }
        else
        {
          buf[rlength].val[0]='>';
          buf[rlength].val[1]='\0';
          pline--;
        }
		rlength++;
        break;
      case '=':
        readch();
        if(ch=='=')
        {
          buf[rlength].sig[0]='r';
          buf[rlength].sig[1]='l';
	      buf[rlength].sig[2]='o';
	      buf[rlength].sig[3]='p';
	      buf[rlength].sig[4]='\0';
          buf[rlength].val[0]='=';
	      buf[rlength].val[1]='=';
          buf[rlength].val[2]='\0';
        }
        else
        {
          buf[rlength].sig[0]='=';
          buf[rlength].sig[1]='\0';
          pline--;
        }
        rlength++;
        break;
      case '%':
        readch();
        if(ch=='=')
        {
          buf[rlength].sig[0]='%';
	      buf[rlength].sig[1]='=';
	      buf[rlength].sig[2]='\0';
        }
        else
        {
          buf[rlength].sig[0]='%';
	      buf[rlength].sig[1]='\0';
          pline--;
        }
	    rlength++;
        break;
      case '|':
        readch();
        if(ch=='|')
        {
          buf[rlength].sig[0]='o';
          buf[rlength].sig[1]='r';
	      buf[rlength].sig[2]='\0';
          rlength++;
        }
        else
        {
          cout<<"错误"<<misnum<<":"<<"第"<<linenum<<"行|字符错误"<<endl;
          misnum++;
          pline--;
        }
        break;
      case '&':
        readch();
        if(ch=='&')
        {
          buf[rlength].sig[0]='a';
          buf[rlength].sig[1]='n';
	      buf[rlength].sig[2]='d';
	      buf[rlength].sig[3]='\0';
          rlength++;
        }
        else
        {
          cout<<"错误"<<misnum<<":"<<"第"<<linenum<<"行&字符错误"<<endl;
          misnum++;
          pline--;
        }
        break;
        default:
          cout<<"错误"<<misnum<<":"<<"第"<<linenum<<"行"<<ch<<"字符错误"<<endl;
          misnum++;
          break;
    }
	if(end!=EOF)
	  readch();
  }
  cout<<"共有"<<misnum<<"个错误!"<<endl;
  cout<<"词法分析结束!"<<endl;
}

/**************分析结果输出函数******************/
void save()
{
  saveFile<<"词法分析结果如下:"<<'\n';
  for(int i=0;i<rlength;i++)
  {
    int j=0;int m=0;
    saveFile<<"(";
    while(buf[i].sig[j]!='\0')
    {
      saveFile<<buf[i].sig[j];
      j++;
    }
    saveFile<<",";
    while(buf[i].val[m]!='\0')
    {
      saveFile<<buf[i].val[m];
      m++;
    }
    saveFile<<")"; 
  }
  saveFile<<endl;
  saveFile<<"标识符表如下:"<<endl;
  saveFile<<"number"<<"   "<<"name"<<"      "<<"type"<<"     "<<"address"<<'\n';
  for(int x=0;x<slength;x++)
  {
    saveFile<<x<<"        ";
    for(int j=0;sign[x].name[j]!='\0';j++)
      saveFile<<sign[x].name[j];
    saveFile<<"        "<<sign[x].type<<"        "<<&sign[i].address<<'\n';
  }
  saveFile<<"常数表如下:"<<endl;
  saveFile<<"number"<<"    "<<"name"<<"      "<<"value"<<'\n';
  for(int k=0;k<nlength;k++)
  {
    saveFile<<k<<"         ";
    for(int j=0;number[k].name[j]!='\0';j++)
    {
      saveFile<<number[k].name[j];
    }
	saveFile<<"          "<<number[k].value<<'\n';
  }
}

/*******************main()主函数*********************/
void main()
{
  char filename1[128],filename2[128];
  cout<<"请输入你要编译的源文件名称:";            //打开源程序文件
  cin>>filename1;
  openFile.open(filename1);
  if(openFile.fail())
  {
    cout<<"打开文件失败!"<<endl;
    return;
  }
  cout<<"请输入你要建立的目标文件名称:";           //建立记号文件
  cin>>filename2;
  saveFile.open(filename2);
  init();
  readch();
  scanner();
  openFile.close();
  save();
  saveFile.close();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -