Advertisement
Guest User

Untitled

a guest
Apr 26th, 2018
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.79 KB | None | 0 0
  1. #include "TableCreator.h"
  2. #include <algorithm>
  3. #include <iostream>
  4.  
  5. std::string EPS = "\\\\L";
  6. Symbol epsilon(EPS);
  7. std::string END = "$";
  8.  
  9. /*debug.*/
  10. void printSet(std::set<Symbol> set)
  11. {
  12. std::cout << "{";
  13. for (auto &s : set)
  14. {
  15. std::cout << s.getValue() << ", ";
  16. }
  17. std::cout << "}" << std::endl;
  18. }
  19. void printVector(std::vector<Symbol> set)
  20. {
  21. std::cout << "{";
  22. for (auto &s : set)
  23. {
  24. std::cout << s.getValue() << ", ";
  25. }
  26. std::cout << "}" << std::endl;
  27. }
  28. void printSetMap(std::map<Symbol, std::set<Symbol>> setMap)
  29. {
  30. std::map<Symbol, std::set<Symbol>>::iterator it1;
  31. for (it1 = setMap.begin(); it1 != setMap.end(); it1++)
  32. {
  33. std::cout << it1->first.getValue() << ":";
  34. printSet(it1->second);
  35. }
  36. }
  37.  
  38. TableCreator::TableCreator(CFG c) : cfg(c) {}
  39.  
  40. void merge(std::set<Symbol> &to, std::set<Symbol> &from, const Symbol &exclude)
  41. {
  42. // std::cout << "merge and exc " << exclude.getValue() << std::endl;
  43. for (auto &s : from)
  44. {
  45. // std::cout << s.getValue() << " ";
  46. if (s != exclude)
  47. {
  48. to.insert(s);
  49. }
  50. }
  51. // std::cout << std::endl;
  52. }
  53.  
  54. std::set<Symbol> TableCreator::findFirstRec(Symbol sym)
  55. {
  56. std::map<Symbol, std::set<Symbol>>::iterator mapIt = firstMap.find(sym);
  57. if (mapIt != firstMap.end())
  58. {
  59. // std::cout << sym.getValue() << " is found " << mapIt->first.getValue() << std::endl;
  60. // printSet(mapIt->second);
  61. return mapIt->second;
  62. }
  63. std::set<Symbol> newSet;
  64. if (sym.isTerminal())
  65. {
  66. // std::cout << sym.getValue() << " is terminal" << std::endl;
  67. newSet.insert(sym);
  68. return newSet;
  69. }
  70. std::vector<Production> all = cfg.getProductions(sym);
  71. std::vector<Production>::iterator proIt;
  72. for (proIt = all.begin(); proIt != all.end(); proIt++) // looping on all productions.
  73. {
  74. std::vector<Symbol> nextPro = proIt->rhs();
  75. // std::cout << sym.getValue() << " prod ";
  76. // printVector(nextPro);
  77. std::set<Symbol> ans;
  78. int i;
  79. for (i = 0; i < nextPro.size(); i++)
  80. {
  81. // std::cout << sym.getValue() << " calling " << nextPro[i].getValue() << std::endl;
  82. ans = findFirstRec(nextPro[i]);
  83. // printSet(ans);
  84. std::set<Symbol>::iterator ansIt = ans.find(epsilon);
  85. if (ansIt == ans.end()) //eps is not in Yi
  86. {
  87. merge(newSet, ans, *(new Symbol()));
  88. // std::cout << "newSet of " << sym.getValue();
  89. // printSet(newSet);
  90. break; //a production has finished.
  91. }
  92. // std::cout << "EPS FOund" << std::endl;
  93. merge(newSet, ans, *ansIt); //merge all except epsolin.
  94. }
  95. /*
  96. * Here i am adding epsolin if we reach the last symbol and its first set contain epsolin.
  97. * because it means that all previous symbols must derive epsolin.
  98. */
  99. if (i == nextPro.size())
  100. {
  101. // std::cout << "adding eps to " << sym.getValue() << std::endl;
  102. std::set<Symbol>::iterator ansIt = ans.find(epsilon);
  103. if (ansIt != ans.end())
  104. {
  105. newSet.insert(*ansIt); //inserting epsolin.
  106. }
  107. }
  108. }
  109. return newSet;
  110. }
  111.  
  112. std::set<Symbol> TableCreator::findFellowRec(Symbol sym, std::map<Symbol, bool> visit)
  113. {
  114. std::map<Symbol, std::set<Symbol>>::iterator fellowIt = fellowMap.find(sym);
  115. if (fellowIt != fellowMap.end() && fellowIt->second.size() > 0)
  116. {
  117. // std::cout << sym.getValue() << " is found " << fellowIt->first.getValue() << std::endl;
  118. return fellowIt->second;
  119. }
  120. visit[sym] = true;
  121. std::set<Symbol> newSet;
  122. if (sym.isTerminal())
  123. {
  124. newSet.insert(sym);
  125. return newSet;
  126. }
  127. std::vector<Production> all = cfg.getAllProductions();
  128. std::vector<Production>::iterator productionIt;
  129. for (productionIt = all.begin(); productionIt != all.end(); productionIt++) // looping on all productions.
  130. {
  131. std::vector<Symbol> rhs = productionIt->rhs();
  132. std::vector<Symbol>::iterator symbolIt = find(rhs.begin(), rhs.end(), sym);
  133. if (symbolIt != rhs.end())
  134. {
  135. Symbol nonTerm = productionIt->lhs();
  136. if ((symbolIt + 1) == rhs.end())
  137. {
  138. if (!visit[nonTerm] && nonTerm != sym) //to avoid recursive calls incase of E >> aE .
  139. {
  140. std::set<Symbol> ans = findFellowRec(nonTerm, visit);
  141. merge(newSet, ans, *(new Symbol())); //merging fellow of lhs.
  142. }
  143. continue;
  144. }
  145. Symbol followingSymbol = *(++symbolIt);
  146. std::set<Symbol> firstOfFellow = firstMap[followingSymbol];
  147. // std::cout << sym.getValue() << " followed by " << followingSymbol.getValue() << " under "
  148. // << nonTerm.getValue() << " ";
  149. // printSet(firstOfFellow);
  150. std::set<Symbol>::iterator it = firstOfFellow.find(epsilon);
  151. if (it != firstOfFellow.end())
  152. {
  153. // std::cout << "EPS found " << std::endl;
  154. std::set<Symbol> ans = findFellowRec(nonTerm, visit);
  155. merge(newSet, ans, *(new Symbol())); //merging fellow of lhs.
  156. }
  157. // std::cout << "EPS not found " << std::endl;
  158. merge(newSet, firstOfFellow, epsilon); //merging first of the following symbol.
  159. }
  160. }
  161. if (sym == cfg.getStartSymbol())
  162. newSet.insert(END);
  163. return newSet;
  164. }
  165.  
  166. void TableCreator::findFirstSet()
  167. {
  168. for (auto &s : cfg.getTerminals())
  169. {
  170. firstMap[s] = findFirstRec(s);
  171. }
  172. for (auto &s : cfg.getNonTerminals())
  173. {
  174. firstMap[s] = findFirstRec(s);
  175. }
  176. }
  177.  
  178. void TableCreator::findFellowSet()
  179. {
  180. for (auto &s : cfg.getNonTerminals())
  181. {
  182. std::map<Symbol, bool> visit;
  183. fellowMap[s] = findFellowRec(s, visit);
  184. }
  185. }
  186. std::set<Symbol> TableCreator::findRhsFirst(std::vector<Symbol> rhs)
  187. {
  188. std::set<Symbol> ans;
  189.  
  190. for (auto &sym : rhs)
  191. {
  192. ans.insert(firstMap[sym].begin(), firstMap[sym].end());
  193. if (firstMap[sym].find(epsilon) == firstMap[sym].end()) //no epsilon in the firt of this symbol
  194. break; //stop adding.
  195. }
  196. return ans;
  197. }
  198. LL1Table TableCreator::createTable()
  199. {
  200. findFirstSet();
  201.  
  202. std::cout << "printing first set." << std::endl;
  203. printSetMap(firstMap);
  204.  
  205. findFellowSet();
  206.  
  207. std::cout << "printing fellow set." << std::endl;
  208. printSetMap(fellowMap);
  209.  
  210. LL1Table ll1Table;
  211. ll1Table.setStartSymbol(cfg.getStartSymbol());
  212.  
  213. for (auto &production : cfg.getAllProductions())
  214. {
  215. Symbol nonTerm = production.lhs();
  216. std::set<Symbol> first = firstMap[nonTerm];
  217. std::set<Symbol> fellow = fellowMap[nonTerm];
  218. std::set<Symbol> difference;
  219. std::set_difference(fellow.begin(), fellow.end(), first.begin(),
  220. first.end(), std::inserter(difference, difference.end()));
  221. bool hasEPS = (first.find(epsilon) != first.end());
  222. std::set<Symbol> rhsFirst = findRhsFirst(production.rhs());
  223. for (auto &term : rhsFirst)
  224. {
  225. if (term.getValue() == EPS)
  226. continue;
  227. ll1Table.addProduction(nonTerm, term, production, false);
  228. }
  229. if (hasEPS && production.rhs().size() != 1 && production.rhs()[0] != epsilon)
  230. continue;
  231. for (auto &term : difference)
  232. ll1Table.addProduction(nonTerm, term, production, !hasEPS);
  233. }
  234. return ll1Table;
  235. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement