1

我正在研究一个简单的数学解析器。刚刚读到的东西number = 1 + 2;

我有一个包含这些标记的向量。它们存储字符的类型和字符串值。我试图逐步通过向量来构建这些令牌的 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

1 回答 1

4

还有很多我们没有看到的代码,所以我不能准确地告诉你发生了什么,但我看到了一些值得关注的事情。一是 Statement() 方法并不总是返回一个值。如果第一个if测试没有通过,那么我们调用advance()并从例程的底部跌落而没有明确的返回。调用者将尝试获取函数的返回值,但它会得到垃圾。这可能会导致各种问题,包括双重free()调用等,很容易导致段错误。

Expression()有同样的问题。

于 2012-04-08T05:35:37.420 回答