pd_grammar.cppGo to the documentation of this file.00001 /** @file pd_merge.cpp grammar data structure */ 00002 00003 00004 /* Pushdown plugin for FAU Discrete Event Systems Library (libfaudes) 00005 00006 Copyright (C) 2013 Stefan Jacobi, Sven Schneider, Anne-Kathrin Hess 00007 00008 */ 00009 00010 #include "pd_grammar.h" 00011 00012 namespace faudes { 00013 00014 /******************************* 00015 * 00016 * Implementation of GrammarSymbol 00017 * 00018 */ 00019 bool GrammarSymbol::operator==(const GrammarSymbol& other) const{ 00020 if (!(*this < other) && !(other < *this)) return true; 00021 return false; 00022 } 00023 00024 bool GrammarSymbol::operator!=(const GrammarSymbol& other) const{ 00025 if (!(*this < other) && !(other < *this)) return false; 00026 return true; 00027 } 00028 00029 /******************************* 00030 * 00031 * Implementation of Terminal 00032 * 00033 */ 00034 00035 std::string Terminal::Str() const{ 00036 return PushdownGenerator::GlobalEventSymbolTablep()->Symbol(mEvent); 00037 } 00038 00039 bool Terminal::IsLambda() const{ 00040 if (PushdownGenerator::GlobalEventSymbolTablep()->Symbol(mEvent).compare(FAUDES_PD_LAMBDA) == 0) 00041 return true; 00042 return false; 00043 } 00044 00045 bool Terminal::operator<(const GrammarSymbol& other) const{ 00046 if(typeid(*this) != typeid(other)) return false; //other is a nonterminal 00047 const Terminal& t = dynamic_cast<const Terminal&>(other); //other is a terminal 00048 return mEvent < t.Event(); 00049 } 00050 00051 Terminal* Terminal::Clone() const{ 00052 00053 Terminal* t = NULL; 00054 try{ 00055 t = new Terminal(*this); 00056 } 00057 catch (std::bad_alloc& ba){ 00058 std::cerr << "bad_alloc caught in Terminal::Clone new Clone(*this): " << ba.what() << std::endl; 00059 } 00060 return t; 00061 } 00062 00063 /******************************* 00064 * 00065 * Implementation of Nonterminal 00066 * 00067 */ 00068 std::string Nonterminal::Str() const{ 00069 std::stringstream s; 00070 std::vector<Idx>::const_iterator it; 00071 s << "(" << mStartState << ", ["; 00072 for(it = mOnStack.begin(); it != mOnStack.end(); it++){ 00073 if(it == mOnStack.begin()){ 00074 s << PushdownGenerator::GlobalStackSymbolTablep()->Symbol(*it); 00075 } 00076 else{ 00077 s << ", " << PushdownGenerator::GlobalStackSymbolTablep()->Symbol(*it); 00078 } 00079 } 00080 s << "]"; 00081 if(mEndState != 0){ 00082 s << ", " << mEndState; 00083 } 00084 s << ")"; 00085 return s.str(); 00086 } 00087 00088 bool Nonterminal::operator<(const GrammarSymbol& other) const{ 00089 if(typeid(*this) != typeid(other)) return true; //other is a terminal 00090 const Nonterminal& nt = dynamic_cast<const Nonterminal&>(other); //other is a nonterminal 00091 if (mStartState < nt.StartState()) return true; 00092 if (mStartState > nt.StartState()) return false; 00093 00094 if (mOnStack.size() < nt.OnStack().size()) return true; //also makes sure that it2 will not go out of bounds 00095 if (nt.OnStack().size() < mOnStack.size()) return false; 00096 00097 std::vector<Idx>::const_iterator it1, it2; 00098 it2 = nt.OnStack().begin(); 00099 for(it1 = mOnStack.begin(); it1 != mOnStack.end(); it1++){ 00100 if(*it1 < *it2) return true; 00101 if(*it2 < *it1) return false; 00102 it2++; 00103 } 00104 00105 if (mEndState < nt.EndState()) return true; 00106 return false; 00107 } 00108 00109 Nonterminal* Nonterminal::Clone() const{ 00110 Nonterminal* nt = NULL; 00111 try{ 00112 nt = new Nonterminal(*this); 00113 } 00114 catch (std::bad_alloc& ba){ 00115 std::cerr << "bad_alloc caught in Nonterminal::Clone new Clone(*this): " << ba.what() << std::endl; 00116 } 00117 return nt; 00118 } 00119 00120 /******************************* 00121 * 00122 * Implementation of CompareGsVector 00123 * 00124 */ 00125 00126 bool CompareGsVector(const GrammarSymbolVector& lhs, const GrammarSymbolVector& rhs){ 00127 if (lhs.size() < rhs.size()) return true; //also makes sure that it2 will not go out of bounds 00128 if (rhs.size() < lhs.size()) return false; 00129 00130 GrammarSymbolVector::const_iterator it1, it2; 00131 it2 = rhs.begin(); 00132 for(it1 = lhs.begin(); it1 != lhs.end(); it1++){ 00133 if(**it1 < **it2) return true; 00134 if(**it2 < **it1) return false; 00135 it2++; 00136 } 00137 return false; 00138 } 00139 00140 /******************************* 00141 * 00142 * Implementation of EqualsGsVector 00143 * 00144 */ 00145 bool EqualsGsVector(const GrammarSymbolVector& lhs, const GrammarSymbolVector& rhs){ 00146 return(!CompareGsVector(lhs,rhs) && !CompareGsVector(rhs,lhs)); 00147 } 00148 00149 /******************************* 00150 * 00151 * Implementation of CompareGs 00152 * 00153 */ 00154 00155 bool CompareGs(const GrammarSymbolPtr& lhs, const GrammarSymbolPtr& rhs){ 00156 return *lhs < *rhs; 00157 } 00158 00159 /* ************************* 00160 * ContainsWord 00161 * *************************/ 00162 bool ContainsWord(const GrammarSymbolWordSet& set, const GrammarSymbolVector& word){ 00163 00164 GrammarSymbolWordSet::const_iterator setit; 00165 GrammarSymbolVector::const_iterator gsit1, gsit2; 00166 bool found = false; 00167 00168 //iterate over the word set and look for the word 00169 for(setit = set.begin(); setit != set.end(); setit++){ 00170 00171 //sizes are the same so this word is a candidate 00172 if(setit->size() == word.size()){ 00173 00174 found = true; 00175 00176 //compare the words' symbols 00177 gsit2 = word.begin(); 00178 for(gsit1 = setit->begin(); gsit1 != setit->end(); gsit1++){ 00179 00180 //symbols were not the same, this is not the word we are looking for 00181 if(**gsit1 != **gsit2){ 00182 found = false; 00183 break; 00184 } 00185 gsit2++; 00186 } 00187 //the word was found and no further search is necessary 00188 if(found){ 00189 break; 00190 } 00191 } 00192 } 00193 return found; 00194 } 00195 /******************************* 00196 * 00197 * Implementation of GrammarProduction 00198 * 00199 */ 00200 00201 std::string GrammarProduction::Str() const{ 00202 std::stringstream s; 00203 s << mLhs.Str() << " --> "; 00204 GrammarSymbolVector::const_iterator it; 00205 for(it = mRhs.begin(); it < mRhs.end(); it++){ 00206 s << (*it)->Str(); 00207 } 00208 return s.str();; 00209 } 00210 00211 bool GrammarProduction::operator<(const GrammarProduction& other) const{ 00212 if (mLhs < other.Lhs()) return true; 00213 if (other.Lhs() < mLhs) return false; 00214 if(CompareGsVector(mRhs,other.Rhs())) return true; 00215 // if (mRhs.size() < other.Rhs().size()) return true; //also makes sure that it2 will not go out of bounds 00216 // if (other.Rhs().size() < mRhs.size()) return false; 00217 // 00218 // std::vector<GrammarSymbol*>::const_iterator it1, it2; 00219 // it2 = other.Rhs().begin(); 00220 // for(it1 = mRhs.begin(); it1 != mRhs.end(); it1++){ 00221 // if(**it1 < **it2) return true; 00222 // if(**it2 < **it1) return false; 00223 // it2++; 00224 // } 00225 return false; 00226 } 00227 00228 00229 /******************************* 00230 * 00231 * Implementation of Grammar 00232 * 00233 */ 00234 00235 bool Grammar::SetStartSymbol(const Nonterminal& s){ 00236 mStartSymbol = s; 00237 return mNonterminals.insert(s).second; 00238 } 00239 00240 bool Grammar::InsTerminal(const Terminal& t){ 00241 return mTerminals.insert(t).second; 00242 } 00243 00244 void Grammar::InsTerminals(const std::set<Terminal>& t){ 00245 mTerminals.insert(t.begin(),t.end()); 00246 } 00247 00248 bool Grammar::InsNonterminal(const Nonterminal& nt){ 00249 return mNonterminals.insert(nt).second; 00250 } 00251 00252 void Grammar::InsNonterminals(const std::set<Nonterminal>& nt){ 00253 mNonterminals.insert(nt.begin(),nt.end()); 00254 } 00255 00256 bool Grammar::InsGrammarProduction(const GrammarProduction& gp){ 00257 00258 //check lefthand side for validity 00259 if(mNonterminals.find(gp.Lhs()) == mNonterminals.end()) { 00260 std::stringstream errstr; 00261 errstr << "Grammar symbol mismatch: Lefthand-side nonterminal " << gp.Lhs().Str() << " does not exist in grammar." <<std::endl; 00262 throw Exception("Grammar::InsGrammarProduction", errstr.str(), 1001); 00263 } 00264 00265 //check righthand side for validity 00266 GrammarSymbolVector::const_iterator gsit; 00267 for(gsit = gp.Rhs().begin(); gsit != gp.Rhs().end(); gsit ++){ 00268 00269 //check nonterminals 00270 ConstNonterminalPtr nt = std::tr1::dynamic_pointer_cast<const Nonterminal>(*gsit); 00271 if(nt != NULL){ 00272 if(mNonterminals.find(*nt) == mNonterminals.end()) { 00273 std::stringstream errstr; 00274 errstr << "Grammar symbol mismatch: Righthand-side nonterminal " << nt->Str() << " does not exist in grammar." <<std::endl; 00275 throw Exception("Grammar::InsGrammarProduction", errstr.str(), 1001); 00276 } 00277 } 00278 //check terminals 00279 ConstTerminalPtr t = std::tr1::dynamic_pointer_cast<const Terminal>(*gsit); 00280 if(t != NULL){ 00281 if(mTerminals.find(*t) == mTerminals.end()) { 00282 std::stringstream errstr; 00283 errstr << "Grammar symbol mismatch: Righthand-side terminal " << t->Str() << " does not exist in grammar." <<std::endl; 00284 throw Exception("Grammar::InsGrammarProduction", errstr.str(), 1001); 00285 } 00286 } 00287 } 00288 00289 return mGrammarProductions.insert(gp).second; 00290 } 00291 00292 void Grammar::InsGrammarProductions(const std::set<GrammarProduction>& gp){ 00293 std::set<GrammarProduction>::const_iterator gpit; 00294 for(gpit = gp.begin(); gpit != gp.end(); gpit++){ 00295 InsGrammarProduction(*gpit); 00296 } 00297 } 00298 00299 std::set<Terminal>::const_iterator Grammar::TerminalsBegin() const{ 00300 return mTerminals.begin(); 00301 } 00302 00303 std::set<Terminal>::const_iterator Grammar::TerminalsEnd() const{ 00304 return mTerminals.end(); 00305 } 00306 00307 std::set<Nonterminal>::const_iterator Grammar::NonterminalsBegin() const{ 00308 return mNonterminals.begin(); 00309 } 00310 00311 std::set<Nonterminal>::const_iterator Grammar::NonterminalsEnd() const{ 00312 return mNonterminals.end(); 00313 } 00314 00315 std::set<GrammarProduction>::const_iterator Grammar::GrammarProductionsBegin() const{ 00316 return mGrammarProductions.begin(); 00317 } 00318 00319 std::set<GrammarProduction>::const_iterator Grammar::GrammarProductionsEnd() const{ 00320 return mGrammarProductions.end(); 00321 } 00322 00323 std::string Grammar::StrTerminals() const{ 00324 std::string s; 00325 std::set<Terminal>::const_iterator it; 00326 it = mTerminals.end(); 00327 for(it = mTerminals.begin(); it != mTerminals.end(); it++){ 00328 if(it == mTerminals.begin()) s+= it->Str(); 00329 else s+= ", " + it->Str(); 00330 } 00331 return s; 00332 } 00333 00334 std::string Grammar::StrNonterminals() const{ 00335 std::string s; 00336 std::set<Nonterminal>::const_iterator it; 00337 it = mNonterminals.end(); 00338 for(it = mNonterminals.begin(); it != mNonterminals.end(); it++){ 00339 if(it == mNonterminals.begin()) s+= it->Str(); 00340 else s+= ", " + it->Str(); 00341 } 00342 return s; 00343 } 00344 00345 std::string Grammar::StrStartSymbol() const{ 00346 return mStartSymbol.Str(); 00347 } 00348 00349 std::string Grammar::StrGrammarProductions() const{ 00350 std::string s; 00351 std::set<GrammarProduction>::const_iterator it; 00352 it = mGrammarProductions.end(); 00353 for(it = mGrammarProductions.begin(); it != mGrammarProductions.end(); it++){ 00354 s+= "\n " + it->Str(); 00355 } 00356 return s; 00357 } 00358 00359 std::string Grammar::Str() const{ 00360 std::string s; 00361 00362 s += "start symbol: " + StrStartSymbol() + "\n"; 00363 s += "nonterminals: " + StrNonterminals() + "\n"; 00364 s += "terminals: " + StrTerminals() + "\n"; 00365 s += "grammar productions: " + StrGrammarProductions() + "\n"; 00366 00367 return s; 00368 00369 } 00370 00371 } // namespace faudes 00372 libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen |