Pergunta

Estou escrevendo um compilador para um pequeno idioma, e minha classe de analisador está atualmente encarregada de construir um AST para uso posteriormente. No entanto, expressões recursivas não estão funcionando corretamente porque o vetor em cada nó AST que detém nós filhos não está funcionando corretamente. Atualmente, o arquivo de cabeçalho do meu AST é assim:

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);
    ASTtype getNodeType();
    std::string text;
    ASTtype nodeType;
    int size;
    scalarType evalType;
    std::vector<AST> children;
};

Aqui está o código de análise de expressão que está causando problemas:

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);
}

Um exemplo de expressão que não funciona é + 1 + 2 + 3 4. Ele deve analisar um AST assim: + [1, + [2, + [3, 4]], mas, em vez disso, eu entendo: + [ 1, + []

Algum conselho sobre o que estou fazendo de errado?

Foi útil?

Solução

parent.children.push_back(expr) copia a expressão. Portanto, liga AST::AST(AST const&). Um bug nisso certamente poderia causar o problema que você vê. No entanto, sem o código, não podemos encontrar bugs nele.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top