<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      尋找生命的意義  
      早日脫貧

      語言:C/C++

      關鍵字:詞法分析,哈希表,鏈表法處理哈希沖突

      摘要:開發(fā)一個簡單的編譯器。編譯一個程序的步驟:詞法分析,語法分析,語義分析,中間代碼生成,目標代碼生成。本文目的是實現(xiàn)詞法分析。

      1 項目需求描述

      分析一個C語言程序的內(nèi)容。將函數(shù)的變量名設置為灰色,將關鍵字設置為綠色,將整型常量、浮點型常量、字符常量、字符串常量等設置為褐色,將運算符設置為紅色。

      2 設計思路

      2.1 預處理

      2.1.1 定義存儲字符串的結構體。

      /*存儲字符串的結構體定義*/
      typedef struct TKWord {
          int tkcode;
          string spelling;
          struct TKWord* next;
      }TKWord, *pTKWord;
      定義存儲字符串的結構體

      2.1.2 通過枚舉對預置的字符串進行編號。

      /*通過枚舉對預置的字符串進行編號*/
      enum e_TokenCode
      {
          /* 運算符及分隔符 */
          TK_PLUS,        // + 加號
          TK_MINUS,        // - 減號
          TK_STAR,        // * 星號
          TK_DIVIDE,        // / 除號
          TK_MOD,            // % 求余運算符
          TK_EQ,            // == 等于號
          TK_NEQ,            // != 不等于號
          TK_LT,            // < 小于號
          TK_LEQ,            // <= 小于等于號
          TK_GT,            // > 大于號
          TK_GEQ,            // >= 大于等于號
          TK_ASSIGN,        // = 賦值運算符 
          TK_POINTSTO,    // -> 指向結構體成員運算符
          TK_DOT,            // . 結構體成員運算符
          TK_AND,         // & 地址與運算符
          TK_OPENPA,        // ( 左圓括號
          TK_CLOSEPA,        // ) 右圓括號
          TK_OPENBR,        // [ 左中括號
          TK_CLOSEBR,        // ] 右中括號
          TK_BEGIN,        // { 左大括號
          TK_END,            // } 右大括號
          TK_SEMICOLON,    // ; 分號    
          TK_COMMA,        // , 逗號
          TK_ELLIPSIS,    // ... 省略號
          TK_EOF,            // 文件結束符
      
          /* 常量 */
          TK_CINT,        // 整型常量
          TK_CFLOAT,        // 浮點型常量
          TK_CCHAR,        // 字符常量
          TK_CSTR,        // 字符串常量
      
          /* 關鍵字 */
          KW_CHAR,        // char關鍵字
          KW_SHORT,        // short關鍵字
          KW_INT,            // int關鍵字
          KW_VOID,        // void關鍵字  
          KW_STRUCT,        // struct關鍵字   
          KW_IF,            // if關鍵字
          KW_ELSE,        // else關鍵字
          KW_FOR,            // for關鍵字
          KW_CONTINUE,    // continue關鍵字
          KW_BREAK,        // break關鍵字   
          KW_RETURN,        // return關鍵字
      
          /* 標識符 */
          TK_IDENT        // 函數(shù)名或變量名
      };
      typedef enum e_TokenCode tokencode;
      對預置的字符串進行編號

      2.1.3 定義一個靜態(tài)結構數(shù)組,其中存放各種預置的字符串及其token。然后將他們分別通過哈希公式映射并添加到哈希表中。

      /*定義一個靜態(tài)結構數(shù)組*/
      static TKWord keywords[] = { 
          {TK_PLUS,"+",NULL},
          {TK_MINUS,"-",NULL},
          {TK_STAR,"*",NULL},
          {TK_DIVIDE,"/",NULL},
          {TK_MOD,"%",NULL},
          {TK_EQ,"==",NULL},
          {TK_NEQ,"!=",NULL},
          {TK_LT,"<",NULL},
          {TK_LEQ,"<=",NULL},
          {TK_GT,">",NULL},
          {TK_GEQ,">=",NULL},
          {TK_ASSIGN,"=",NULL},
          {TK_POINTSTO,"->",NULL},
          {TK_DOT,".",NULL},
          {TK_AND,"&",NULL},
          {TK_OPENPA,"(",NULL},
          {TK_CLOSEPA,")",NULL},
          {TK_OPENBR,"[",NULL},
          {TK_CLOSEBR,"]",NULL},
          {TK_BEGIN,"{",NULL},
          {TK_END,"}",NULL},
          {TK_SEMICOLON,";",NULL},
          {TK_COMMA,",",NULL},
          {TK_ELLIPSIS,"...",NULL},
          {TK_EOF,"End Of File",NULL},
      
          {TK_CINT,"整形常量",NULL},
          {TK_CFLOAT,"浮點型常量",NULL},
          {TK_CCHAR,"字符常量",NULL},
          {TK_CSTR,"字符串常量",NULL},
      
          {KW_CHAR,"char",NULL},
          {KW_SHORT,"short",NULL},
          {KW_INT,"int",NULL},
          {KW_VOID,"void",NULL},
          {KW_STRUCT,"struct",NULL},
      
          {KW_IF,"if",NULL},
          {KW_ELSE,"else",NULL},
          {KW_FOR,"for",NULL},
          {KW_CONTINUE,"continue",NULL},
          {KW_BREAK,"break",NULL},
          {KW_RETURN,"return",NULL},
          {40}
      };
      定義靜態(tài)結構數(shù)組keywords
      /*定義哈希函數(shù)*/
      int elf_hash(string key) {
          int h = 0, g, i = 0;
          while (key[i]) {
              h = (h << 4) + key[i++];
              g = h & 0xf0000000;
              if (g)
                  h ^= g >> 24;
              h &= ~g;
          }
          return h % MAXKEY;
      }
      哈希函數(shù)elf_hash
      /*定義哈希表*/
      TKWord* tk_Hashtable[MAXKEY] = { 0 };
      定義哈希表
      /*定義函數(shù),用于將靜態(tài)結構數(shù)組中各種預置的字符串及其token分別通過哈希公式映射并添加到哈希表中*/
      void InitKeywords(pTKWord keywords, int keywordsLen, pTKWord* tk_Hashtable) {
          for (int i = 0; i < keywordsLen; i++) {
              TKWord tmp = keywords[i];
              if (tk_Hashtable[elf_hash(tmp.spelling)] == NULL) {
                  TKWord* pnew = new TKWord;
                  pnew->next = NULL;
                  pnew->tkcode = tmp.tkcode;
                  /*string snew = tmp.spelling;
                  for (int j = 0; j < snew.size(); j++) {
                      pnew->spelling.push_back(snew[j]);
                  }*/
                  pnew->spelling = tmp.spelling;//拷貝字符串
                  tk_Hashtable[elf_hash(tmp.spelling)] = pnew;
              }
              else {
                  TKWord* p = tk_Hashtable[elf_hash(tmp.spelling)];
                  TKWord* q = p;
                  while (p != NULL) {
                      if (!p->spelling.compare(tmp.spelling)) {
                          break;
                      }
                      q = p;
                      p = p->next;
                  }
                  if (!p) {
                      TKWord* pnew = new TKWord;
                      pnew->next = NULL;
                      pnew->spelling = tmp.spelling;
                      pnew->tkcode = tmp.tkcode;
                      tk_Hashtable[elf_hash(tmp.spelling)] = pnew;
                  }
              }
          }
      }
      函數(shù)InitKeywords
          int keywordsLen = sizeof(keywords) / sizeof(TKWord);
          InitKeywords(keywords, keywordsLen, tk_Hashtable);
      該步驟的main函數(shù)

      2.2 打開文件test.txt,每次取一行放入str中。

          ifstream file;
          file.open("test.txt", ios::in);
          if (!file.is_open()) {
              return;
          }
          string str;
          while (getline(file, str)) {
              ...
              }
      該步驟的main函數(shù)

      2.3 (在while函數(shù)中操作)對這一行str分割成一個個具有獨立意義的字符串,并分別存放到向量(動態(tài)數(shù)組)中。

      /*定義一個向量word,用于存放分割后的字符串*/
      vector<TKWord>word;
      定義向量word
      /*定義函數(shù),用于將str分割成一個個有獨立意義的字符串,并存放在向量word中*/
      void split(vector<TKWord>& word,const string str) {
          for (int i = 0; i < str.length(); i++) {
              if (isalpha(str[i]) || str[i] == '_') {//函數(shù)名或變量名
                  TKWord tmp;
                  tmp.tkcode = TK_IDENT;
                  tmp.next = NULL;
                  while (isalnum(str[i])||str[i]=='_') {
                      tmp.spelling.push_back(str[i]);
                      i++;
                  }
                  word.push_back(tmp);
                  i--;
              }
              else if(str[i]=='"') {//字符串常量
                  TKWord tmp;
                  tmp.tkcode = TK_CSTR;
                  tmp.next = NULL;
                  tmp.spelling.push_back(str[i]);
                  i++;
                  while (str[i] != '"') {
                      tmp.spelling.push_back(str[i]);
                      i++;
                  }
                  tmp.spelling.push_back('"');
                  word.push_back(tmp);
              }
              else if (str[i] == '\'') {//字符常量
                  TKWord tmp;
                  tmp.tkcode = TK_CCHAR;
                  tmp.next = NULL;
                  tmp.spelling.push_back(str[i]);
                  i++;
                  while (str[i] != '\'') {
                      tmp.spelling.push_back(str[i]);
                      i++;
                  }
                  tmp.spelling.push_back('\'');
                  word.push_back(tmp);
              }
              else if (ispunct(str[i])) {//運算符
                  TKWord tmp;
              
                  tmp.next = NULL;
                  tmp.spelling.push_back(str[i]);
                  word.push_back(tmp);
              }
              else if (str[i] == ' ') {//空格
                  TKWord tmp;
                  
                  tmp.next = NULL;
                  tmp.spelling.push_back(str[i]);
                  word.push_back(tmp);
              }
              else if(isdigit(str[i])){//純數(shù)字(目前將整型常量和浮點型常量考慮在一起)
                  TKWord tmp;
                  tmp.tkcode = TK_CINT;
                  tmp.next = NULL;
                  while (isdigit(str[i]) || str[i] == '.') {
                      tmp.spelling.push_back(str[i]);
                      i++;
                  }
                  word.push_back(tmp);
                  i--;
              }
              else if(str[i]=='\t') {//tab鍵
                  TKWord tmp;
                  
                  tmp.next = NULL;
                  tmp.spelling = "    ";
                  word.push_back(tmp);
              }
          }
      }
      定義分割函數(shù)split
              if (str.empty()) {
                  continue;
              }
              word.clear();
              split(word, str);
      該步驟的main函數(shù)

      2.4 (在while函數(shù)中操作)將word中存放好的一個個字符串們分別處理。首先,將字符串鏈接到哈希表上。通過哈希函數(shù)得到哈希值,通過哈希值在哈希表上定位,判斷對應位置是否為NULL:若為NULL,將該字符串所在的結構體鏈接到該位置;若不為NULL,由于采用鏈表法處理哈希沖突,故此時應該在該位置所鏈接的鏈表中不斷比較字符串直到找到匹配的字符串所在結構體,若最終沒有匹配成功,就申請一個新的結構體并將該字符串所在結構體的所有信息拷貝到新的結構體中,并將這個新結構體鏈接到鏈表表尾。然后,根據(jù)該字符串的token顏色打印該字符串。

      /*顏色打印函數(shù)*/
      void printColor(string str, int token) {
          HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
          if (token >= TK_IDENT) {//變量名或者函數(shù)名為灰色
              SetConsoleTextAttribute(h, FOREGROUND_INTENSITY);
          }
          else if (token >= KW_CHAR) {//關鍵字為綠色
              SetConsoleTextAttribute(h, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
          }
          else if (token >= TK_CINT) {//整型常量、浮點型常量、字符常量、字符串常量等為褐色
              SetConsoleTextAttribute(h, FOREGROUND_RED | FOREGROUND_GREEN);
          }
          else {//運算符為紅色
              SetConsoleTextAttribute(h, FOREGROUND_RED | FOREGROUND_INTENSITY);
          }
          if (-1 == str[0]) {
              printf("\n ENd Of File");
              SetConsoleTextAttribute(h, FOREGROUND_RED | FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
          }
          else {
              cout << str;
          }
      }
      顏色打印函數(shù)
      for (int i = 0; i < word.size(); i++) {
                  TKWord tmp = word[i];
                  if (tk_Hashtable[elf_hash(tmp.spelling)] == NULL) {
                      TKWord* pnew = new TKWord;
                      pnew->next = NULL;
                      pnew->tkcode = tmp.tkcode;
                      /*string snew = tmp.spelling;
                      for (int j = 0; j < snew.size(); j++) {
                          pnew->spelling.push_back(snew[j]);
                      }*/
                      pnew->spelling = tmp.spelling;//拷貝字符串
                      tk_Hashtable[elf_hash(tmp.spelling)] = pnew;
                  }
                  else {
                      TKWord* p = tk_Hashtable[elf_hash(tmp.spelling)];
                      TKWord* q = p;
                      while (p != NULL) {
                          if (!p->spelling.compare(tmp.spelling)) {
                              word[i].tkcode = p->tkcode;
                              break;
                          }
                          q = p;
                          p = p->next;
                      }
                      if (!p) {
                          TKWord* pnew = new TKWord;
                          pnew->next = NULL;
                          pnew->spelling = tmp.spelling;
                          pnew->tkcode = tmp.tkcode;
                          q->next = pnew;
                      }
                  }
                  printColor(word[i].spelling, word[i].tkcode);
      該步驟的main函數(shù)

      3 完整代碼

      #include <string>
      #include <Windows.h>
      #include <fstream>
      #include <iostream>
      #include <vector>
      #include <ctype.h>
      
      using namespace std;
      /*通過枚舉對預置的字符串進行編號*/
      enum e_TokenCode
      {
          /* 運算符及分隔符 */
          TK_PLUS,        // + 加號
          TK_MINUS,        // - 減號
          TK_STAR,        // * 星號
          TK_DIVIDE,        // / 除號
          TK_MOD,            // % 求余運算符
          TK_EQ,            // == 等于號
          TK_NEQ,            // != 不等于號
          TK_LT,            // < 小于號
          TK_LEQ,            // <= 小于等于號
          TK_GT,            // > 大于號
          TK_GEQ,            // >= 大于等于號
          TK_ASSIGN,        // = 賦值運算符 
          TK_POINTSTO,    // -> 指向結構體成員運算符
          TK_DOT,            // . 結構體成員運算符
          TK_AND,         // & 地址與運算符
          TK_OPENPA,        // ( 左圓括號
          TK_CLOSEPA,        // ) 右圓括號
          TK_OPENBR,        // [ 左中括號
          TK_CLOSEBR,        // ] 右中括號
          TK_BEGIN,        // { 左大括號
          TK_END,            // } 右大括號
          TK_SEMICOLON,    // ; 分號    
          TK_COMMA,        // , 逗號
          TK_ELLIPSIS,    // ... 省略號
          TK_EOF,            // 文件結束符
      
          /* 常量 */
          TK_CINT,        // 整型常量
          TK_CFLOAT,        // 浮點型常量
          TK_CCHAR,        // 字符常量
          TK_CSTR,        // 字符串常量
      
          /* 關鍵字 */
          KW_CHAR,        // char關鍵字
          KW_SHORT,        // short關鍵字
          KW_INT,            // int關鍵字
          KW_VOID,        // void關鍵字  
          KW_STRUCT,        // struct關鍵字   
          KW_IF,            // if關鍵字
          KW_ELSE,        // else關鍵字
          KW_FOR,            // for關鍵字
          KW_CONTINUE,    // continue關鍵字
          KW_BREAK,        // break關鍵字   
          KW_RETURN,        // return關鍵字
      
          /* 標識符 */
          TK_IDENT        // 函數(shù)名或變量名
      };
      typedef enum e_TokenCode tokencode;
      /*存儲字符串的結構體定義*/
      typedef struct TKWord {
          int tkcode;
          string spelling;
          struct TKWord* next;
      }TKWord, *pTKWord;
      
      #define MAXKEY 50
      void printColor(string str, int token);
      int elf_hash(string key);
      void InitKeywords(pTKWord keywords, int keywordsLen, pTKWord* tk_Hashtable);
      void split(vector<TKWord>& word, const string str);
      complier.h
      #include "complier.h"
      
      /*定義哈希函數(shù)*/
      int elf_hash(string key) {
          int h = 0, g, i = 0;
          while (key[i]) {
              h = (h << 4) + key[i++];
              g = h & 0xf0000000;
              if (g)
                  h ^= g >> 24;
              h &= ~g;
          }
          return h % MAXKEY;
      }
      /*定義函數(shù),用于將靜態(tài)結構數(shù)組中各種預置的字符串及其token分別通過哈希公式映射并添加到哈希表中*/
      void InitKeywords(pTKWord keywords, int keywordsLen, pTKWord* tk_Hashtable) {
          for (int i = 0; i < keywordsLen; i++) {
              TKWord tmp = keywords[i];
              if (tk_Hashtable[elf_hash(tmp.spelling)] == NULL) {
                  TKWord* pnew = new TKWord;
                  pnew->next = NULL;
                  pnew->tkcode = tmp.tkcode;
                  /*string snew = tmp.spelling;
                  for (int j = 0; j < snew.size(); j++) {
                      pnew->spelling.push_back(snew[j]);
                  }*/
                  pnew->spelling = tmp.spelling;//拷貝字符串
                  tk_Hashtable[elf_hash(tmp.spelling)] = pnew;
              }
              else {
                  TKWord* p = tk_Hashtable[elf_hash(tmp.spelling)];
                  TKWord* q = p;
                  while (p != NULL) {
                      if (!p->spelling.compare(tmp.spelling)) {
                          break;
                      }
                      q = p;
                      p = p->next;
                  }
                  if (!p) {
                      TKWord* pnew = new TKWord;
                      pnew->next = NULL;
                      pnew->spelling = tmp.spelling;
                      pnew->tkcode = tmp.tkcode;
                      tk_Hashtable[elf_hash(tmp.spelling)] = pnew;
                  }
              }
          }
      }
      /*定義函數(shù),用于將str分割成一個個有獨立意義的字符串,并存放在向量word中*/
      void split(vector<TKWord>& word,const string str) {
          for (int i = 0; i < str.length(); i++) {
              if (isalpha(str[i]) || str[i] == '_') {//函數(shù)名或變量名
                  TKWord tmp;
                  tmp.tkcode = TK_IDENT;
                  tmp.next = NULL;
                  while (isalnum(str[i])||str[i]=='_') {
                      tmp.spelling.push_back(str[i]);
                      i++;
                  }
                  word.push_back(tmp);
                  i--;
              }
              else if(str[i]=='"') {//字符串常量
                  TKWord tmp;
                  tmp.tkcode = TK_CSTR;
                  tmp.next = NULL;
                  tmp.spelling.push_back(str[i]);
                  i++;
                  while (str[i] != '"') {
                      tmp.spelling.push_back(str[i]);
                      i++;
                  }
                  tmp.spelling.push_back('"');
                  word.push_back(tmp);
              }
              else if (str[i] == '\'') {//字符常量
                  TKWord tmp;
                  tmp.tkcode = TK_CCHAR;
                  tmp.next = NULL;
                  tmp.spelling.push_back(str[i]);
                  i++;
                  while (str[i] != '\'') {
                      tmp.spelling.push_back(str[i]);
                      i++;
                  }
                  tmp.spelling.push_back('\'');
                  word.push_back(tmp);
              }
              else if (ispunct(str[i])) {//運算符
                  TKWord tmp;
              
                  tmp.next = NULL;
                  tmp.spelling.push_back(str[i]);
                  word.push_back(tmp);
              }
              else if (str[i] == ' ') {//空格
                  TKWord tmp;
                  
                  tmp.next = NULL;
                  tmp.spelling.push_back(str[i]);
                  word.push_back(tmp);
              }
              else if(isdigit(str[i])){//純數(shù)字(目前將整型常量和浮點型常量考慮在一起)
                  TKWord tmp;
                  tmp.tkcode = TK_CINT;
                  tmp.next = NULL;
                  while (isdigit(str[i]) || str[i] == '.') {
                      tmp.spelling.push_back(str[i]);
                      i++;
                  }
                  word.push_back(tmp);
                  i--;
              }
              else if(str[i]=='\t') {//tab鍵
                  TKWord tmp;
                  
                  tmp.next = NULL;
                  tmp.spelling = "    ";
                  word.push_back(tmp);
              }
          }
      }
      /*顏色打印函數(shù)*/
      void printColor(string str, int token) {
          HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
          if (token >= TK_IDENT) {//變量名或者函數(shù)名為灰色
              SetConsoleTextAttribute(h, FOREGROUND_INTENSITY);
          }
          else if (token >= KW_CHAR) {//關鍵字為綠色
              SetConsoleTextAttribute(h, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
          }
          else if (token >= TK_CINT) {//整型常量、浮點型常量、字符常量、字符串常量等為褐色
              SetConsoleTextAttribute(h, FOREGROUND_RED | FOREGROUND_GREEN);
          }
          else {//運算符為紅色
              SetConsoleTextAttribute(h, FOREGROUND_RED | FOREGROUND_INTENSITY);
          }
          if (-1 == str[0]) {
              printf("\n ENd Of File");
              SetConsoleTextAttribute(h, FOREGROUND_RED | FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
          }
          else {
              cout << str;
          }
      }
      complier.cpp
      #include "complier.h"
      /*定義一個靜態(tài)結構數(shù)組*/
      static TKWord keywords[] = { 
          {TK_PLUS,"+",NULL},
          {TK_MINUS,"-",NULL},
          {TK_STAR,"*",NULL},
          {TK_DIVIDE,"/",NULL},
          {TK_MOD,"%",NULL},
          {TK_EQ,"==",NULL},
          {TK_NEQ,"!=",NULL},
          {TK_LT,"<",NULL},
          {TK_LEQ,"<=",NULL},
          {TK_GT,">",NULL},
          {TK_GEQ,">=",NULL},
          {TK_ASSIGN,"=",NULL},
          {TK_POINTSTO,"->",NULL},
          {TK_DOT,".",NULL},
          {TK_AND,"&",NULL},
          {TK_OPENPA,"(",NULL},
          {TK_CLOSEPA,")",NULL},
          {TK_OPENBR,"[",NULL},
          {TK_CLOSEBR,"]",NULL},
          {TK_BEGIN,"{",NULL},
          {TK_END,"}",NULL},
          {TK_SEMICOLON,";",NULL},
          {TK_COMMA,",",NULL},
          {TK_ELLIPSIS,"...",NULL},
          {TK_EOF,"End Of File",NULL},
      
          {TK_CINT,"整形常量",NULL},
          {TK_CFLOAT,"浮點型常量",NULL},
          {TK_CCHAR,"字符常量",NULL},
          {TK_CSTR,"字符串常量",NULL},
      
          {KW_CHAR,"char",NULL},
          {KW_SHORT,"short",NULL},
          {KW_INT,"int",NULL},
          {KW_VOID,"void",NULL},
          {KW_STRUCT,"struct",NULL},
      
          {KW_IF,"if",NULL},
          {KW_ELSE,"else",NULL},
          {KW_FOR,"for",NULL},
          {KW_CONTINUE,"continue",NULL},
          {KW_BREAK,"break",NULL},
          {KW_RETURN,"return",NULL},
          {40}
      };
      /*定義哈希表*/
      TKWord* tk_Hashtable[MAXKEY] = { 0 };
      /*定義一個向量word,用于存放分割后的字符串*/
      vector<TKWord>word;
      
      void main() {
          int keywordsLen = sizeof(keywords) / sizeof(TKWord);
          InitKeywords(keywords, keywordsLen, tk_Hashtable);
          ifstream file;
          file.open("test.txt", ios::in);
          if (!file.is_open()) {
              return;
          }
          string str;
          while (getline(file, str)) {
              if (str.empty()) {
                  continue;
              }
              word.clear();
              split(word, str);
              for (int i = 0; i < word.size(); i++) {
                  TKWord tmp = word[i];
                  if (tk_Hashtable[elf_hash(tmp.spelling)] == NULL) {
                      TKWord* pnew = new TKWord;
                      pnew->next = NULL;
                      pnew->tkcode = tmp.tkcode;
                      /*string snew = tmp.spelling;
                      for (int j = 0; j < snew.size(); j++) {
                          pnew->spelling.push_back(snew[j]);
                      }*/
                      pnew->spelling = tmp.spelling;//拷貝字符串
                      tk_Hashtable[elf_hash(tmp.spelling)] = pnew;
                  }
                  else {
                      TKWord* p = tk_Hashtable[elf_hash(tmp.spelling)];
                      TKWord* q = p;
                      while (p != NULL) {
                          if (!p->spelling.compare(tmp.spelling)) {
                              word[i].tkcode = p->tkcode;
                              break;
                          }
                          q = p;
                          p = p->next;
                      }
                      if (!p) {
                          TKWord* pnew = new TKWord;
                          pnew->next = NULL;
                          pnew->spelling = tmp.spelling;
                          pnew->tkcode = tmp.tkcode;
                          q->next = pnew;
                      }
                  }
                  printColor(word[i].spelling, word[i].tkcode);
              }
              cout << endl;
          }
      }
      main.cpp

      4 測試文件及顯示結果

      int split(vector<string> &word,const string str){
          for(int i=0;i<str.length();i++){
              if(str[i]==34){
                  string temp;
                  temp.push_back(str[i]);
                  i++;
                  while(str[i]!=34){
                      temp.push_back(str[i]);
                      i++;
                  }
                  temp.push_back(str[i]);
                  word.push_back(temp);
              }else if(ispunct(str[i])||str[i]==' \b'){
                  string temp;
                  temp.push_back(str[i]);
                  word.push_back(temp);
              }else if(isdigit(str[i])){
                  string temp;
                  while(isdigit(str[i])){
                      temp.push_back(str[i]);
                      ++i;
                  }
                  if(str[i]=='.'){
                      ++i;
                      if(isdigit(str[i])){
                          temp.push_back('.');
                          while(isdigit(str[i])){
                              temp.push_back(str[i]);
                              i++;
                          }
                      }else{
                          return -1;
                      }
                  }
                  word.push_back(temp);
                  --i;
              }else if(isalpha(str[i])){
                  string temp;
                  while(isalnum(str[i])){
                      temp.push_back(str[i]);
                      i++;
                  }
                  word.push_back(temp);
                  --i;
              }else if(str[i]=='\t'){
                  string temp="    ";
                  word.push_back(temp);
              }
          }
      }
      test.txt

      5 尚需改進的地方

      分析不完全。如沒有將所有運算符考慮進去;在分割函數(shù)中,函數(shù)名和變量名、數(shù)字的整型和浮點型也都沒有分開考慮。

      6 經(jīng)驗和教訓

      bug: 前面定義里含有string的結構體,后面用malloc申請一個新的結構體,并將舊的結構體拷貝到新結構體中,但是這期間拷貝string時總是報錯,在多次嘗試之后,最后發(fā)現(xiàn)將malloc換用new后程序正確運行。

      教訓:不要將C和C++的操作混用!(這里用C語言的malloc函數(shù)申請一個包含C++獨用的string類型的結構體,這是會在后面的操作中出現(xiàn)錯誤)

       

      posted on 2022-03-19 15:52  田園脆雞堡  閱讀(159)  評論(0)    收藏  舉報
       
      主站蜘蛛池模板: 亚洲美女少妇偷拍萌白酱| 性一交一乱一伦| 91精品久久一区二区三区| 熟妇人妻无码中文字幕老熟妇| 亚洲午夜福利精品无码不卡| 日韩伦理片| 一区二区亚洲人妻av| jk白丝喷浆| 尤物国精品午夜福利视频| 亚洲av永久无码精品天堂久久| 国产精品久久久久影院色| 国产成人a在线观看视频| 亚洲天堂网中文在线资源| 日韩国产中文字幕精品| 国产自产对白一区| 亚洲免费人成在线视频观看| 建平县| 98久久人妻少妇激情啪啪| 麻豆一区二区中文字幕| 国产v综合v亚洲欧美久久| 亚洲一区二区av高清| 亚洲色欲色欱WWW在线| 康乐县| 国产成人精品亚洲午夜| 亚洲性线免费观看视频成熟| 亚洲 一区二区 在线| 亚洲精品美女一区二区| 久久婷婷丁香五月综合五| 双乳奶水饱满少妇呻吟免费看| 免费观看全黄做爰大片| 久久精品国产亚洲欧美| 成人免费A级毛片无码片2022 | 无码人妻黑人中文字幕| 国产AV国片精品有毛| 国产高清一区二区三区视频| 国产精品无码素人福利不卡| 熟妇的奶头又大又长奶水视频| 亚洲偷偷自拍码高清视频| 国产熟睡乱子伦午夜视频| 人人澡人摸人人添| 国内自拍偷拍福利视频看看|