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

📄 cpp3.cpp

📁 词法分析器,根据编译原理输入语法在新的TXT文本中输出相应的词法分析代码
💻 CPP
字号:
  #include   <iostream>   
  #include   <fstream>//文件流头文件无.h,以下有说明   
  #include   <string>   
  #include   <string.h>//字符串头文件   
  #include<stdio.h>//标准输入输出   
  #include   <ctype.h>//包含了isalpha等,是字符分类宏   
  using   namespace   std;//在目前的版本中可以支持这样的,不用.h为后缀了   
    
  char*   ReserveWords[32]   =   {//   保留字数组定义   
      "auto","double","int","struct","break",     
  "else","long","switch","case","enum","register","typedef",   
  "char","extern","return","union","const","float","short",   
  "unsigned","continue","for","signed","void","default","goto",   
  "sizeof","volatile","do","if","while","static"};//,"main"加上后则识别main为保留字   
  char   arrow[]   =   "                     ";   
  /*char   arrow[]   =   "   ----->   ";   
  宏定义便于以后的修改   
  可以定义此项作为结果输出的分界..如(   ----->   5   
  格式如:dst   <<   strToken   <<   arrow   <<   "1"   <<   enter;   
  */   
  char   enter[]   =   "\r\n";   
  //   读入字符ch   
  char   GetChar(ifstream&   src)   
  {   
      char   cRet;   
      src.get(cRet);//读入一个字符.get是ifstream中的一个函数   
      return   cRet;   
  }   
  //   读入空格   
  char   GetBC(ifstream&   src)//字符型函数   
  {   
      char   cRet;   
      src.get(cRet);//同上   
      while   (cRet   ==   '   ')//空格   
          src.get(cRet);//继续读入   
      return   cRet;//返回字符型值   
  }   
  //   连接单词符号   
  void   Concat(char   *str,   char   c)   
  {   
      size_t   n   =   strlen(str);//得到目前串长度   
      str[n++]   =   c;//作为连接的组合空间   
      str[n]   =   '\0';//结束标志   
  }   
  //   判断是否为保留字   
  bool   Reserve(const   char*   str)   
  {   
      bool   bRet   =   false;   
      for   (int   i   =   0;   i   <   32;   i++)   
      {   
          if   (strcmp(ReserveWords[i],   str)   ==   0)//是关键字的话   
          {   
              bRet   =   true;//true确认   
              break;   
          }   
      }   
      return   bRet;   
  }   
  //   回调字符   
  char   Retract(ifstream&   src)   
  {   
      src.seekg(-1,   ios::cur);/*文件流中的一个函数,两种类型,两种参数!   
                                                      seekg(pos_type   _Pos);   
      seekg(off_type   _Off,ios_base::seekdir   _Way);   
                                                      _Off     
  An   offset   to   move   the   read   pointer   relative   to   way.     
      _Pos     
  The   absolute   position   in   which   to   move   the   read   pointer.     
      _Way     
  One   of   the   ios_base::seekdir   enumerations.     
      Return   Value   
          The   stream   (*this).   
                                                      //用于在文件流移动读指针   
      */   
      return   '\0';   
  }   
  //   分析函数   
  void   Analyzer(ifstream&   src,   ofstream&   dst)   
  {   
      char   ch;   
      char   strToken[1024]   =   "";//初始置空   
      ch   =   GetBC(src);//定义ch字符初始空格   
    
      //   判断标识符的情况   
      if   (isalpha(ch))   
      {   
          while   (isalpha(ch)   ||   isdigit(ch)   ||   ch   ==   '_')   
          {   
              Concat(strToken,   ch);//判断是否为单个字符,进行连接   
              ch   =   GetChar(src);   
          }   
          ch   =   Retract(src);//字符回调后重新对字符或字符串进行判断   
          if   (Reserve(strToken))   
              dst   <<   strToken   <<   arrow   <<   "1"   <<   enter;//输出流的一种格式   
          else   
              dst   <<   strToken   <<   arrow   <<   "2"   <<   enter;//不为保留字,则为数字,有上面的条件判定   
      }   
      //   判断数字的情况   
      else   if   (isdigit(ch))   
      {   
          while   (isdigit(ch))//下个字符不是数字,退出运行过程   
          {   
              Concat(strToken,   ch);//进行连接,多位数...   
              ch   =   GetChar(src);//从标准输入设备读取一个字符,若文件结束或出错,则返回-1   
                                          //而getc是从文件中读入一个字符,若文件结束或出错,返回EOF   
          }   
          Retract(src);//回调字符   
          dst   <<   strToken   <<   arrow   <<   "3"   <<   enter;//类型3   
      }   //   判断转义字符与串的情况   
      else   if   (ch   ==   '\'')//是\'转义字符   
      {   
          Concat(strToken,   ch);//将其连接   
          ch   =   GetChar(src);   
          while   (ch   !=   '\'')//不是\'字符,继续连接   
          {   
              Concat(strToken,   ch);   
              ch   =   GetChar(src);   
          }   
          if   (ch   !=   '\'')//界定长度   
              cerr   <<   "String   is   too   long   -   more   than   1024   bytes!"   <<   endl;   
          else   
          {   
              Concat(strToken,   ch);   
              dst   <<   strToken   <<   arrow   <<   "String"   <<   enter;//串   
          }   
      }   
      //   判断所有没有歧义的单目运算符   
      else   if   (ch   ==   '+')   
          dst   <<   ch   <<   arrow   <<   "4"   <<   enter;////类型4,以下输出,意义相同   
      else   if   (ch   ==   '-')   
          dst   <<   ch   <<   arrow   <<   "4"   <<   enter;   
      else   if   (ch   ==   '*')   
          dst   <<   ch   <<   arrow   <<   "4"   <<   enter;   
      else   if   (ch   ==   '/')   
          dst   <<   ch   <<   arrow   <<   "4"   <<   enter;   
      else   if   (ch   ==   '=')   
          dst   <<   ch   <<   arrow   <<   "4"   <<   enter;   
      else   if   (ch   ==   '[')   
          dst   <<   ch   <<   arrow   <<   "5"   <<   enter;   
      else   if   (ch   ==   ']')   
          dst   <<   ch   <<   arrow   <<   "5"   <<   enter;   
      else   if   (ch   ==   ',')   
          dst   <<   ch   <<   arrow   <<   "5"   <<   enter;   
      else   if   (ch   ==   '^')   
          dst   <<   ch   <<   arrow   <<   "4"   <<   enter;   
      else   if   (ch   ==   ';')   
          dst   <<   ch   <<   arrow   <<   "5"   <<   enter;   
      else   if   (ch   ==   '(')   
          dst   <<   ch   <<   arrow   <<   "5"   <<   enter;   
      else   if   (ch   ==   ')')   
          dst   <<   ch   <<   arrow   <<   "5"   <<   enter;   
      else   if   (ch   ==   '{')   
          dst   <<   ch   <<   arrow   <<   "5"   <<   enter;   
      else   if   (ch   ==   '}')   
          dst   <<   ch   <<   arrow   <<   "5"   <<   enter;   
      //   判断<、<>和<=   
      else   if   (ch   ==   '<')   
      {   
          ch   =   GetChar(src);   
          if   (ch   ==   '>')   
              dst   <<   "<>"   <<   arrow   <<   "4"   <<   enter;   
          else   if   (ch   ==   '=')   
              dst   <<   "<="   <<   arrow   <<   "4"   <<   enter;   
          else   
          {   
              dst   <<   '<'   <<   arrow   <<   "4"   <<   enter;   
              Retract(src);//<=,<>也即!=   
          }   
      }   
      //   判断>和>=   
      else   if   (ch   ==   '>')   
      {   
          ch   =   GetChar(src);   
          if   (ch   ==   '=')   
              dst   <<   ">="   <<   arrow   <<   "4"   <<   enter;//类型4   
          else   
          {   
              dst   <<   '>'   <<   arrow   <<   "4"   <<   enter;//类型4   
              Retract(src);//>=   
          }   
      }   
      //   判断.和..   
      else   if   (ch   ==   '.')   
      {   
          ch   =   GetChar(src);   
          if   (ch   ==   '.')   
              dst   <<   ".."   <<   arrow   <<   "2"   <<   enter;//类型2   
          else   
          {   
              dst   <<   '.'   <<   arrow   <<   "2"   <<   enter;//类型2   
              Retract(src);//.和..   
          }   
      }   
      //   判断:和:=   
      else   if   (ch   ==   ':')   
      {   
          ch   =   GetChar(src);   
          if   (ch   ==   '=')   
              dst   <<   ":="   <<   arrow   <<   "4"   <<   enter;//类型4   
          else   
          {   
              dst   <<   ':'   <<   arrow   <<   "2"   <<   enter;//类型2   
              Retract(src);//:=   逐级判断,分析为各个独立个体,所以需要回调分析,保持字符或字符串完整性   
          }   
      }   
  }   
  int   main(int   argc,   char*   argv[])   
  {   
      string   strSrc;   
      if   (argc   ==   1)     //   命令行的支持   
      {   
          cout   <<   "Please   input   source   file\nlike   in.txt...   \n\n";   
          getline(cin,   strSrc);   
  /*   
          if(cin=="in.txt"){   
  cout   <<   "the   source   program   below:\n";   
  while(ch=fopen("in.txt","r")!=NULL)     
    {   
    printf("%c",ch);   
    }   
  cout<<"\n\n"<<"The   result   has   created   to   out.txt\n";   
  }   
  */   
    system("pause");//系统暂停,让用户确定   
  }   
      else   
          strSrc   =   argv[1];   
      ifstream   src(strSrc.c_str());     //   打开文件   
      if   (src.fail())   
      {   
          cerr   <<   "\aFailed   to   open   \""   <<   strSrc   <<   "\"!"   <<   endl;//cerr输出错误机制,有声音提示   
          return   1;   
      }   
      ofstream   dst("out.txt");   
      //   开始解析,整个文件,知道文件尾   
      while   (!src.eof())//   
          Analyzer(src,   dst);   
      //   收尾工作   
      src.close();//关闭输入文件流   
      dst.close();//关闭输出文件流   
      cout   <<   "The   result   of   Analyzing   is   written   into   out.txt."   <<   endl;   
      return   0;//整形返回   
  }

⌨️ 快捷键说明

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