开发者

What is the copy constructor bug causing parsing errors?

I'm writing a compiler for a small language, and my Parser class is currently in charge of building an AST for use later. However, recursive expressions are not working correctly because the vector in each AST node that holds child nodes are not working correctly. Currently my AST's header file looks like this:

class AST
{
public:
    enum ASTtype {nil, fdecl, pdecl, vdecl, rd, wr, set, rdLV, setLV, exprLV, add, sub, mul, fcall,
        divide, mod, lt, gt, lte, gte, eq, ne, aAnd, aOr, aNot, aNeg, nConst, t, f, vs, dl, loop,
        cond, ss};
    enum scalarType {tNA, tINVALID, tINT, tLONG, tBOOL};
    AST ();
    AST (AST const&);
    AST (ASTtype);
    AST (ASTtype, std::string);
    void addChild(AST);
 开发者_JAVA百科   ASTtype getNodeType();
    std::string text;
    ASTtype nodeType;
    int size;
    scalarType evalType;
    std::vector<AST> children;
};

Here's the expression parsing code that is causing trouble:

void Parser::e(AST& parent)
{
    AST expr;
    AST::ASTtype check = AST::nil;
    bool binOp = false;

    switch (lookahead.type)
    {
        case Lexer::AND    : check = AST::aAnd  ; binOp = true; break; 
        case Lexer::OR     : check = AST::aOr   ; binOp = true; break; 
        case Lexer::NOT    : check = AST::aNot  ; break;
        case Lexer::NEG    : check = AST::aNeg  ; break;
        case Lexer::PLUS   : check = AST::add   ; binOp = true; break;
        case Lexer::MINUS  : check = AST::sub   ; binOp = true; break;
        case Lexer::SPLAT  : check = AST::mul   ; binOp = true; break;
        case Lexer::FSLASH : check = AST::divide; binOp = true; break;
        case Lexer::MOD    : check = AST::mod   ; binOp = true; break;
        case Lexer::EQ     : check = AST::eq    ; binOp = true; break;
        case Lexer::LT     : check = AST::lt    ; binOp = true; break;
        case Lexer::GT     : check = AST::gt    ; binOp = true; break;
        case Lexer::GTE    : check = AST::gte   ; binOp = true; break;
        case Lexer::LTE    : check = AST::lte   ; binOp = true; break;
        case Lexer::NE     : check = AST::ne    ; binOp = true; break;
    }
    if (check != AST::nil && binOp)
    {
        match(lookahead.type);
        expr = AST(check);
        e(expr);
        e(expr);
    } else if (check != AST::nil && !binOp) {
        match(lookahead.type);
        expr = AST(check);
    } else if (lookahead.type == Lexer::IDENT) {

        if (symbols.resolve(lookahead.text).sym_type == symbol::FUNC)
        {
            expr = AST(AST::fcall, lookahead.text);
            match(Lexer::IDENT);
            while (lookahead.type != Lexer::BANG)
            {
                e(expr);
            }
            match(Lexer::BANG);
        } else {
            expr = AST(AST::exprLV);
            lv(expr);
        }
    } else if (lookahead.type == Lexer::T) {
        match(Lexer::T); //true
        expr = AST(AST::t);
    } else if (lookahead.type == Lexer::F) {
        match(Lexer::F); //false
        expr = AST(AST::f);
    } else {
        expr = AST(AST::nConst, lookahead.text);
        match(Lexer::NUM);
    }
    parent.children.push_back(expr);
}

An example expression that doesn't work is + 1 + 2 + 3 4. It should parse into an AST like this: + [1, + [2, + [3, 4]], but instead I get this: + [1, + []]

Any advice on what I'm doing wrong?


parent.children.push_back(expr) copies the expression. Hence, it calls AST::AST(AST const&). A bug in that could certainly cause the problem you see. However, without the code, we can't find bugs in it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜