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