2013-10-27 148 views
0

我正在用C++寫一個tokenizer。它要做的是在文件中搜索「」中包含的字符串字符,以及符號[和]。它將創建一個令牌對象,並將其存儲在一個向量中。它應該通過調用input.get()忽略所有空白字符來忽略它們,但我不確定這是否是正確的方法。我也覺得我可以做出愚蠢的錯誤,如==而不是=。這裏是我當前的代碼編寫tokenizer時遇到困難

vector<Token> tokenize(wstring file) 
{ 
    ifstream input = ifstream(file); 
    vector<Token> tokens; 

    while(input.peek() != std::char_traits<char>::eof()) 
    { 
     wchar_t ch = (wchar_t) input.peek(); 

     if (isspace(ch)) 
     { 
      input.get(); 
     } 
     else if(ch == '[' || ch == ']') 
     { 
      input.get(); 
      wstring str(&ch); 
      tokens.push_back(Token(SYMBOL, str)); 
     } 
     else if (ch == '"') 
     { 
      wstringstream accum; 
      input.get(); 

      while(input.peek() != '"') 
      { 
       if(input.peek() == std::char_traits<char>::eof()) 
        endProgram(L"Unterminated String Literal"); 

       accum<<input.peek(); 
       input.get(); 
      } 

      tokens.push_back(Token(STRING, accum.str())); 
     } 
    } 

    for(int i = 0; i < tokens.size(); i++) 
    { 
     wcout<<tokens.at(i).getData()<<endl; 
    } 

    return tokens; 
} 

然而,當我在這樣

] ] 
"ddsd" 

"sdsd" 

[[]]]]][[ 

文件運行這段代碼,我得到我的錯誤UnterminatedStringLiteral我到底做錯了什麼?順便說一下,我對C++很陌生,所以簡單的解釋會很好。

+0

請注意,失敗結果in.peek()'拼寫'std :: char_traits :: eof()'而不是'-1'。雖然通常使用的是'-1',但並不要求該值爲'-1'。 –

+0

oh生病改變 – Popgalop

+0

我還是得到錯誤 – Popgalop

回答

0

添加更多「令牌」時,您的代碼可能會變得更加複雜。
我建議要麼使用switch聲明:

switch (ch) 
{ 
    case '[': 
     //... 
     break; 
    case ']': 
     //... 
     break; 
// ... 
    default: 
     //... 
     break; 
}; 

或使用帶有函數指針查找表:

typedef (void)(*Function_Pointer_Type)(char ch); 
    struct Lookup_Table_Entry 
    { 
    char token; 
    Function_Pointer_Type token_processor_func; 
    }; 

    static const Lookup_Table_Entry token_table[] = 
    { 
    { '[', Open_Bracket_Handler}, 
    { ']', Close_Bracket_Handler}, 
    { '\"', String_Delimiter}, 
    }; 
    static const unsigned int token_table_size = 
    sizeof(token_table)/sizeof(token_table[0]); 

    //... 
    for (unsigned int i = 0; i < token_table_size; ++i) 
    { 
    if (ch == token_table[i].token) 
    { 
     token_table[i].token_processor_func(ch); 
     break; 
    } 
    } 

的這兩個代碼片段是更清潔和可處理的情況下一個字符不是令牌。

表查找允許更容易地擴展代碼,應該添加更多的標記。

+1

但是仍然沒有解決我目前的問題 – Popgalop

0

我做了這樣的代碼,這些..

/// if(*parm_data == ' ' || *parm_data == ';' || *parm_data == '|' 
    // || *parm_data == '\t' || *parm_data == ',') break; 

     char *CHXLog::GetToken(char *parm_data, char *parm_token) 
     { 
      while(*parm_data != 0 && *parm_data != '\n') 
      { 

       if(*parm_data == ',') 
       {  
        break; 
       } 
       else 
       { 
        *parm_token =*parm_data; 
       } 
       parm_data++; 
       parm_token++; 
      } 

      *parm_token = '\0'; 

      return parm_data + 1; 

     } 
+0

我不確定我明白你在做什麼,我不明白這與我的原始代碼有什麼關係 – Popgalop

0

我想通了,我的問題,在此代碼,

 while(input.peek() != '"') 
     { 
      if(input.peek() == std::char_traits<char>::eof()) 
       endProgram(L"Unterminated String Literal"); 

      accum<<input.peek(); 
      input.get(); 
     } 

     tokens.push_back(Token(STRING, accum.str())); 

,應該有一個

input.get(); 

跳過「字符