pd_alg_lrp.cpp
Go to the documentation of this file.
1 /** @file pd_alg_lrp.cpp functions related to parsers*/
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_alg_lrp.h"
11 
12 namespace faudes {
13 
14 
15 /* *************************
16  * MachineGoto
17  * *************************/
18 std::set<Idx> GeneratorGoto(const GotoGenerator& gotoGen, Idx state, const GrammarSymbolPtr& symbol){
19 
20  //state set to return
21  std::set<Idx> successorStates;
22 
23  TransSet::Iterator transit;
24  //iterate over all states with state as a start state
25  for(transit = gotoGen.TransRelBegin(state); transit != gotoGen.TransRelEnd(state); transit++){
26 
27  //if the symbol is the same, insert end state of the transition as successor state
28  if(*gotoGen.Symbol(*transit) == *symbol){
29  successorStates.insert(transit->X2);
30  }
31  }
32  return successorStates;
33 }
34 
35 
36 /* *************************
37  * GeneratorGotoSeq
38  * *************************/
39 std::vector<Idx> GeneratorGotoSeq(const GotoGenerator& gotoGen, Idx startState, const GrammarSymbolVector& word){
40 
41  //state sequence to return
42  std::vector<Idx> rStateSequence;
43 
44  //for later use
46  GrammarSymbolPtr lambdaPtr(lambda);
47 
48 
49  //if the word is not empty (or does not contain lambda), it is of the form w = a.w'
50  if(!word.empty()){
51  if(*word.front() != *lambda){
52 
53  //get front symbol a and remaining word w'
54  GrammarSymbolPtr frontSymbol = word.front();
55  GrammarSymbolVector remainingWord(word.begin() + 1, word.end());
56 
57  //get next state in the sequence
58  std::set<Idx> nextStateSet = GeneratorGoto(gotoGen, startState, frontSymbol);
59  Idx nextState;
60  if(!nextStateSet.empty()){
61  nextState = *nextStateSet.begin();
62 
63  //append the next state in the sequence
64  rStateSequence.push_back(nextState);
65  }
66 
67  //get the rest of the sequence
68  std::vector<Idx> remainingSequence = GeneratorGotoSeq(gotoGen, nextState, remainingWord);
69 
70  //append the rest of the sequence
71  rStateSequence.insert(rStateSequence.end(), remainingSequence.begin(), remainingSequence.end());
72  }
73  }
74  return rStateSequence;
75 }
76 
77 /* *************************
78  * LrpShiftRules
79  * *************************/
80 std::set<Lr1ParserAction> LrpShiftRules(const Grammar& gr, const Grammar& augGr, const GotoGenerator& gotoGen, uint k){
81 
82  //parser actions to return
83  std::set<Lr1ParserAction> rActions;
84 
85  //lambda terminal for later use
87  GrammarSymbolPtr lambdaPtr(lambda);
88 
89  StateSet::Iterator stateit;
90  //iterate over all states q of the gotoGenerator
91  for(stateit = gotoGen.StatesBegin(); stateit != gotoGen.StatesEnd(); stateit++){
92 
93  std::set<Terminal>::const_iterator tit;
94  //iterate over all terminals a of the grammar
95  for(tit = gr.TerminalsBegin(); tit != gr.TerminalsEnd(); tit++){
96 
97  //do not care for lambda
98  if(tit->IsLambda()){
99  continue;
100  }
101 
102  //convert terminal into GrammarSymbolPtr
103  Terminal* a = new Terminal(*tit);
104  GrammarSymbolPtr aPtr(a);
105 
106  //get the successor state q' for this terminal
107  std::set<Idx> succStateSet = GeneratorGoto(gotoGen, *stateit, aPtr);
108 
109  //continue, if there is no successor state (there can't be too many since gotoGen
110  //is supposed to be deterministic)
111  if(succStateSet.size() != 1){
112  continue;
113  }
114 
115  //extract the successor state
116  Idx succState = *succStateSet.begin();
117 
118  std::set<Lr1Configuration>::const_iterator configit;
119  //iterate over all configurations contained in the successor state
120  for(configit = gotoGen.ConfigSet(*stateit).begin(); configit != gotoGen.ConfigSet(*stateit).end(); configit++){
121 
122  //only consider this configuration (A -> w1 . a w2, z) if the
123  //production (A -> w1 a w2) is in the grammar.
124 
125  GrammarSymbolVector beforeDot, afterDot;
126  //construct right-hand side of the production, but need to make sure to delete
127  //unnecessary lambdas
128  beforeDot = configit->BeforeDot();
129  if(**beforeDot.begin() == *lambda){
130  beforeDot.clear();
131  }
132  afterDot = configit->AfterDot();
133  if(**afterDot.begin() == *lambda){
134  afterDot.clear();
135  }
136 
137  //create w1 a w2 from afterDot and beforeDot
138  GrammarSymbolVector rhs(beforeDot);
139  rhs.insert(rhs.end(), afterDot.begin(), afterDot.end());
140  if(rhs.empty()){
141  rhs.push_back(lambdaPtr);
142  }
143 
144  //construct production
145  GrammarProduction gp(configit->Lhs(), rhs);
146 
147  //test if the configuration is not in the grammar and if so, continue
148  if(gr.GrammarProductions().find(gp) == gr.GrammarProductionsEnd()){
149  continue;
150  }
151 
152  //construct the word w2 z
153  //w2 can't be lambda
154  GrammarSymbolVector w2z(configit->AfterDot().begin() + 1, configit->AfterDot().end());
155 
156  //append z if it's not lambda
157  if(!configit->Lookahead().IsLambda()){
158  Terminal* lookahead = new Terminal(configit->Lookahead());
159  GrammarSymbolPtr lookaheadPtr(lookahead);
160  w2z.push_back(lookaheadPtr);
161  }
162 
163  //get first terminals after w2z (will be either nothing or lambda)
164  std::set<Terminal> firstTerminals = FirstLeq1(augGr, k - 1, w2z);
165 
166  std::set<Terminal>::const_iterator firsttit;
167  //iterate over first terminals and add a parser action for each terminal y
168  for(firsttit = firstTerminals.begin(); firsttit != firstTerminals.end(); firsttit++){
169 
170  //just to make sure that the terminal must be lambda
171  if(!firsttit->IsLambda()){
172  std::stringstream errstr;
173  errstr << "While executing LrpRules(): Constructing shift actions and the terminal " << firsttit->Str() << ", which was expected to be lambda" << std::endl;
174  throw Exception("LrpRules", errstr.str(), 1001);
175  }
176 
177  //construct left-hand side of the rule (q | a y) (which is (q | a),
178  //because y is lambda)
179  std::vector<Idx> stateStack;
180  stateStack.push_back(*stateit);
181  Lr1ParserActionElement actionLhs(stateStack, *a);
182 
183  //construct right-hand side of the rule (q q' | y)
184  stateStack.push_back(succState);
185  Lr1ParserActionElement actionRhs(stateStack, *lambda);
186 
187  //construct shift action (q | a) -> (q q' | lambda) and insert into
188  //set of actions
189  Lr1ParserAction action(actionLhs, actionRhs);
190  rActions.insert(action);
191  }
192  }
193  }
194  }
195  return rActions;
196 }
197 
198 /* *************************
199  * LrpReduceRules
200  * *************************/
201 std::set<Lr1ParserAction> LrpReduceRules(const Grammar& gr, const Grammar& augGr, const GotoGenerator& gotoGen, uint k){
202 
203  //parser actions to return
204  std::set<Lr1ParserAction> rActions;
205 
206  //lambda terminal for later use
208 
209  StateSet::Iterator stateit;
210  //iterate over all states q of the gotoGenerator
211  for(stateit = gotoGen.StatesBegin(); stateit != gotoGen.StatesEnd(); stateit++){
212 
213  std::set<Lr1Configuration>::const_iterator configit;
214  //iterate over all configurations contained in the state q
215  for(configit = gotoGen.ConfigSet(*stateit).begin(); configit != gotoGen.ConfigSet(*stateit).end(); configit++){
216 
217  //only consider this configuration if it is of the form (A -> lambda . w, z),
218  //i. e. if beforeDot is lambda
219  if(**configit->BeforeDot().begin() != *lambda){
220  continue;
221  }
222 
223  //only consider this configuration if the production (A -> w) is in the grammar
224  GrammarProduction gp(configit->Lhs(), configit->AfterDot());
225  if(gr.GrammarProductions().find(gp) == gr.GrammarProductionsEnd()){
226  continue;
227  }
228 
229  //convert A into GrammarSymbolPtr and get successor state qa of q with the symbol A
230  Nonterminal* a = new Nonterminal(configit->Lhs());
231  GrammarSymbolPtr aPtr(a);
232  std::set<Idx> succStateSet = GeneratorGoto(gotoGen, *stateit, aPtr);
233 
234  //if there is no successor state, continue
235  if(succStateSet.size() != 1){
236  continue;
237  }
238  Idx succState = *succStateSet.begin();
239 
240  //get successor state sequence qs of q with the word w
241  std::vector<Idx> succStateSequence = GeneratorGotoSeq(gotoGen, *stateit, configit->AfterDot());
242 
243  //join state q and state sequence qs
244  std::vector<Idx> qQs;
245  qQs.push_back(*stateit);
246  qQs.insert(qQs.end(), succStateSequence.begin(), succStateSequence.end());
247 
248  //get last state of qQs state sequence
249  Idx lastState = qQs.back();
250 
251  std::set<Lr1Configuration>::const_iterator lsconfigit;
252  //iterate over configurations in the last state
253  for(lsconfigit = gotoGen.ConfigSet(lastState).begin(); lsconfigit != gotoGen.ConfigSet(lastState).end(); lsconfigit++){
254 
255  //only consider this configuration if it is of the form (A -> w . lambda, y),
256  if(lsconfigit->Lhs() != configit->Lhs()){
257  continue;
258  }
259  if(!EqualsGsVector(lsconfigit->BeforeDot(), configit->AfterDot())){
260  continue;
261  }
262  if(**lsconfigit->AfterDot().begin() != *lambda){
263  continue;
264  }
265 
266  //get the lookahead terminal
267  Terminal lookahead(lsconfigit->Lookahead());
268 
269  //add parser action for each configuration
270  //construct left-hand side (q qs | y)
271  Lr1ParserActionElement lhs(qQs, lookahead);
272 
273  //construct right-hand side (q qa | y)
274  std::vector<Idx> stateStack;
275  stateStack.push_back(*stateit);
276  stateStack.push_back(succState);
277  Lr1ParserActionElement rhs(stateStack, lookahead);
278 
279  //construct reduce action (q qs | y) -> (q qa | y) and insert it into set
280  //of actions
281  Lr1ParserAction action(lhs, rhs, gp);
282  rActions.insert(action);
283  }
284  }
285  }
286  return rActions;
287 }
288 
289 /* *************************
290  * LrpRules
291  * *************************/
292 std::set<Lr1ParserAction> LrpRules(const Grammar& gr, const Grammar& augGr, const GotoGenerator& gotoGen, uint k){
293 
294  //parser actions to return
295  std::set<Lr1ParserAction> rActions;
296 
297  //get shift actions
298  rActions = LrpShiftRules(gr, augGr, gotoGen, k);
299 
300  //get reduce actions
301  std::set<Lr1ParserAction> reduceActions = LrpReduceRules(gr, augGr, gotoGen, k);
302  rActions.insert(reduceActions.begin(), reduceActions.end());
303 
304  return rActions;
305 }
306 
307 /* *************************
308  * Lrp
309  * *************************/
310 Lr1Parser Lrp(const Grammar& gr, const Grammar& augGr, const GotoGenerator& gotoGen, uint k, const Terminal& augSymbol){
311 
312  //parser to return
313  Lr1Parser rParser;
314 
315  //convert augSymbol $ into GrammarSymbolPtr
316  Terminal* augSymbolTemp = new Terminal(augSymbol);
317  GrammarSymbolPtr augSymbolPtr(augSymbolTemp);
318 
319  //convert the grammar's start symbol q0 into GrammarSymbolPtr
320  Nonterminal* q0 = new Nonterminal(gr.StartSymbol());
321  GrammarSymbolPtr q0Ptr(q0);
322 
323  //get successor state of the initial goto generator state and $
324  std::set<Idx> succStateSetAug = GeneratorGoto(gotoGen, gotoGen.InitState(), augSymbolPtr);
325 
326  //get successor state sequence of the initial goto generator state and $ q0
327  GrammarSymbolVector word;
328  word.push_back(augSymbolPtr);
329  word.push_back(q0Ptr);
330  std::vector<Idx> succStateSeqAugQ0 = GeneratorGotoSeq(gotoGen, gotoGen.InitState(), word);
331 
332  //get successor state sequence of the initial goto generator state and $ q0 $
333  word.push_back(augSymbolPtr);
334  std::vector<Idx> succStateSeqAugQ0Aug = GeneratorGotoSeq(gotoGen, gotoGen.InitState(), word);
335 
336  //if the successor states for $, $ q0 and $ q0 $ exist (i. e. they are not empty)
337  if(!succStateSetAug.empty() && !succStateSeqAugQ0.empty() && !succStateSeqAugQ0Aug.empty()){
338 
339  //get the successor state for $
340  Idx succStateAug = *succStateSetAug.begin();
341 
342  //get the last state of the $ q0 sequence
343  Idx lastStateAugQ0 = succStateSeqAugQ0.back();
344 
345  //get the last state of the $ q0 $ sequence
346  Idx lastStateAugQ0Aug = succStateSeqAugQ0Aug.back();
347 
348  StateSet::Iterator stateit;
349  //insert all states of the gotoGen as nonterminals of the parser, but exclude
350  //the start state and the end state
351  for(stateit = gotoGen.StatesBegin(); stateit != gotoGen.StatesEnd(); stateit++){
352  if(*stateit != gotoGen.InitState() && *stateit != lastStateAugQ0Aug){
353  rParser.InsNonterminal(*stateit);
354  }
355  }
356 
357  std::set<Terminal>::const_iterator tit;
358  //insert all the augmented grammar's terminals as the parser's terminals
359  for(tit = augGr.TerminalsBegin(); tit != augGr.TerminalsEnd(); tit++){
360  rParser.InsTerminal(*tit);
361  }
362 
363  //set the parser's start state
364  rParser.SetStartState(succStateAug);
365 
366  //set the parser's final state
367  rParser.SetFinalState(lastStateAugQ0);
368 
369  //get the parsing actions
370  std::set<Lr1ParserAction> actions = LrpRules(gr, augGr, gotoGen, k);
371 
372  std::set<Lr1ParserAction>::const_iterator actit;
373  //insert the parsing actions into the parser
374  for(actit = actions.begin(); actit != actions.end(); actit++){
375  rParser.InsAction(*actit);
376  }
377 
378  //save $ for later reference in the parser
379  rParser.SetAugSymbol(augSymbol);
380  }
381 
382  return rParser;
383 }
384 
385 /* *************************
386  * Gp2Pp
387  * *************************/
388 PushdownGenerator Gp2Pp(const GotoGenerator& gotoGen, const Lr1Parser& parser){
389 
390  //generator to return
391  PushdownGenerator rPd;
392 
393  std::set<Idx>::const_iterator ntit;
394  std::set<Terminal>::const_iterator tit;
395  std::map<std::pair<Idx,Idx>, Idx> stateMap;
396  std::map<std::pair<Idx,Idx>, Idx>::const_iterator statemapit;
397 
398  //iterate over the parser's nonterminals
399  for(ntit = parser.Nonterminals().begin(); ntit != parser.Nonterminals().end();ntit++){
400 
401  //insert states for each pair of nonterminal and terminal of the parser
402  for(tit = parser.Terminals().begin(); tit != parser.Terminals().end(); tit++){
403 
404  //insert new states. start/final states can be inserted if the current terminal
405  //is lambda
406  Idx newState;
407  //start state
408  if(parser.StartState() == *ntit && tit->IsLambda()){
409  newState = rPd.InsInitState();
410  }
411  //final state
412  else if(parser.FinalState() == *ntit && tit->IsLambda()){
413  newState = rPd.InsMarkedState();
414  }
415  //normal state
416  else{
417  newState = rPd.InsState();
418  }
419 
420  //set MergeStateEvent of that new state
421  MergeStateEvent mse(*ntit, tit->Event());
422  rPd.SetMerge(newState, mse);
423 
424  //save information on how the new states were created for later reference
425  std::pair<Idx,Idx> key = std::make_pair(*ntit, tit->Event());
426  stateMap.insert(std::make_pair(key, newState));
427  }
428 
429  //the parser's nonterminals are the generator's stack symbols (needs conversion to
430  //string)
431  std::stringstream s;
432  s << *ntit;
433  rPd.InsStackSymbol(s.str());
434  }
435 
436  //lambda is always a stack symbol
438 
439  //add "0" as stack bottom
440  rPd.SetStackBottom("0");
441 
442  //the parser's terminals are the generator's events
443  for(tit = parser.Terminals().begin(); tit != parser.Terminals().end(); tit++){
444 
445  //insert event
446  rPd.InsEvent(tit->Str());
447  }
448 
449  //insert final state of the pushdown generator. the final state is a tuple of
450  //the goto generator's final state and lambda. first check if that state already
451  //has been added
452  std::pair<Idx, Idx> finalState = std::make_pair(*gotoGen.MarkedStatesBegin(), rPd.EventIndex(FAUDES_PD_LAMBDA));
453  statemapit = stateMap.find(finalState);
454 
455  std::set<Lr1ParserAction>::const_iterator actit;
456  //iterate over parser actions to create transitions
457  for(actit = parser.Actions().begin(); actit != parser.Actions().end(); actit++){
458 
459  //get left-hand side and right-hand side of the action
460  Lr1ParserActionElement lhs = actit->Lhs();
461  Lr1ParserActionElement rhs = actit->Rhs();
462 
463  //if the actions left-hand side next terminal is lambda, it is an unexpected rule,
464  //so throw an error
465  if(lhs.NextTerminal().IsLambda()){
466  std::stringstream errstr;
467  errstr << "While executing Gp2Pp(): Tried to create transition from parser action " << actit->Str() << ", but no rule exists for converting transitions with lambda in the left-hand side's next terminal. " << std::endl;
468  throw Exception("Gp2Pp", errstr.str(), 1001);
469  }
470 
471  //for each shift action (A | a) -> (AB | lambda)
472  else if(lhs.StateStack().size() == 1 &&
473  rhs.StateStack().size() == 2 &&
474  rhs.NextTerminal().IsLambda() &&
475  lhs.StateStack().front() == rhs.StateStack().front())
476  {
477  //extract A, B, a and lambda
478  Idx stateA = rhs.StateStack().front();
479  Idx stateB = rhs.StateStack().back();
480  Idx eventA = lhs.NextTerminal().Event();
481  Idx eventLambda = rhs.NextTerminal().Event();
482 
483  //get state (A, lambda)
484  statemapit = stateMap.find(std::make_pair(stateA,eventLambda));
485  if(statemapit == stateMap.end()){
486  std::stringstream errstr;
487  errstr << "While executing Gp2Pp(): Tried to find a pushdown generator state for the pair of goto generator state " << stateA << " and parser terminal " << eventLambda << " (" << rhs.NextTerminal().Str() << "), but could not be found." << std::endl;
488  throw Exception("Gp2Pp", errstr.str(), 1001);
489  }
490  Idx aLambda = statemapit->second;
491 
492  //get state (B, lambda)
493  statemapit = stateMap.find(std::make_pair(stateB,eventLambda));
494  if(statemapit == stateMap.end()){
495  std::stringstream errstr;
496  errstr << "While executing Gp2Pp(): Tried to find a pushdown generator state for the pair of goto generator state " << stateB << " and parser terminal " << eventLambda << " (" << rhs.NextTerminal().Str() << "), but could not be found." << std::endl;
497  throw Exception("Gp2Pp", errstr.str(), 1001);
498  }
499  Idx bLambda = statemapit->second;
500 
501  //get state (A, a)
502  statemapit = stateMap.find(std::make_pair(stateA,eventA));
503  if(statemapit == stateMap.end()){
504  std::stringstream errstr;
505  errstr << "While executing Gp2Pp(): Tried to find a pushdown generator state for the pair of goto generator state " << stateA << " and parser terminal " << eventA << " (" << lhs.NextTerminal().Str() << "), but could not be found." << std::endl;
506  throw Exception("Gp2Pp", errstr.str(), 1001);
507  }
508  Idx aA = statemapit->second;
509 
510  //create stack symbol vectors lambda and A
511  std::vector<StackSymbol> popLambda, pushA;
512  popLambda.push_back(StackSymbol(FAUDES_PD_LAMBDA));
513  std::stringstream s;
514  s << stateA;
515  pushA.push_back(StackSymbol(s.str()));
516 
517  //insert transition ((A, lambda), a, lambda, A, (B, lambda))
518  rPd.SetTransition(aLambda, eventA, bLambda, popLambda, pushA);
519 
520  //insert transition ((A, a), lambda, lambda, A, (B, lambda))
521  rPd.SetTransition(aA, eventLambda, bLambda, popLambda, pushA);
522 
523 
524  }
525 
526  //for each reduce action (AwB | y) -> (AC | y)
527  else if(//lhs.StateStack().size() >= 2 &&
528  rhs.StateStack().size() == 2 &&
529  lhs.StateStack().front() == rhs.StateStack().front() &&
530  lhs.NextTerminal() == rhs.NextTerminal())
531  {
532 
533  //extract A, B, C, w and y
534  Idx stateA = rhs.StateStack().front();
535  Idx stateB = lhs.StateStack().back();
536  Idx stateC = rhs.StateStack().back();
537  Idx eventY = lhs.NextTerminal().Event();
538  std::vector<Idx> statesW;
539  if(lhs.StateStack().size() > 2){
540  statesW = std::vector<Idx>(lhs.StateStack().begin() + 1, lhs.StateStack().end() - 1);
541  }
542 
543  //get state (B, lambda)
544  Idx eventLambda = rPd.EventIndex(FAUDES_PD_LAMBDA);
545  statemapit = stateMap.find(std::make_pair(stateB,eventLambda));
546  if(statemapit == stateMap.end()){
547  std::stringstream errstr;
548  errstr << "While executing Gp2Pp(): Tried to find a pushdown generator state for the pair of goto generator state " << stateB << " and parser terminal " << eventLambda << " (" << FAUDES_PD_LAMBDA << "), but could not be found." << std::endl;
549  throw Exception("Gp2Pp", errstr.str(), 1001);
550  }
551  Idx bLambda = statemapit->second;
552 
553  //get state (C, y)
554  statemapit = stateMap.find(std::make_pair(stateC,eventY));
555  if(statemapit == stateMap.end()){
556  std::stringstream errstr;
557  errstr << "While executing Gp2Pp(): Tried to find a pushdown generator state for the pair of goto generator state " << stateC << " and parser terminal " << eventY << " (" << lhs.NextTerminal().Str() << "), but could not be found." << std::endl;
558  throw Exception("Gp2Pp", errstr.str(), 1001);
559  }
560  Idx cY = statemapit->second;
561 
562  //get state (B, y)
563  statemapit = stateMap.find(std::make_pair(stateB,eventY));
564  if(statemapit == stateMap.end()){
565  std::stringstream errstr;
566  errstr << "While executing Gp2Pp(): Tried to find a pushdown generator state for the pair of goto generator state " << stateB << " and parser terminal " << eventY << " (" << lhs.NextTerminal().Str() << "), but could not be found." << std::endl;
567  throw Exception("Gp2Pp", errstr.str(), 1001);
568  }
569  Idx bY = statemapit->second;
570 
571  //create stack symbol vectors w^-1 A and A
572  std::vector<StackSymbol> popWA, pushA;
573  std::vector<Idx>::const_reverse_iterator idxit;
574  for(idxit = statesW.rbegin(); idxit != statesW.rend(); idxit++){
575  std::stringstream s;
576  s << *idxit;
577  popWA.push_back(StackSymbol(s.str()));
578  }
579  std::stringstream s;
580  s << stateA;
581  //only pop A if AwB has a size greater than 1
582  if(lhs.StateStack().size() > 1){
583  popWA.push_back(StackSymbol(s.str()));
584  }
585  else{
586  popWA.push_back(StackSymbol(FAUDES_PD_LAMBDA));
587  }
588  pushA.push_back(StackSymbol(s.str()));
589 
590  //insert transition ((B, lambda), eventY, w^-1 A, A, (C, y))
591  rPd.SetTransition(bLambda, eventY, cY, popWA, pushA);
592 
593  //insert transition ((B, y), lambda, w^-1 A, A, (C, y))
594  rPd.SetTransition(bY, eventLambda, cY, popWA, pushA);
595 
596  }
597 
598  //every other action must be an error
599  else{
600  std::stringstream errstr;
601  errstr << "While executing Gp2Pp(): Tried to create transition from parser action " << actit->Str() << ", but no rule exists for converting it. It seems to be neither a shift nor a reduce action. " << std::endl;
602  throw Exception("Aug", errstr.str(), 1001);
603  }
604  }
605 
606 
607  return rPd;
608 }
609 
610 /* *************************
611  * Dim
612  * *************************/
613 PushdownGenerator Dim(const PushdownGenerator& pd, const Terminal& augSymbol){
614 
615  //generator to return
616  PushdownGenerator rPd = pd;
617 
618  TransSet::Iterator transit;
619  PopPushSet::const_iterator ppit;
620  //look at every transition
621  for(transit = pd.TransRelBegin(); transit != pd.TransRelEnd(); transit++){
622 
623  //if the event is the same as augSymbol
624  if(transit->Ev == augSymbol.Event()){
625 
626  //set that transition's start state as final
627  rPd.InsMarkedState(transit->X1);
628 
629  //delete that transition from the generator for every pop push set
630  for(ppit = pd.PopPushBegin(*transit); ppit != pd.PopPushEnd(*transit); ppit++){
631  rPd.ClrTransition(*transit, ppit->first, ppit->second);
632  }
633  }
634  }
635 
636  //remove the event
637  rPd.DelEvent(augSymbol.Event());
638 
639  return rPd;
640 }
641 
642 } // namespace faudes
643 

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