2011-06-01 28 views
2

我正在開發非常基本的ISA的彙編程序。目前,我正在實現解析器功能,並使用字符串流來抓取行中的單詞。下面是彙編代碼示例:避免從字符串流中攫取任何東西

; This program counts from 10 to 0 
     .ORIG x3000 
     LEA R0, TEN  ; This instruction will be loaded into memory location x3000 
     LDW R1, R0, #0 
START ADD R1, R1, #-1 
     BRZ DONE 
     BR START 
         ; blank line 
DONE TRAP x25  ; The last executable instruction 
TEN  .FILL x000A ; This is 10 in 2's comp, hexadecimal 
     .END 

不要擔心彙編代碼的性質,只需看第3行,右邊有註釋。我的解析器函數是不完整的,但這裏是我有:

// Define three conditions to code 
enum {DONE, OK, EMPTY_LINE}; 
// Tuple containing a condition and a string vector 
typedef tuple<int,vector<string>> Code; 

// Passed an alias to a string 
// Parses the line passed to it 
Code ReadAndParse(string& line) 
{ 

    /***********************************************/ 
    /****************REMOVE COMMENTS****************/ 
    /***********************************************/ 
    // Sentinel to flag down position of first 
    // semicolon and the index position itself 
    bool found = false; 
    size_t semicolonIndex = -1; 

    // Convert the line to lowercase 
    for(int i = 0; i < line.length(); i++) 
    { 
     line[i] = tolower(line[i]); 

     // Find first semicolon 
     if(line[i] == ';' && !found) 
     { 
      semicolonIndex = i; 
      // Throw the flag 
      found = true; 
     } 
    } 

    // Erase anything to and from semicolon to ignore comments 
    if(found != false) 
     line.erase(semicolonIndex); 


    /***********************************************/ 
    /*****TEST AND SEE IF THERE'S ANYTHING LEFT*****/ 
    /***********************************************/ 

    // To snatch and store words 
    Code code; 
    string token; 
    stringstream ss(line); 
    vector<string> words; 

    // While the string stream is still of use 
    while(ss.good()) 
    { 
     // Send the next string to the token 
     ss >> token; 
     // Push it onto the words vector 
     words.push_back(token); 

     // If all we got was nothing, it's an empty line 
     if(token == "") 
     { 
      code = make_tuple(EMPTY_LINE, words); 
      return code; 
     } 
    } 

    /***********************************************/ 
    /***********DETERMINE OUR TYPE OF CODE**********/ 
    /***********************************************/ 


    // At this point it should be fine 
    code = make_tuple(OK, words); 
    return code; 
} 

正如你所看到的,法典元組包含在枚舉decleration和矢量包含在該行的所有單詞所代表的條件。我想要的是將每行中的每個單詞推入矢量中然後返回。

問題出現在函數的第三次調用(彙編代碼的第三行)上。我使用ss.good()函數來確定在字符串流中是否有任何單詞。出於某種原因,即使第三行中沒有第四個單詞,ss.good()函數也會返回true,並且我最終將[lea] [r0,] [ten]和[ten]這兩個單詞推入向量中。 ss.good()對於第四次調用是真實的,並且令牌沒有收到任何東西,因此我將[ten]推入向量兩次。

我注意到如果我刪除分號和最後一個單詞之間的空格,則不會發生此錯誤。我想知道如何獲得正確的數字推入向量。

請不要推薦Boost庫。我喜歡這個圖書館,但我想保持這個項目的簡單。這沒什麼大不了的,這個處理器只有十幾個指令。另外,請記住,這個功能只是一半,我正在逐步測試和調試它。

回答

5

流的錯誤標誌只在之後得到設置條件(例如到達流尾)已經發生。

嘗試用更換您的循環條件:

while(ss >> token) 
{ 
    // Push it onto the words vector 
    words.push_back(token); 

    // If all we got was nothing, it's an empty line 
    if(token == "") 
    { 
     code = make_tuple(EMPTY_LINE, words); 
     return code; 
    } 
} 

有了這個代碼,我得到了3線以下令牌:

"LEA" 
"R0," 
"TEN" 
";" 
"This" 
"instruction" 
"will" 
"be" 
"loaded" 
"into" 
"memory" 
"location" 
"x3000" 

我知道你在試圖解析語言是簡單的一個。但是,如果您考慮使用專門的工具進行工作,例如flex,那麼您會爲自己做點好事。

+1

+1。哇,不知怎的,直到我發佈我的帖子之前,它都沒有顯示你的帖子。奇怪的。刪除我的,因爲它是愚蠢的。我會補充,但是,看到這個常見問題:http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.2 – 2011-06-01 05:58:58

+1

@Merlyn摩根 - 格雷厄姆:很好的鏈接,謝謝! – NPE 2011-06-01 06:10:02