Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "TableCreator.h"
- #include <algorithm>
- std::string EPS = "~";
- std::string END = "$";
- TableCreator::TableCreator() {}
- TableCreator::TableCreator(CFG &c) : cfg(c) {}
- void merge(std::set<Symbol> &to, std::set<Symbol> &from, Symbol *exclude)
- {
- for (auto &s : from)
- {
- if (s != exclude)
- {
- to.insert(s);
- }
- }
- }
- std::set<Symbol> TableCreator::findFirstRec(Symbol &sym)
- {
- std::set<Symbol> newSet;
- if (sym.isTerminal())
- {
- newSet.insert(sym);
- return newSet;
- }
- auto mapIt = firstMap.find(sym);
- if (mapIt != firstMap.end)
- return mapIt->second;
- std::vector<Production> all = cfg.getProductions(sym);
- std::vector<Production>::iterator proIt;
- for (proIt = all.begin(); proIt != all.end; proIt++) // looping on all productions.
- {
- std::vector<Symbol>::iterator symIt;
- std::set<Symbol> ans;
- for (symIt = proIt->rhs().begin(); symIt != proIt->rhs().end(); symIt++) // looping on all symbols.
- {
- ans = findFirstRec(*symIt);
- std::set<Symbol>::iterator ansIt = ans.find(EPS);
- if (ansIt == ans.end()) //eps is not in Yi
- {
- merge(newSet, ans, new Symbol());
- break; //a production has finished.
- }
- merge(newSet, ans, ansIt); //merge all except epsolin.
- }
- /*
- * Here i am adding epsolin if we reach the last symbol and its first set contain epsolin.
- * because it means that all previous symbols must derive epsolin.
- */
- if (symIt == proIt->rhs().end())
- {
- std::set<Symbol>::iterator ansIt = ans.find(EPS);
- if (ansIt != ans.end())
- {
- newSet.insert(*ansIt); //inserting epsolin.
- }
- }
- }
- return newSet;
- }
- std::set<Symbol> TableCreator::findFellowRec(Symbol &sym)
- {
- std::set<Symbol> newSet;
- if (sym == cgf.getStartSymbol())
- {
- newSet.insert(END);
- return newSet;
- }
- std::map<Symbol, std::set<Symbol>>::iterator fellowIt = fellowMap.find(sym);
- if (fellowIt != fellowMap.end())
- return fellowIt->second;
- std::vector<Production> all = cfg.getAllProductions();
- std::vector<Production>::iterator productionIt;
- for (productionIt = all.begin(); productionIt != all.end(); productionIt++) // looping on all productions.
- {
- std::vector<Symbol> rhs = productionIt->rhs();
- std::vector<Symbol>::iterator symbolIt = find(rhs.begin(), rhs.end(), sym);
- if (symbolIt != rhs.end())
- {
- Symbol nonTerm = productionIt->lhs();
- if ((symbolIt + 1) == rhs.end())
- {
- std::set<Symbol> ans = findFellowRec(nonTerm);
- merge(newSet, ans, new Symbol()); //merging fellow of lhs.
- continue;
- }
- Symbol followingSymbol = *symbolIt++;
- std::set<Symbol> firstOfFellow = firstMap[followingSymbol];
- std::set<Symbol>::iterator it = firstOfFellow.find(EPS);
- if (it != firstOfFellow.end())
- {
- std::set<Symbol> ans = findFellowRec(nonTerm);
- merge(newSet, ans, new Symbol()); //merging fellow of lhs.
- }
- merge(newSet, firstOfFellow, new Symbol()); //merging first of the fellowing symbol.
- }
- }
- return newSet;
- }
- void TableCreator::findFirstSet()
- {
- for (auto &s : cfg.getTerminals())
- {
- firstMap[s] = findFirstRec(s);
- }
- for (auto &s : cfg.getNonTerminals())
- {
- firstMap[s] = findFirstRec(s);
- }
- }
- void TableCreator::findFellowSet()
- {
- for (auto &s : cfg.getNonTerminals())
- {
- fellowMap[s] = findFellowRec(s);
- }
- }
- LL1Table &TableCreator::createTable()
- {
- findFirstSet();
- findFellowSet();
- LL1Table ll1Table;
- for (auto &nonTerm : cfg.getNonTerminals())
- {
- std::set<Symbol> first = firstMap[nonTerm];
- std::set<Symbol> fellow = fellowMap[nonTerm];
- for (auto &term : cfg.getTerminals())
- {
- Production prod = findProduction(cfg.getProductions(nonTerm),term);
- ll1Table.addProduction(nonTerm, term, prod ,);
- }
- }
- return LL1Table;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement