私は再帰的降下構文解析プログラムを作成しようとしています。これまでのところ、すべての基礎がありました。文法を強制するためのいくつかの関数を適切に実装するだけです。私はすべてが正しいと思った、それはそれを見ますが、私はAop
、Expr
、またはTerm
機能が何か間違っていると思います。入力ストリームが途切れてしまい、物事が認識されないことがあります。私はしかし、どのように表示されません。BNF文法ルールを実際のC++関数/コードに変換する
詳細については、コード例を参照して説明するサイトまたはソースがありますか?私が見たことはすべて非常に一般的ですが、これは問題ありませんが、私は実装についていません。
注:2016年4月17日編集:私の機能はかなり良く、プログラムのコンテキストのためにうまく構成されていました。私が気付いていた問題は、特定のインスタンスでgetTokenを呼び出すときに入力ストリームから文字を摂取したということでした。場合によってはこれは問題ありませんが、それ以外の場合は入力ストリームをリセットする必要があります。だから、文字列charをcharに戻す必要がある場合には、小さなループを追加するだけです。例えば:
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;
}
だからそれは言われて、私はかなりそれに応じて私のプログラムを編集することができたと私は文字を食べていたものを見たら、すべてが働きました。
これは文法です:
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
は、ここですべての機能を持つ主なプログラムです:私が最もトラブルを抱えているように見えるhttp://pastebin.com/qMB8h8vE
機能がAssignmentOperator(Aop)
、Expression(Expr)
、およびTerm
です。私はここにそれらをリストアップします。
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;
}
人々に読ませたい場合は、コードを(構造に対応した形で)インデントしてください。 – rici
どうすればそれを読むことができますか?ワオ。 –
再帰的降下パーサーの記述方法に関する私の答えを参照してください:http://stackoverflow.com/questions/2245962/is-there-an-alternative-for-flex-bison-that-is-usable-on-8bit -embedded-systems/2336769#2336769 –