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

まだ見ていないコードがたくさんあるので、何が起こっているのかを正確にお伝えすることはできませんが、懸念すべき理由がいくつか見られます。1 つは、Statement() メソッドが常に値を返すとは限らないことです。最初のifテストに合格しない場合は、呼び出しadvance()て、明示的なリターンなしでルーチンの一番下に落ちます。呼び出し元は関数の戻り値を取得しようとしますが、ガベージが返されます。free()これは、二重呼び出しなど、セグメンテーション違反を簡単に引き起こす可能性のあるものを含む、あらゆる種類の問題につながる可能性があります。

Expression()同じ問題があります。

于 2012-04-08T05:35:37.420 に答える