Advertisement
Guest User

Untitled

a guest
Apr 26th, 2018
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.34 KB | None | 0 0
  1. #include "TableCreator.h"
  2. #include <algorithm>
  3.  
  4. std::string EPS = "~";
  5. std::string END = "$";
  6.  
  7. TableCreator::TableCreator() {}
  8. TableCreator::TableCreator(CFG &c) : cfg(c) {}
  9.  
  10. void merge(std::set<Symbol> &to, std::set<Symbol> &from, Symbol *exclude)
  11. {
  12.     for (auto &s : from)
  13.     {
  14.         if (s != exclude)
  15.         {
  16.             to.insert(s);
  17.         }
  18.     }
  19. }
  20.  
  21. std::set<Symbol> TableCreator::findFirstRec(Symbol &sym)
  22. {
  23.     std::set<Symbol> newSet;
  24.     if (sym.isTerminal())
  25.     {
  26.         newSet.insert(sym);
  27.         return newSet;
  28.     }
  29.     auto mapIt = firstMap.find(sym);
  30.     if (mapIt != firstMap.end)
  31.         return mapIt->second;
  32.     std::vector<Production> all = cfg.getProductions(sym);
  33.     std::vector<Production>::iterator proIt;
  34.     for (proIt = all.begin(); proIt != all.end; proIt++) // looping on all productions.
  35.     {
  36.         std::vector<Symbol>::iterator symIt;
  37.         std::set<Symbol> ans;
  38.         for (symIt = proIt->rhs().begin(); symIt != proIt->rhs().end(); symIt++) // looping on all symbols.
  39.         {
  40.             ans = findFirstRec(*symIt);
  41.             std::set<Symbol>::iterator ansIt = ans.find(EPS);
  42.             if (ansIt == ans.end()) //eps is not in Yi
  43.             {
  44.                 merge(newSet, ans, new Symbol());
  45.                 break; //a production has finished.
  46.             }
  47.             merge(newSet, ans, ansIt); //merge all except epsolin.
  48.         }
  49.         /*
  50.         *  Here i am adding epsolin if we reach the last symbol and its first set contain epsolin.
  51.         *  because it means that all previous symbols must derive epsolin.
  52.         */
  53.         if (symIt == proIt->rhs().end())
  54.         {
  55.             std::set<Symbol>::iterator ansIt = ans.find(EPS);
  56.             if (ansIt != ans.end())
  57.             {
  58.                 newSet.insert(*ansIt); //inserting epsolin.
  59.             }
  60.         }
  61.     }
  62.     return newSet;
  63. }
  64.  
  65. std::set<Symbol> TableCreator::findFellowRec(Symbol &sym)
  66. {
  67.     std::set<Symbol> newSet;
  68.     if (sym == cgf.getStartSymbol())
  69.     {
  70.         newSet.insert(END);
  71.         return newSet;
  72.     }
  73.     std::map<Symbol, std::set<Symbol>>::iterator fellowIt = fellowMap.find(sym);
  74.     if (fellowIt != fellowMap.end())
  75.         return fellowIt->second;
  76.     std::vector<Production> all = cfg.getAllProductions();
  77.     std::vector<Production>::iterator productionIt;
  78.     for (productionIt = all.begin(); productionIt != all.end(); productionIt++) // looping on all productions.
  79.     {
  80.         std::vector<Symbol> rhs = productionIt->rhs();
  81.         std::vector<Symbol>::iterator symbolIt = find(rhs.begin(), rhs.end(), sym);
  82.         if (symbolIt != rhs.end())
  83.         {
  84.             Symbol nonTerm = productionIt->lhs();
  85.             if ((symbolIt + 1) == rhs.end())
  86.             {
  87.                 std::set<Symbol> ans = findFellowRec(nonTerm);
  88.                 merge(newSet, ans, new Symbol()); //merging fellow of lhs.
  89.                 continue;
  90.             }
  91.             Symbol followingSymbol = *symbolIt++;
  92.             std::set<Symbol> firstOfFellow = firstMap[followingSymbol];
  93.             std::set<Symbol>::iterator it = firstOfFellow.find(EPS);
  94.             if (it != firstOfFellow.end())
  95.             {
  96.                 std::set<Symbol> ans = findFellowRec(nonTerm);
  97.                 merge(newSet, ans, new Symbol()); //merging fellow of lhs.
  98.             }
  99.             merge(newSet, firstOfFellow, new Symbol()); //merging first of the fellowing symbol.
  100.         }
  101.     }
  102.     return newSet;
  103. }
  104.  
  105. void TableCreator::findFirstSet()
  106. {
  107.     for (auto &s : cfg.getTerminals())
  108.     {
  109.         firstMap[s] = findFirstRec(s);
  110.     }
  111.     for (auto &s : cfg.getNonTerminals())
  112.     {
  113.         firstMap[s] = findFirstRec(s);
  114.     }
  115. }
  116.  
  117. void TableCreator::findFellowSet()
  118. {
  119.     for (auto &s : cfg.getNonTerminals())
  120.     {
  121.         fellowMap[s] = findFellowRec(s);
  122.     }
  123. }
  124.  
  125. LL1Table &TableCreator::createTable()
  126. {
  127.     findFirstSet();
  128.     findFellowSet();
  129.     LL1Table ll1Table;
  130.     for (auto &nonTerm : cfg.getNonTerminals())
  131.     {
  132.         std::set<Symbol> first = firstMap[nonTerm];
  133.         std::set<Symbol> fellow = fellowMap[nonTerm];
  134.         for (auto &term : cfg.getTerminals())
  135.         {
  136.             Production prod = findProduction(cfg.getProductions(nonTerm),term);
  137.            
  138.             ll1Table.addProduction(nonTerm, term, prod ,);
  139.         }
  140.     }
  141.     return LL1Table;
  142. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement