I'm trying to create a recursive descent parser. So far I have all the foundation set, I just need to properly implement a few functions to enforce the grammar. I thought everything was right, it looks it, but I guess my Aop
, Expr
, or Term
function is doing something wrong. Sometimes the input stream gets cut off and things aren't recognized. I don't see how though.
Is there any site or source that explains this more in depth, with code examples? Everything I've seen is very generic, which is fine, but I'm stuck on implementation.
NOTE: Edit April 17 2016: My functions were pretty much alright and well structured for the context of my program. The problem I was having, and didn't realize, was that at certain instances when I called getToken I "ate up" characters from the input stream. Sometimes this is fine, other times it wasn't and the input stream needed to be reset. So I simply add a small loop in cases where I needed to put back strings char by char. E.G:
if(t.getType() !=Token::EQOP)
{
//cout<<"You know it" << endl;
int size = t.getLexeme().size();
while(size>0)
{
br->putback(t.getLexeme().at(size-1));
size--;
}
return ex;
}
So with that being said, I pretty much was able to edit my program accordingly and everything worked out once I saw what was eating up the characters.
This is the grammar :
Program::= StmtList
StmtList::= Stmt | StmtList
Stmt::= PRINTKW Aop SC | INTKW VAR SC | STRKW VAR SC | Aop SC
Expr::= Expr PLUSOP Term | Expr MINUSOP Term | Term
Term::= Term STAROP Primary | Primary
Primary::= SCONST | ICONST | VAR | LPAREN Aop RPAREN
Here's the main program with all of the functions: http://pastebin.com/qMB8h8vE
The functions that I seem to be having the most trouble with is AssignmentOperator(Aop)
, Expression(Expr)
, and Term
. I'll list them here.
ParseTree* Aop(istream *br)
{
ParseTree * element = Expr(br);
if(element!=0)
{
if(element->isVariable())
{
Token t= getToken(br);
if(t==Token::EQOP)
{
cout<<"No" << endl;
ParseTree * rhs = Aop(br);
if(rhs==0)
return 0;
else
{
return new AssignOp(element, rhs);
}
}
else
{
return element;
}
}
}
return 0;
}
ParseTree* Expr(istream *br)
{
ParseTree * element = Term(br);
if(element!=0)
{
Token t=getToken(br);
if(t==Token::MINUSOP || t==Token::PLUSOP)
{
if(t==Token::PLUSOP)
{
ParseTree* rhs = Expr(br);
if(rhs==0)
return 0;
else
{
return new AddOp(element, rhs);
}
}
if(t==Token::MINUSOP)
{
ParseTree* rhs = Expr(br);
if(rhs==0)
return 0;
else
{
return new SubtractOp(element, rhs); //or switch the inputs idk
}
}
}
else
{
return element;
}
}
return 0;
}
ParseTree* Term(istream *br)
{
ParseTree *element = Primary(br);
if(element!=0)
{
Token t=getToken(br);
if(t==Token::STAROP)
{
ParseTree* rhs =Term(br);
if(rhs==0)
return 0;
else
{
return new MultiplyOp(element, rhs);
}
}
else
{
return element;
}
}
return 0;
}