pd_grammar.cpp
Go to the documentation of this file.
1 /** @file pd_merge.cpp grammar data structure */
2 
3 
4 /* Pushdown plugin for FAU Discrete Event Systems Library (libfaudes)
5 
6  Copyright (C) 2013 Stefan Jacobi, Sven Schneider, Anne-Kathrin Hess
7 
8 */
9 
10 #include "pd_grammar.h"
11 
12 namespace faudes {
13 
14 /*******************************
15 *
16 * Implementation of GrammarSymbol
17 *
18 */
19 bool GrammarSymbol::operator==(const GrammarSymbol& other) const{
20  if (!(*this < other) && !(other < *this)) return true;
21  return false;
22 }
23 
24 bool GrammarSymbol::operator!=(const GrammarSymbol& other) const{
25  if (!(*this < other) && !(other < *this)) return false;
26  return true;
27 }
28 
29 /*******************************
30 *
31 * Implementation of Terminal
32 *
33 */
34 
35 std::string Terminal::Str() const{
37 }
38 
39 bool Terminal::IsLambda() const{
41  return true;
42  return false;
43 }
44 
45 bool Terminal::operator<(const GrammarSymbol& other) const{
46  if(typeid(*this) != typeid(other)) return false; //other is a nonterminal
47  const Terminal& t = dynamic_cast<const Terminal&>(other); //other is a terminal
48  return mEvent < t.Event();
49 }
50 
52 
53  Terminal* t = NULL;
54  try{
55  t = new Terminal(*this);
56  }
57  catch (std::bad_alloc& ba){
58  std::cerr << "bad_alloc caught in Terminal::Clone new Clone(*this): " << ba.what() << std::endl;
59  }
60  return t;
61 }
62 
63 /*******************************
64 *
65 * Implementation of Nonterminal
66 *
67 */
68 std::string Nonterminal::Str() const{
69  std::stringstream s;
70  std::vector<Idx>::const_iterator it;
71  s << "(" << mStartState << ", [";
72  for(it = mOnStack.begin(); it != mOnStack.end(); it++){
73  if(it == mOnStack.begin()){
75  }
76  else{
78  }
79  }
80  s << "]";
81  if(mEndState != 0){
82  s << ", " << mEndState;
83  }
84  s << ")";
85  return s.str();
86 }
87 
88 bool Nonterminal::operator<(const GrammarSymbol& other) const{
89  if(typeid(*this) != typeid(other)) return true; //other is a terminal
90  const Nonterminal& nt = dynamic_cast<const Nonterminal&>(other); //other is a nonterminal
91  if (mStartState < nt.StartState()) return true;
92  if (mStartState > nt.StartState()) return false;
93 
94  if (mOnStack.size() < nt.OnStack().size()) return true; //also makes sure that it2 will not go out of bounds
95  if (nt.OnStack().size() < mOnStack.size()) return false;
96 
97  std::vector<Idx>::const_iterator it1, it2;
98  it2 = nt.OnStack().begin();
99  for(it1 = mOnStack.begin(); it1 != mOnStack.end(); it1++){
100  if(*it1 < *it2) return true;
101  if(*it2 < *it1) return false;
102  it2++;
103  }
104 
105  if (mEndState < nt.EndState()) return true;
106  return false;
107 }
108 
110  Nonterminal* nt = NULL;
111  try{
112  nt = new Nonterminal(*this);
113  }
114  catch (std::bad_alloc& ba){
115  std::cerr << "bad_alloc caught in Nonterminal::Clone new Clone(*this): " << ba.what() << std::endl;
116  }
117  return nt;
118 }
119 
120 /*******************************
121 *
122 * Implementation of CompareGsVector
123 *
124 */
125 
127  if (lhs.size() < rhs.size()) return true; //also makes sure that it2 will not go out of bounds
128  if (rhs.size() < lhs.size()) return false;
129 
130  GrammarSymbolVector::const_iterator it1, it2;
131  it2 = rhs.begin();
132  for(it1 = lhs.begin(); it1 != lhs.end(); it1++){
133  if(**it1 < **it2) return true;
134  if(**it2 < **it1) return false;
135  it2++;
136  }
137  return false;
138 }
139 
140 /*******************************
141 *
142 * Implementation of EqualsGsVector
143 *
144 */
146  return(!CompareGsVector(lhs,rhs) && !CompareGsVector(rhs,lhs));
147 }
148 
149 /*******************************
150 *
151 * Implementation of CompareGs
152 *
153 */
154 
155 bool CompareGs(const GrammarSymbolPtr& lhs, const GrammarSymbolPtr& rhs){
156  return *lhs < *rhs;
157 }
158 
159 /* *************************
160  * ContainsWord
161  * *************************/
163 
164  GrammarSymbolWordSet::const_iterator setit;
165  GrammarSymbolVector::const_iterator gsit1, gsit2;
166  bool found = false;
167 
168  //iterate over the word set and look for the word
169  for(setit = set.begin(); setit != set.end(); setit++){
170 
171  //sizes are the same so this word is a candidate
172  if(setit->size() == word.size()){
173 
174  found = true;
175 
176  //compare the words' symbols
177  gsit2 = word.begin();
178  for(gsit1 = setit->begin(); gsit1 != setit->end(); gsit1++){
179 
180  //symbols were not the same, this is not the word we are looking for
181  if(**gsit1 != **gsit2){
182  found = false;
183  break;
184  }
185  gsit2++;
186  }
187  //the word was found and no further search is necessary
188  if(found){
189  break;
190  }
191  }
192  }
193  return found;
194 }
195 /*******************************
196 *
197 * Implementation of GrammarProduction
198 *
199 */
200 
201 std::string GrammarProduction::Str() const{
202  std::stringstream s;
203  s << mLhs.Str() << " --> ";
204  GrammarSymbolVector::const_iterator it;
205  for(it = mRhs.begin(); it < mRhs.end(); it++){
206  s << (*it)->Str();
207  }
208  return s.str();;
209 }
210 
212  if (mLhs < other.Lhs()) return true;
213  if (other.Lhs() < mLhs) return false;
214  if(CompareGsVector(mRhs,other.Rhs())) return true;
215 // if (mRhs.size() < other.Rhs().size()) return true; //also makes sure that it2 will not go out of bounds
216 // if (other.Rhs().size() < mRhs.size()) return false;
217 //
218 // std::vector<GrammarSymbol*>::const_iterator it1, it2;
219 // it2 = other.Rhs().begin();
220 // for(it1 = mRhs.begin(); it1 != mRhs.end(); it1++){
221 // if(**it1 < **it2) return true;
222 // if(**it2 < **it1) return false;
223 // it2++;
224 // }
225  return false;
226 }
227 
228 
229 /*******************************
230 *
231 * Implementation of Grammar
232 *
233 */
234 
236  mStartSymbol = s;
237  return mNonterminals.insert(s).second;
238 }
239 
241  return mTerminals.insert(t).second;
242 }
243 
244 void Grammar::InsTerminals(const std::set<Terminal>& t){
245  mTerminals.insert(t.begin(),t.end());
246 }
247 
249  return mNonterminals.insert(nt).second;
250 }
251 
252 void Grammar::InsNonterminals(const std::set<Nonterminal>& nt){
253  mNonterminals.insert(nt.begin(),nt.end());
254 }
255 
257 
258  //check lefthand side for validity
259  if(mNonterminals.find(gp.Lhs()) == mNonterminals.end()) {
260  std::stringstream errstr;
261  errstr << "Grammar symbol mismatch: Lefthand-side nonterminal " << gp.Lhs().Str() << " does not exist in grammar." <<std::endl;
262  throw Exception("Grammar::InsGrammarProduction", errstr.str(), 1001);
263  }
264 
265  //check righthand side for validity
266  GrammarSymbolVector::const_iterator gsit;
267  for(gsit = gp.Rhs().begin(); gsit != gp.Rhs().end(); gsit ++){
268 
269  //check nonterminals
270  ConstNonterminalPtr nt = std::dynamic_pointer_cast<const Nonterminal>(*gsit);
271  if(nt){
272  if(mNonterminals.find(*nt) == mNonterminals.end()) {
273  std::stringstream errstr;
274  errstr << "Grammar symbol mismatch: Righthand-side nonterminal " << nt->Str() << " does not exist in grammar." <<std::endl;
275  throw Exception("Grammar::InsGrammarProduction", errstr.str(), 1001);
276  }
277  }
278  //check terminals
279  ConstTerminalPtr t = std::dynamic_pointer_cast<const Terminal>(*gsit);
280  if(t){
281  if(mTerminals.find(*t) == mTerminals.end()) {
282  std::stringstream errstr;
283  errstr << "Grammar symbol mismatch: Righthand-side terminal " << t->Str() << " does not exist in grammar." <<std::endl;
284  throw Exception("Grammar::InsGrammarProduction", errstr.str(), 1001);
285  }
286  }
287  }
288 
289  return mGrammarProductions.insert(gp).second;
290 }
291 
292 void Grammar::InsGrammarProductions(const std::set<GrammarProduction>& gp){
293  std::set<GrammarProduction>::const_iterator gpit;
294  for(gpit = gp.begin(); gpit != gp.end(); gpit++){
295  InsGrammarProduction(*gpit);
296  }
297 }
298 
299 std::set<Terminal>::const_iterator Grammar::TerminalsBegin() const{
300  return mTerminals.begin();
301 }
302 
303 std::set<Terminal>::const_iterator Grammar::TerminalsEnd() const{
304  return mTerminals.end();
305 }
306 
307 std::set<Nonterminal>::const_iterator Grammar::NonterminalsBegin() const{
308  return mNonterminals.begin();
309 }
310 
311 std::set<Nonterminal>::const_iterator Grammar::NonterminalsEnd() const{
312  return mNonterminals.end();
313 }
314 
315 std::set<GrammarProduction>::const_iterator Grammar::GrammarProductionsBegin() const{
316  return mGrammarProductions.begin();
317 }
318 
319 std::set<GrammarProduction>::const_iterator Grammar::GrammarProductionsEnd() const{
320  return mGrammarProductions.end();
321 }
322 
323 std::string Grammar::StrTerminals() const{
324  std::string s;
325  std::set<Terminal>::const_iterator it;
326  it = mTerminals.end();
327  for(it = mTerminals.begin(); it != mTerminals.end(); it++){
328  if(it == mTerminals.begin()) s+= it->Str();
329  else s+= ", " + it->Str();
330  }
331  return s;
332 }
333 
334 std::string Grammar::StrNonterminals() const{
335  std::string s;
336  std::set<Nonterminal>::const_iterator it;
337  it = mNonterminals.end();
338  for(it = mNonterminals.begin(); it != mNonterminals.end(); it++){
339  if(it == mNonterminals.begin()) s+= it->Str();
340  else s+= ", " + it->Str();
341  }
342  return s;
343 }
344 
345 std::string Grammar::StrStartSymbol() const{
346  return mStartSymbol.Str();
347 }
348 
349 std::string Grammar::StrGrammarProductions() const{
350  std::string s;
351  std::set<GrammarProduction>::const_iterator it;
352  it = mGrammarProductions.end();
353  for(it = mGrammarProductions.begin(); it != mGrammarProductions.end(); it++){
354  s+= "\n " + it->Str();
355  }
356  return s;
357 }
358 
359 std::string Grammar::Str() const{
360  std::string s;
361 
362  s += "start symbol: " + StrStartSymbol() + "\n";
363  s += "nonterminals: " + StrNonterminals() + "\n";
364  s += "terminals: " + StrTerminals() + "\n";
365  s += "grammar productions: " + StrGrammarProductions() + "\n";
366 
367  return s;
368 
369 }
370 
371 
372 
373 } // namespace faudes
374 

libFAUDES 2.28c --- 2016.09.30 --- c++ api documentaion by doxygen