Yinelemeli bir yoklama ayrıştırıcısı oluşturmaya çalışıyorum. Şimdiye kadar tüm temel setlere sahibim, dilbilgisini zorlamak için sadece birkaç işlevi yerine getirmem gerekiyor. Her şeyin doğru olduğunu düşündüm, öyle görünüyor, ama sanırım Aop
, Expr
veya Term
işlevlerim yanlış bir şey yapıyor. Bazen giriş akışı kesilir ve işler tanınmaz. Nasıl olduğunu göremiyorum.BNF dilbilgisi kurallarını gerçek C++ işlevlerine/koduna dönüştürme
Kod örnekleri ile bunu daha ayrıntılı olarak açıklayan herhangi bir site veya kaynak var mı? Gördüğüm her şey çok genel, ki bu iyi, ama uygulamaya takılıyorum.
NOT: 17 Nisan 2016'yı düzenle: İşlevlerim, programımın içeriği için oldukça iyi ve iyi yapılandırılmıştı. Anladığım ve fark etmediğim sorun, getToken'i çağırdığım bazı durumlarda giriş akışından gelen karakterleri "yedim" idi. Bazen bu iyi, diğer zamanlarda değildi ve giriş akışının sıfırlanması gerekiyordu. Bu yüzden karakterleri char char ile arkamıza koymam gerektiği durumlarda küçük bir döngü ekliyorum. Örneğin: bununla
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;
}
Yani
söyleniyor, hemen hemen ben buna göre programımı düzenlemek mümkün oldu ve karakterleri yiyip bitiriyordu gördükten sonra her şey çalıştı.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
İşte tüm fonksiyonlarında azalmaya ana program var: Ben AssignmentOperator(Aop)
olduğu ile Expression(Expr)
en fazla sorun yaşıyor gibisin http://pastebin.com/qMB8h8vE
işlevleri ve Term
Bu
dilbilgisi olduğunu . Onları burada listeleyeceğim. Bir recusrive iniş ayrıştırıcı yazmak içinParseTree* 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;
}
İnsanların okumasını istiyorsanız, lütfen kodunuzu (yapıya uygun bir şekilde) girin. – rici
_you_ nasıl okuyabilir? Vay. –
Özyineli soy ayrıştırıcılarının nasıl yazılacağına dair cevabımı görün: http://stackoverflow.com/questions/2245962/is-there-an-alternative-for-flex-bison-that-is-usable-on-8-bit -embedded-systems/2336769 # 2336769 –