2009-12-02 5 views
0

J'écris un compilateur pour une petite langue, et ma classe Parser est actuellement en charge de la construction d'un AST pour une utilisation ultérieure. Cependant, les expressions récursives ne fonctionnent pas correctement car le vecteur dans chaque noeud AST qui contient des nœuds enfants ne fonctionne pas correctement. Actuellement le fichier d'en-tête de mon AST ressemble à ceci:Quel est le bogue du constructeur de copie provoquant des erreurs d'analyse?

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

Voici le code d'analyse d'expression qui pose problème:

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

Un exemple d'expression qui ne fonctionne pas est + 1 + 2 + 3 4. Il faut analyser dans un AST comme ceci: + [1, + [2, + [3, 4]], mais j'obtenir ceci: + [1, + []]

Tous les conseils sur ce que je suis-je mal?

+0

Pouvez-vous donner plus de détails sur ce "bug de constructeur de copie"? Êtes-vous en train de dire que si vous avez un 'AST' qui a d'autres' AST's dans 'children' qu'il ne copie pas correctement? Pourquoi avez-vous inclus le code de 'e()' mais pas le constructeur de la copie, si le constructeur de la copie a un bug? –

+0

Je dis copier le constructeur comme une supposition. Je ne suis pas vraiment sûr de ce qui cause le problème, et je pensais que si quelqu'un regardait e(), il pourrait révéler un bug ou un malentendu fondamental de C++ que j'ai négligé. – iand675

Répondre

0

parent.children.push_back(expr) copie l'expression. Par conséquent, il appelle AST::AST(AST const&). Un bug dans cela pourrait certainement causer le problème que vous voyez. Cependant, sans le code, nous ne pouvons pas trouver de bogues.

Questions connexes