pd_alg_lrp_test.cpp
Go to the documentation of this file.
1 /** @file pd_alg_lrp_test.cpp Unit Tests */
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 #include "pd_alg_lrp_test.h"
10 
11 namespace faudes {
12 
13 
14 /* *****************
15  * TestGeneratorGotoOneSuccessor
16  * *****************/
18  std::string name = "GeneratorGoto One Successor";
19  TestStart(name);
20 
21  Grammar gr = TestGrammar7();
22 
23  //create terminals
25  GrammarSymbolPtr ptrta(ta);
27  GrammarSymbolPtr ptrtb(tb);
28  Terminal* tdollar = new Terminal(PushdownGenerator::GlobalEventSymbolTablep()->Index("$"));
29  GrammarSymbolPtr ptrtdollar(tdollar);
31  GrammarSymbolPtr ptrtlambda(tlambda);
32 
33  //create nonterminals
34  std::vector<Idx> v;
35  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("dot"));
36  Nonterminal* nt1dot = new Nonterminal(1,v);
37  GrammarSymbolPtr ptrnt1dot(nt1dot);
38 
39  v.clear();
40  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("square"));
41  Nonterminal* nt1square = new Nonterminal(1,v);
42  GrammarSymbolPtr ptrnt1square(nt1square);
43 
44  //test with state ((1, [dot]) -> $(1, [square]) . $, lambda) and symbol $
45  // ((1, [dot]) -> $(1, [square])$ . lambda, lambda)
46  GrammarSymbolVector beforeDot, afterDot;
47  beforeDot.push_back(ptrtdollar);
48  beforeDot.push_back(ptrnt1square);
49  afterDot.push_back(ptrtdollar);
50  Lr1Configuration config(*nt1dot, beforeDot, afterDot, *tlambda);
51 
52  std::set<Lr1Configuration> startState;
53  startState.insert(config);
54 
55  beforeDot.clear();
56  afterDot.clear();
57  beforeDot.push_back(ptrtdollar);
58  beforeDot.push_back(ptrnt1square);
59  beforeDot.push_back(ptrtdollar);
60  afterDot.push_back(ptrtlambda);
61  Lr1Configuration expectedConfig(*nt1dot, beforeDot, afterDot, *tlambda);
62 
63  GotoGenerator gotoGen = Lrm(gr,1);
64  std::set<Idx> successorStates = GeneratorGoto(gotoGen, gotoGen.StateIndex(startState), ptrtdollar);
65  try{
66 
67  //size of successorStates must be one
68  if(successorStates.size() != 1){
69  std::stringstream errstr;
70  errstr << "number of successor states was expected to be 1, but was " << successorStates.size() << "." << std::endl;
71  throw Exception(name, errstr.str(), 1003);
72  }
73 
74  //number of contained configurations must be one
75  if(gotoGen.ConfigSet(*successorStates.begin()).size() != 1){
76  std::stringstream errstr;
77  errstr << "number of configurations in successor state " << *successorStates.begin() << " was expected to be 1, but was " << gotoGen.ConfigSet(*successorStates.begin()).size() << "." << std::endl;
78  throw Exception(name, errstr.str(), 1003);
79  }
80 
81  //the contained configuration must be expectedConfig
82  if(*gotoGen.ConfigSet(*successorStates.begin()).begin() != expectedConfig){
83  std::stringstream errstr;
84  errstr << "configuration contained in successor state " << *successorStates.begin() << " was expected to be (" << expectedConfig.Str() << "), but was (" << gotoGen.ConfigSet(*successorStates.begin()).begin()->Str() << ")." << std::endl;
85  throw Exception(name, errstr.str(), 1003);
86  }
87  }
88  catch (Exception e){
89  }
90  TestEnd(name);
91 }
92 
93 /* *****************
94  * TestGeneratorGotoNoSuccessor
95  * *****************/
97  std::string name = "GeneratorGoto No Successor";
98  TestStart(name);
99 
100  Grammar gr = TestGrammar7();
101 
102  //create terminals
104  GrammarSymbolPtr ptrta(ta);
106  GrammarSymbolPtr ptrtb(tb);
107  Terminal* tdollar = new Terminal(PushdownGenerator::GlobalEventSymbolTablep()->Index("$"));
108  GrammarSymbolPtr ptrtdollar(tdollar);
110  GrammarSymbolPtr ptrtlambda(tlambda);
111 
112  //create nonterminals
113  std::vector<Idx> v;
114  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("dot"));
115  Nonterminal* nt1dot = new Nonterminal(1,v);
116  GrammarSymbolPtr ptrnt1dot(nt1dot);
117 
118  v.clear();
119  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("square"));
120  Nonterminal* nt1square = new Nonterminal(1,v);
121  GrammarSymbolPtr ptrnt1square(nt1square);
122 
123  //test with state ((1, [dot]) -> $(1, [square]) . $, $) and symbol $
124  // empty
125  GrammarSymbolVector beforeDot, afterDot;
126  beforeDot.push_back(ptrtdollar);
127  beforeDot.push_back(ptrnt1square);
128  afterDot.push_back(ptrtdollar);
129  Lr1Configuration config(*nt1dot, beforeDot, afterDot, *tdollar);
130 
131  std::set<Lr1Configuration> startState;
132  startState.insert(config);
133 
134  GotoGenerator gotoGen = Lrm(gr,1);
135 
136  std::set<Idx> successorStates = GeneratorGoto(gotoGen, gotoGen.StateIndex(startState), ptrtdollar);
137 
138  try{
139 
140  //size of successorStates must be zero
141  if(successorStates.size() != 0){
142  std::stringstream errstr;
143  errstr << "number of successor states was expected to be 0, because state with configuration (" << config.Str() << ") does not exist , but was " << successorStates.size() << "." << std::endl;
144  throw Exception(name, errstr.str(), 1003);
145  }
146  }
147  catch (Exception e){
148  }
149 
150  //test with state ((1, [dot]) -> $(1, [square]) . $, lambda) and symbol a
151  // empty
152  beforeDot.clear();
153  afterDot.clear();
154  beforeDot.push_back(ptrtdollar);
155  beforeDot.push_back(ptrnt1square);
156  afterDot.push_back(ptrtdollar);
157  Lr1Configuration config2(*nt1dot, beforeDot, afterDot, *tlambda);
158 
159  startState.clear();
160  startState.insert(config2);
161 
162  successorStates = GeneratorGoto(gotoGen, gotoGen.StateIndex(startState), ptrta);
163 
164  try{
165 
166  //size of successorStates must be zero
167  if(successorStates.size() != 0){
168  std::stringstream errstr;
169  errstr << "number of successor states was expected to be 0, because state with configuration (" << config2.Str() << ") and symbol a does not exist, but was " << successorStates.size() << "." << std::endl;
170  throw Exception(name, errstr.str(), 1003);
171  }
172  }
173  catch (Exception e){
174  }
175  TestEnd(name);
176 }
177 
178 /* *****************
179  * TestGeneratorGotoSeqFull
180  * *****************/
182  std::string name = "GeneratorGotoSeq Full";
183  TestStart(name);
184 
185  Grammar gr = TestGrammar7();
186 
187  //create terminals
189  GrammarSymbolPtr ptrta(ta);
191  GrammarSymbolPtr ptrtb(tb);
192  Terminal* tdollar = new Terminal(PushdownGenerator::GlobalEventSymbolTablep()->Index("$"));
193  GrammarSymbolPtr ptrtdollar(tdollar);
195  GrammarSymbolPtr ptrtlambda(tlambda);
196 
197  //create nonterminals
198  std::vector<Idx> v;
199  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("dot"));
200  Nonterminal* nt1dot = new Nonterminal(1,v);
201  GrammarSymbolPtr ptrnt1dot(nt1dot);
202 
203  v.clear();
204  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("square"));
205  Nonterminal* nt1square = new Nonterminal(1,v);
206  GrammarSymbolPtr ptrnt1square(nt1square);
207 
208  //test with state ((1, [dot]) -> lambda . $(1, [square])$, lambda) and
209  //word $a(1, [square])
210  GrammarSymbolVector beforeDot, afterDot;
211  beforeDot.push_back(ptrtlambda);
212  afterDot.push_back(ptrtdollar);
213  afterDot.push_back(ptrnt1square);
214  afterDot.push_back(ptrtdollar);
215  Lr1Configuration config(*nt1dot, beforeDot, afterDot, *tlambda);
216 
217  std::set<Lr1Configuration> startState;
218  startState.insert(config);
219 
220  GrammarSymbolVector word;
221 
222  word.push_back(ptrtdollar);
223  word.push_back(ptrta);
224  word.push_back(ptrnt1square);
225 
226  //create expected last state of the sequence
227  beforeDot.clear();
228  afterDot.clear();
229  beforeDot.push_back(ptrta);
230  beforeDot.push_back(ptrnt1square);
231  afterDot.push_back(ptrtlambda);
232  Lr1Configuration expectedEndConfig(*nt1square, beforeDot, afterDot, *tdollar);
233 
234  GotoGenerator gotoGen = Lrm(gr,1);
235  std::vector<Idx> stateSequence = GeneratorGotoSeq(gotoGen, gotoGen.StateIndex(startState), word);
236 
237  try{
238 
239  //size of stateSequence must be 3
240  if(stateSequence.size() != 3){
241  std::stringstream errstr;
242  errstr << "number of successor states was expected to be 3, but was " << stateSequence.size() << "." << std::endl;
243  throw Exception(name, errstr.str(), 1003);
244  }
245 
246  //number of contained configurations in the last state must be 1
247  if(gotoGen.ConfigSet(stateSequence.back()).size() != 1){
248  std::stringstream errstr;
249  errstr << "number of configurations in the last state of the sequence was expected to be 1, but was " << gotoGen.ConfigSet(stateSequence.back()).size() << "." << std::endl;
250  throw Exception(name, errstr.str(), 1003);
251  }
252 
253  //the last configuration in the sequence must be expectedEndConfig
254  if(*gotoGen.ConfigSet(stateSequence.back()).begin() != expectedEndConfig){
255  std::stringstream errstr;
256  errstr << "state at the end of the sequence was expected to contain the configuration (" << expectedEndConfig.Str() << "), but was (" << gotoGen.ConfigSet(stateSequence.back()).begin()->Str() << ")." << std::endl;
257  throw Exception(name, errstr.str(), 1003);
258  }
259  }
260  catch (Exception e){
261  }
262  TestEnd(name);
263 }
264 
265 /* *****************
266  * TestGeneratorGotoSeqPartial
267  * *****************/
269  std::string name = "GeneratorGotoSeq Partial";
270  TestStart(name);
271 
272  Grammar gr = TestGrammar7();
273 
274  //create terminals
276  GrammarSymbolPtr ptrta(ta);
278  GrammarSymbolPtr ptrtb(tb);
279  Terminal* tdollar = new Terminal(PushdownGenerator::GlobalEventSymbolTablep()->Index("$"));
280  GrammarSymbolPtr ptrtdollar(tdollar);
282  GrammarSymbolPtr ptrtlambda(tlambda);
283 
284  //create nonterminals
285  std::vector<Idx> v;
286  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("dot"));
287  Nonterminal* nt1dot = new Nonterminal(1,v);
288  GrammarSymbolPtr ptrnt1dot(nt1dot);
289 
290  v.clear();
291  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("square"));
292  Nonterminal* nt1square = new Nonterminal(1,v);
293  GrammarSymbolPtr ptrnt1square(nt1square);
294 
295  //test with state ((1, [dot]) -> lambda . $(1, [square])$, lambda) and
296  //word $b$
297  GrammarSymbolVector beforeDot, afterDot;
298  beforeDot.push_back(ptrtlambda);
299  afterDot.push_back(ptrtdollar);
300  afterDot.push_back(ptrnt1square);
301  afterDot.push_back(ptrtdollar);
302  Lr1Configuration config(*nt1dot, beforeDot, afterDot, *tlambda);
303 
304  std::set<Lr1Configuration> startState;
305  startState.insert(config);
306 
307  GrammarSymbolVector word;
308 
309  word.push_back(ptrtdollar);
310  word.push_back(ptrtb);
311  word.push_back(ptrtdollar);
312 
313  //create expected last state of the sequence
314  beforeDot.clear();
315  afterDot.clear();
316  beforeDot.push_back(ptrtb);
317  afterDot.push_back(ptrtlambda);
318  Lr1Configuration expectedEndConfig(*nt1square, beforeDot, afterDot, *tdollar);
319 
320  GotoGenerator gotoGen = Lrm(gr,1);
321  std::vector<Idx> stateSequence = GeneratorGotoSeq(gotoGen, gotoGen.StateIndex(startState), word);
322 
323  try{
324 
325  //size of stateSequence must be 2
326  if(stateSequence.size() != 2){
327  std::stringstream errstr;
328  errstr << "number of successor states was expected to be 2, but was " << stateSequence.size() << "." << std::endl;
329  throw Exception(name, errstr.str(), 1003);
330  }
331 
332  //number of contained configurations in the last state must be 1
333  if(gotoGen.ConfigSet(stateSequence.back()).size() != 1){
334  std::stringstream errstr;
335  errstr << "number of configurations in the last state of the sequence was expected to be 1, but was " << gotoGen.ConfigSet(stateSequence.back()).size() << "." << std::endl;
336  throw Exception(name, errstr.str(), 1003);
337  }
338 
339  //the last configuration in the sequence must be expectedEndConfig
340  if(*gotoGen.ConfigSet(stateSequence.back()).begin() != expectedEndConfig){
341  std::stringstream errstr;
342  errstr << "state at the end of the sequence was expected to contain the configuration (" << expectedEndConfig.Str() << "), but was (" << gotoGen.ConfigSet(stateSequence.back()).begin()->Str() << ")." << std::endl;
343  throw Exception(name, errstr.str(), 1003);
344  }
345  }
346  catch (Exception e){
347  }
348  TestEnd(name);
349 }
350 
351 /* *****************
352  * TestLrpShiftRulesNumberAndTerminals
353  * *****************/
355  std::string name = "LrpShiftRules Number And Terminals";
356  TestStart(name);
357 
358  Grammar gr = TestGrammar9();
359 
360  //create terminals
362  GrammarSymbolPtr ptrta(ta);
364  GrammarSymbolPtr ptrtb(tb);
365  Terminal* tdollar = new Terminal(PushdownGenerator::GlobalEventSymbolTablep()->Index("$"));
366  GrammarSymbolPtr ptrtdollar(tdollar);
368  GrammarSymbolPtr ptrtlambda(tlambda);
369 
370  //create nonterminals
371  std::vector<Idx> v;
372  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("dot"));
373  Nonterminal* nt1dot = new Nonterminal(1,v);
374  GrammarSymbolPtr ptrnt1dot(nt1dot);
375 
376  v.clear();
377  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("square"));
378  Nonterminal* nt1square = new Nonterminal(1,v);
379  GrammarSymbolPtr ptrnt1square(nt1square);
380 
381  Grammar augGr = Aug(gr, *nt1dot ,*tdollar);
382 
383  GotoGenerator gotoGen = Lrm(augGr, 1);
384  std::set<Lr1ParserAction> actions = LrpShiftRules(gr, augGr, gotoGen, 1);
385 
386  try{
387 
388  //number of found actions must be 4
389  if(actions.size() != 4){
390  std::stringstream errstr;
391  errstr << "number of shift actions was expected to be 4, but was " << actions.size() << "." << std::endl;
392  throw Exception(name, errstr.str(), 1003);
393  }
394  //there must be 2 actions that reduce with terminal a
395  int i = 0;
396  std::set<Lr1ParserAction>::const_iterator pait;
397  for(pait = actions.begin(); pait != actions.end(); pait++){
398  if(pait->Lhs().NextTerminal() == *ta){
399  i++;
400  }
401  }
402  if(i != 2){
403  std::stringstream errstr;
404  errstr << "number of shift actions for symbol a of the form (x | a) -> (xy | lambda) was expected to be 2, but was " << i << "." << std::endl;
405  throw Exception(name, errstr.str(), 1003);
406  }
407 
408  //there must be 2 actions that reduce with terminal b
409  i = 0;
410  for(pait = actions.begin(); pait != actions.end(); pait++){
411  if(pait->Lhs().NextTerminal() == *tb){
412  i++;
413  }
414  }
415  if(i != 2){
416  std::stringstream errstr;
417  errstr << "number of shift actions for symbol b of the form (x | b) -> (xy | lambda) was expected to be 2, but was " << i << "." << std::endl;
418  throw Exception(name, errstr.str(), 1003);
419  }
420  }
421  catch (Exception e){
422  }
423  TestEnd(name);
424 }
425 
426 /* *****************
427  * TestLrpReduceRulesNumberAndTerminals
428  * *****************/
430  std::string name = "LrpReduceRules Number And Terminals";
431  TestStart(name);
432 
433  Grammar gr = TestGrammar9();
434 
435  //create terminals
437  GrammarSymbolPtr ptrta(ta);
439  GrammarSymbolPtr ptrtb(tb);
440  Terminal* tdollar = new Terminal(PushdownGenerator::GlobalEventSymbolTablep()->Index("$"));
441  GrammarSymbolPtr ptrtdollar(tdollar);
443  GrammarSymbolPtr ptrtlambda(tlambda);
444 
445  //create nonterminals
446  std::vector<Idx> v;
447  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("dot"));
448  Nonterminal* nt1dot = new Nonterminal(1,v);
449  GrammarSymbolPtr ptrnt1dot(nt1dot);
450 
451  v.clear();
452  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("square"));
453  Nonterminal* nt1square = new Nonterminal(1,v);
454  GrammarSymbolPtr ptrnt1square(nt1square);
455 
456  Grammar augGr = Aug(gr, *nt1dot ,*tdollar);
457 
458  GotoGenerator gotoGen = Lrm(augGr, 1);
459  std::set<Lr1ParserAction> actions = LrpReduceRules(gr, augGr, gotoGen, 1);
460 
461  try{
462 
463  //number of found actions must be 4
464  if(actions.size() != 4){
465  std::stringstream errstr;
466  errstr << "number of shift actions was expected to be 4, but was " << actions.size() << "." << std::endl;
467  throw Exception(name, errstr.str(), 1003);
468  }
469  //there must be 4 actions that shift with terminal $
470  int i = 0;
471  std::set<Lr1ParserAction>::const_iterator pait;
472  for(pait = actions.begin(); pait != actions.end(); pait++){
473  if(pait->Lhs().NextTerminal() == *tdollar && pait->Rhs().NextTerminal() == *tdollar){
474  i++;
475  }
476  }
477  if(i != 4){
478  std::stringstream errstr;
479  errstr << "number of shift actions for symbol a of the form (x | $) -> (xy | $) was expected to be 4, but was " << i << "." << std::endl;
480  throw Exception(name, errstr.str(), 1003);
481  }
482  }
483  catch (Exception e){
484  }
485  TestEnd(name);
486 }
487 
488 /* *****************
489  * TestLrpActions
490  * *****************/
492  std::string name = "Lrp Actions";
493  TestStart(name);
494 
495  Grammar gr = TestGrammar9();
496 
497  //create terminals
499  GrammarSymbolPtr ptrta(ta);
501  GrammarSymbolPtr ptrtb(tb);
502  Terminal* tdollar = new Terminal(PushdownGenerator::GlobalEventSymbolTablep()->Index("$"));
503  GrammarSymbolPtr ptrtdollar(tdollar);
505  GrammarSymbolPtr ptrtlambda(tlambda);
506 
507  //create nonterminals
508  std::vector<Idx> v;
509  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("dot"));
510  Nonterminal* nt1dot = new Nonterminal(1,v);
511  GrammarSymbolPtr ptrnt1dot(nt1dot);
512 
513  v.clear();
514  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("square"));
515  Nonterminal* nt1square = new Nonterminal(1,v);
516  GrammarSymbolPtr ptrnt1square(nt1square);
517 
518  Grammar augGr = Aug(gr, *nt1dot ,*tdollar);
519 
520  GotoGenerator gotoGen = Lrm(augGr, 1);
521  Lr1Parser parser = Lrp(gr, augGr, gotoGen, 1, *tdollar);
522 
523  try{
524 
525  //number of found actions must be 8
526  std::set<Lr1ParserAction> actions = parser.Actions();
527  if(actions.size() != 8){
528  std::stringstream errstr;
529  errstr << "number of actions was expected to be 8, but was " << actions.size() << "." << std::endl;
530  throw Exception(name, errstr.str(), 1003);
531  }
532  //there must be 4 actions with terminal $ and $on the left-hand and right-hand side,
533  //2 with a and lambda, and 2 with b and lambda
534  int dollarCount = 0;
535  int aCount = 0;
536  int bCount = 0;
537  std::set<Lr1ParserAction>::const_iterator pait;
538  for(pait = actions.begin(); pait != actions.end(); pait++){
539  if(pait->Lhs().NextTerminal() == *tdollar && pait->Rhs().NextTerminal() == *tdollar){
540  dollarCount++;
541  }
542  if(pait->Lhs().NextTerminal() == *ta && pait->Rhs().NextTerminal() == *tlambda){
543  aCount++;
544  }
545  if(pait->Lhs().NextTerminal() == *tb && pait->Rhs().NextTerminal() == *tlambda){
546  bCount++;
547  }
548  }
549  if(dollarCount != 4){
550  std::stringstream errstr;
551  errstr << "number of actions for symbol $ of the form (x | $) -> (xy | $) was expected to be 4, but was " << dollarCount << "." << std::endl;
552  throw Exception(name, errstr.str(), 1003);
553  }
554  if(aCount != 2){
555  std::stringstream errstr;
556  errstr << "number of actions for symbol a of the form (x | a) -> (xy | lambda) was expected to be 2, but was " << aCount << "." << std::endl;
557  throw Exception(name, errstr.str(), 1003);
558  }
559  if(bCount != 2){
560  std::stringstream errstr;
561  errstr << "number of actions for symbol b of the form (x | b) -> (xy | $) was expected to be 2, but was " << bCount << "." << std::endl;
562  throw Exception(name, errstr.str(), 1003);
563  }
564  }
565  catch (Exception e){
566  }
567  TestEnd(name);
568 }
569 
570 /* *****************
571  * TestLrpNonterminalsTerminals
572  * *****************/
574  std::string name = "Lrp Nonterminals Terminals";
575  TestStart(name);
576 
577  Grammar gr = TestGrammar9();
578 
579  //create terminals
581  GrammarSymbolPtr ptrta(ta);
583  GrammarSymbolPtr ptrtb(tb);
584  Terminal* tdollar = new Terminal(PushdownGenerator::GlobalEventSymbolTablep()->Index("$"));
585  GrammarSymbolPtr ptrtdollar(tdollar);
587  GrammarSymbolPtr ptrtlambda(tlambda);
588 
589  //create nonterminals
590  std::vector<Idx> v;
591  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("dot"));
592  Nonterminal* nt1dot = new Nonterminal(1,v);
593  GrammarSymbolPtr ptrnt1dot(nt1dot);
594 
595  v.clear();
596  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("square"));
597  Nonterminal* nt1square = new Nonterminal(1,v);
598  GrammarSymbolPtr ptrnt1square(nt1square);
599 
600  Grammar augGr = Aug(gr, *nt1dot ,*tdollar);
601 
602  GotoGenerator gotoGen = Lrm(augGr, 1);
603  Lr1Parser parser = Lrp(gr, augGr, gotoGen, 1, *tdollar);
604 
605  try{
606 
607  //number of Nonterminals must be 5
608  std::set<Idx> nonterminals = parser.Nonterminals();
609  if(nonterminals.size() != 5){
610  std::stringstream errstr;
611  errstr << "number of nonterminals was expected to be 5, but was " << nonterminals.size() << "." << std::endl;
612  throw Exception(name, errstr.str(), 1003);
613  }
614 
615  //number of Terminals must be 4
616  std::set<Terminal> terminals = parser.Terminals();
617  if(terminals.size() != 4){
618  std::stringstream errstr;
619  errstr << "number of terminals was expected to be 4, but was " << terminals.size() << "." << std::endl;
620  throw Exception(name, errstr.str(), 1003);
621  }
622 
623  //the augment symbol must be $
624  if(parser.AugSymbol() != *tdollar){
625  std::stringstream errstr;
626  errstr << "the parser's augment symbol was expected to be " << tdollar->Str() << ", but was " << parser.AugSymbol().Str() << "." << std::endl;
627  throw Exception(name, errstr.str(), 1003);
628  }
629  }
630  catch (Exception e){
631  }
632  TestEnd(name);
633 }
634 
635 /* *****************
636  * TestGp2PpStates
637  * *****************/
639  std::string name = "Gp2Pp States";
640  TestStart(name);
641 
642  Grammar gr = TestGrammar9();
643 
644  //create terminals
645  Terminal* tdollar = new Terminal(PushdownGenerator::GlobalEventSymbolTablep()->Index("$"));
646  GrammarSymbolPtr ptrtdollar(tdollar);
647 
648  //get event indices
653 
654  //create state event pairs that are expected to be used in the generator
655  std::vector<MergeStateEvent> sePairs;
656  std::vector<MergeStateEvent>::iterator sePairsit;
657  sePairs.push_back(MergeStateEvent(6,lambdaIdx));
658  sePairs.push_back(MergeStateEvent(6,aIdx));
659  sePairs.push_back(MergeStateEvent(6,bIdx));
660  sePairs.push_back(MergeStateEvent(7,lambdaIdx));
661  sePairs.push_back(MergeStateEvent(7,aIdx));
662  sePairs.push_back(MergeStateEvent(7,bIdx));
663  sePairs.push_back(MergeStateEvent(4,lambdaIdx));
664  sePairs.push_back(MergeStateEvent(5,lambdaIdx));
665  sePairs.push_back(MergeStateEvent(2,dollarIdx));
666  sePairs.push_back(MergeStateEvent(4,dollarIdx));
667  sePairs.push_back(MergeStateEvent(5,dollarIdx));
668 
669  //create nonterminals
670  std::vector<Idx> v;
671  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("dot"));
672  Nonterminal* nt1dot = new Nonterminal(1,v);
673  GrammarSymbolPtr ptrnt1dot(nt1dot);
674 
675  //create pushdown generator
676  Grammar augGr = Aug(gr, *nt1dot ,*tdollar);
677 
678  GotoGenerator gotoGen = Lrm(augGr, 1);
679  Lr1Parser parser = Lrp(gr, augGr, gotoGen, 1, *tdollar);
680 
681  PushdownGenerator pd = Gp2Pp(gotoGen, parser);
682 
683  try{
684 
685  //number of states must be 20
686  if(pd.Size() != 20){
687  std::stringstream errstr;
688  errstr << "number of states was expected to be 20, but was " << pd.Size() << "." << std::endl;
689  throw Exception(name, errstr.str(), 1003);
690  }
691 
692  //get the states that are actually used
693  StateSet states;
694  TransSet::Iterator transit;
695  for(transit = pd.TransRelBegin(); transit != pd.TransRelEnd(); transit++){
696  states.Insert(transit->X1);
697  states.Insert(transit->X2);
698  }
699  //number of used states must be 11
700  if(states.Size() != 11){
701  std::stringstream errstr;
702  errstr << "number of used states was expected to be 11, but was " << states.Size() << "." << std::endl;
703  throw Exception(name, errstr.str(), 1003);
704  }
705  //test whether the used states are the expected ones
706  StateSet::Iterator stateit;
707  for(stateit = states.Begin(); stateit != states.End(); stateit++){
708 
709  //get MergeStateEvent
710  const MergeStateEvent* mse = dynamic_cast<const MergeStateEvent*>(pd.StateAttribute(*stateit).Merge());
711  if(mse == NULL){
712  throw Exception(name, "MergeStateEvent not set.", 1003);
713  }
714 
715  //test for existence in expected merge state events
716  bool found = false;
717  for(sePairsit = sePairs.begin(); sePairsit != sePairs.end(); sePairsit++){
718  if(sePairsit->State() == mse->State() && sePairsit->Event() == mse->Event()){
719  found = true;
720  break;
721  }
722  }
723 
724  if(!found){
725  std::stringstream errstr;
726  errstr << "state with MergeStateEvent (" << mse->State() << ", " << PushdownGenerator::GlobalEventSymbolTablep()->Symbol(mse->Event()) << ") was not expected to be in the set of used states." << std::endl;
727  throw Exception(name, errstr.str(), 1003);
728  }
729  }
730 
731  }
732  catch (Exception e){
733  }
734  TestEnd(name);
735 }
736 
737 /* *****************
738  * TestGp2PpTransitions
739  * *****************/
741  std::string name = "Gp2Pp Transitions";
742  TestStart(name);
743 
744  Grammar gr = TestGrammar9();
745 
746  //create terminals
747  Terminal* tdollar = new Terminal(PushdownGenerator::GlobalEventSymbolTablep()->Index("$"));
748  GrammarSymbolPtr ptrtdollar(tdollar);
749 
750  //get event indices
755 
756  //create nonterminals
757  std::vector<Idx> v;
758  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("dot"));
759  Nonterminal* nt1dot = new Nonterminal(1,v);
760  GrammarSymbolPtr ptrnt1dot(nt1dot);
761 
762  //create pushdown generator
763  Grammar augGr = Aug(gr, *nt1dot ,*tdollar);
764 
765  GotoGenerator gotoGen = Lrm(augGr, 1);
766  Lr1Parser parser = Lrp(gr, augGr, gotoGen, 1, *tdollar);
767 
768  PushdownGenerator pd = Gp2Pp(gotoGen, parser);
769 
770  try{
771 
772 
773 
774  int transCount = 0;
775  int aCount = 0;
776  int bCount = 0;
777  int dollarCount = 0;
778  int lambdaCount = 0;
779  int push6Count = 0;
780  int push7Count = 0;
781  int popLambdaCount = 0;
782  int popSize1 = 0;
783  int popSize2 = 0;
784  TransSet::Iterator transit;
785  for(transit = pd.TransRelBegin(); transit != pd.TransRelEnd(); transit++){
786 
787  //count events
788  if(transit->Ev == aIdx)
789  aCount++;
790  else if(transit->Ev == bIdx)
791  bCount++;
792  else if(transit->Ev == lambdaIdx)
793  lambdaCount++;
794  else if(transit->Ev == dollarIdx)
795  dollarCount++;
796 
797 
798  PopPushSet popPush = pd.PopPush(*transit);
799  PopPushSet::const_iterator ppit;
800  for(ppit = popPush.begin(); ppit != popPush.end(); ppit++){
801  //count transitions
802  transCount++;
803 
804  //count pops
805  if(ppit->first.size() == 2)
806  popSize2++;
807  else if(ppit->first.size() == 1){
808  popSize1++;
809  if(ppit->first.front() == pd.StackSymbolIndex(FAUDES_PD_LAMBDA))
810  popLambdaCount++;
811  }
812 
813  //count pushes
814  if(ppit->second.size() == 1){
815  if(ppit->second.front() == pd.StackSymbolIndex("6"))
816  push6Count++;
817  else if(ppit->second.front() == pd.StackSymbolIndex("7"))
818  push7Count++;
819  }
820 
821  }
822  }
823 
824  //number of transitions must be 16
825  if(transCount != 16){
826  std::stringstream errstr;
827  errstr << "number of transitions was expected to be 16, but was " << transCount << "." << std::endl;
828  throw Exception(name, errstr.str(), 1003);
829  }
830  //number of a events must be 2
831  if(aCount != 2){
832  std::stringstream errstr;
833  errstr << "number of transitions with the event a was expected to be 2, but was " << aCount << "." << std::endl;
834  throw Exception(name, errstr.str(), 1003);
835  }
836  //number of b events must be 2
837  if(bCount != 2){
838  std::stringstream errstr;
839  errstr << "number of transitions with the event b was expected to be 2, but was " << bCount << "." << std::endl;
840  throw Exception(name, errstr.str(), 1003);
841  }
842  //number of $ events must be 4
843  if(dollarCount != 4){
844  std::stringstream errstr;
845  errstr << "number of transitions with the event $ was expected to be 4, but was " << dollarCount << "." << std::endl;
846  throw Exception(name, errstr.str(), 1003);
847  }
848  //number of lambda events must be 8
849  if(lambdaCount != 8){
850  std::stringstream errstr;
851  errstr << "number of transitions with the event lambda was expected to be 8, but was " << lambdaCount << "." << std::endl;
852  throw Exception(name, errstr.str(), 1003);
853  }
854  //number of 6 pushes must be 8
855  if(push6Count != 8){
856  std::stringstream errstr;
857  errstr << "number of transitions that push 6 was expected to be 8, but was " << push6Count << "." << std::endl;
858  throw Exception(name, errstr.str(), 1003);
859  }
860  //number of 7 pushes must be 8
861  if(push7Count != 8){
862  std::stringstream errstr;
863  errstr << "number of transitions that push 7 was expected to be 8, but was " << push7Count << "." << std::endl;
864  throw Exception(name, errstr.str(), 1003);
865  }
866  //number of transitions that pop 2 stack symbols must be 4
867  if(popSize2 != 4){
868  std::stringstream errstr;
869  errstr << "number of transitions that pop 2 stack symbols was expected to be 4, but was " << popSize2 << "." << std::endl;
870  throw Exception(name, errstr.str(), 1003);
871  }
872  //number of transitions that pop 1 stack symbol must be 12
873  if(popSize1 != 12){
874  std::stringstream errstr;
875  errstr << "number of transitions that pop 1 stack symbol was expected to be 12, but was " << popSize1 << "." << std::endl;
876  throw Exception(name, errstr.str(), 1003);
877  }
878  //number of transitions that pop lambda must be 8
879  if(popLambdaCount != 8){
880  std::stringstream errstr;
881  errstr << "number of transitions that pop lambda was expected to be 8, but was " << popLambdaCount << "." << std::endl;
882  throw Exception(name, errstr.str(), 1003);
883  }
884  }
885  catch (Exception e){
886  }
887  TestEnd(name);
888 }
889 
890 /* *****************
891  * TestDimNoAugment
892  * *****************/
894  std::string name = "Dim No Augment";
895  TestStart(name);
896 
897  Grammar gr = TestGrammar9();
898 
899  //create terminals
900  Terminal* tdollar = new Terminal(PushdownGenerator::GlobalEventSymbolTablep()->Index("$"));
901  GrammarSymbolPtr ptrtdollar(tdollar);
902 
903  //get event indices
905 
906  //create nonterminals
907  std::vector<Idx> v;
908  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("dot"));
909  Nonterminal* nt1dot = new Nonterminal(1,v);
910  GrammarSymbolPtr ptrnt1dot(nt1dot);
911 
912  //create pushdown generator and diminish it
913  Grammar augGr = Aug(gr, *nt1dot ,*tdollar);
914 
915  GotoGenerator gotoGen = Lrm(augGr, 1);
916  Lr1Parser parser = Lrp(gr, augGr, gotoGen, 1, *tdollar);
917 
918  PushdownGenerator pdtemp = Gp2Pp(gotoGen, parser);
919  PushdownGenerator pd = Dim(pdtemp,*tdollar);
920 
921  try{
922 
923  int transCount = 0;
924  Transition trans;
925  bool dollarFound = false;
926  TransSet::Iterator transit;
927  for(transit = pd.TransRelBegin(); transit != pd.TransRelEnd(); transit++){
928  PopPushSet popPush = pd.PopPush(*transit);
929  PopPushSet::const_iterator ppit;
930 
931  //count transitions
932  for(ppit = popPush.begin(); ppit != popPush.end(); ppit++){
933  transCount++;
934  }
935 
936  //look for transitions with $
937  if(transit->Ev == dollarIdx){
938  dollarFound = true;
939  trans = *transit;
940  }
941  }
942 
943  //number of transitions must be 12
944  if(transCount != 12){
945  std::stringstream errstr;
946  errstr << "number of transitions was expected to be 12, but was " << transCount << "." << std::endl;
947  throw Exception(name, errstr.str(), 1003);
948  }
949 
950  //no $ event must be found
951  if(dollarFound){
952  std::stringstream errstr;
953  errstr << "transition "<< trans.Str() << " with event $ was found, but not expected." << std::endl;
954  throw Exception(name, errstr.str(), 1003);
955  }
956 
957  }
958  catch (Exception e){
959  }
960  TestEnd(name);
961 }
962 
963 /* *****************
964  * TestDimNewFinalStates
965  * *****************/
967  std::string name = "Dim Final States";
968  TestStart(name);
969 
970  Grammar gr = TestGrammar9();
971 
972  //create terminals
973  Terminal* tdollar = new Terminal(PushdownGenerator::GlobalEventSymbolTablep()->Index("$"));
974  GrammarSymbolPtr ptrtdollar(tdollar);
975 
976  //get event indices
978 
979  //create nonterminals
980  std::vector<Idx> v;
981  v.push_back(PushdownGenerator::GlobalStackSymbolTablep()->Index("dot"));
982  Nonterminal* nt1dot = new Nonterminal(1,v);
983  GrammarSymbolPtr ptrnt1dot(nt1dot);
984 
985  //create pushdown generator
986  Grammar augGr = Aug(gr, *nt1dot ,*tdollar);
987 
988  GotoGenerator gotoGen = Lrm(augGr, 1);
989  Lr1Parser parser = Lrp(gr, augGr, gotoGen, 1, *tdollar);
990 
991  PushdownGenerator pdtemp = Gp2Pp(gotoGen, parser);
992 
993  //get indices of states that must be made final after diminishing
994  TransSet::Iterator transit;
995  StateSet expectedFinalStates;
996  for(transit = pdtemp.TransRelBegin(); transit != pdtemp.TransRelEnd(); transit++){
997  if(transit->Ev == dollarIdx){
998  expectedFinalStates.Insert(transit->X1);
999  }
1000  }
1001 
1002  //diminish pushdown generator
1003  PushdownGenerator pd = Dim(pdtemp,*tdollar);
1004 
1005  try{
1006 
1007  StateSet::Iterator stateit;
1008  //test for final states
1009  for(stateit = expectedFinalStates.Begin(); stateit != expectedFinalStates.End(); stateit++){
1010  if(!pd.ExistsMarkedState(*stateit)){
1011  std::stringstream errstr;
1012  errstr << "state " << *stateit << " was expected to be a final state, but was not." << std::endl;
1013  throw Exception(name, errstr.str(), 1003);
1014  }
1015  }
1016  }
1017  catch (Exception e){
1018  }
1019  TestEnd(name);
1020 }
1021 
1022 /* *****************
1023  * TestGeneratorGoto
1024  * *****************/
1028 }
1029 
1030 /* *****************
1031  * TestGeneratorGotoSeq
1032  * *****************/
1036 }
1037 
1038 /* *****************
1039  * TestLrpShiftRules
1040  * *****************/
1043 }
1044 
1045 /* *****************
1046  * TestLrpReduceRules
1047  * *****************/
1050 }
1051 
1052 /* *****************
1053  * TestLrp
1054  * *****************/
1055 void TestLrp(){
1056  TestLrpActions();
1058 }
1059 
1060 /* *****************
1061  * TestGp2Pp
1062  * *****************/
1063 void TestGp2Pp(){
1064 
1066  TestGp2PpStates();
1067 }
1068 
1069 /* *****************
1070  * TestDim
1071  * *****************/
1072 void TestDim(){
1073  TestDimNoAugment();
1075 }
1076 
1077 } // namespace faudes
1078 

libFAUDES 2.24g --- 2014.09.15 --- c++ api documentaion by doxygen