1

我正在研究一個簡單的數學解析器。東西只是讀取number = 1 + 2;C++向量和分割錯誤

我有一個向量包含這些令牌。它們存儲字符的類型和字符串值。我試圖通過矢量來構建這些令牌的AST,並且我始終得到分段錯誤,即使在我的代碼應該阻止這種情況發生的印象之下。

這裏是代碼位,用於構建AST:

struct ASTGen 
{ 
    const vector<Token>   &Tokens; 
    unsigned int     size, 
            pointer; 

    ASTGen(const vector<Token> &t) : Tokens(t), pointer(0) 
    { 
     size = Tokens.size() - 1; 
    } 

    unsigned int next() 
    { 
     return pointer + 1; 
    } 

    Node* Statement() 
    { 
     if(next() <= size) 
     { 
      switch(Tokens[next()].type) 
      { 
       case EQUALS 
       : 
        Node* n = Assignment_Expr(); 
        return n; 
      } 
     } 

     advance(); 
    } 

    void advance() 
    { 
     if(next() <= size) ++pointer; 
    } 

    Node* Assignment_Expr() 
    { 
     Node* lnode = new Node(Tokens[pointer], NULL, NULL); 
     advance(); 
     Node* n = new Node(Tokens[pointer], lnode, Expression()); 
     return n; 
    } 

    Node* Expression() 
    { 
     if(next() <= size) 
     {       
      advance(); 
      if(Tokens[next()].type == SEMICOLON) 
      { 
       Node* n = new Node(Tokens[pointer], NULL, NULL); 
       return n; 
      } 

      if(Tokens[next()].type == PLUS) 
      { 
       Node* lnode = new Node(Tokens[pointer], NULL, NULL); 
       advance(); 
       Node* n = new Node(Tokens[pointer], lnode, Expression()); 
       return n; 
      } 
     } 
    } 
}; 

...

ASTGen AST(Tokens); 
Node* Tree = AST.Statement(); 
cout << Tree->Right->Data.svalue << endl; 

我可以訪問Tree->Data.svalue,並得到了=節點的令牌信息,所以我知道該節點是越來越催生,我也可以得到Tree->Left->Data.svalue並得到左邊的變量=

我已經重新編寫了很多次嘗試,通過矢量踩着不同的方法,但我總是得到一個分段錯誤,當我嘗試訪問=右節點(這應該是+節點)

任何幫助不勝感激。

回答

4

還有很多我們還沒有看到的代碼,所以我不能準確地告訴你發生了什麼事情,但我看到一些引起關注的原因。一個是Statement()方法並不總是返回一個值。如果第一個if測試未通過,那麼我們調用advance()並且在沒有明確返回的情況下從例程的底部落下。調用者將嘗試獲取函數的返回值,但它會得到垃圾。這可能會導致各種各樣的問題,包括諸如雙重調用free()等,這很容易導致段錯誤。

Expression()也有同樣的問題。

+1

他的'Expression()'函數也有不返回值的代碼路徑。 – Blastfurnace 2012-04-08 05:38:55

+0

是的,它的確如此! – 2012-04-08 05:40:23

+0

我確實意識到這一點,但現在我並不擔心,因爲這應該正確地對付數字= 1 + 2;或至少這是希望。一旦我能夠解決這個測試案例,我將完成其他控制路徑。 – grep 2012-04-08 05:44:18