Advertisement
Guest User

Untitled

a guest
Feb 16th, 2019
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.34 KB | None | 0 0
  1. #include <iostream>
  2. #include <map>
  3. #include <set>
  4. #include <string>
  5. #include <vector>
  6.  
  7. using namespace std;
  8.  
  9. map<char, string> mapGrammar(vector <string> grammar)       // returns a map from input strings. Variables = keys, Productions = values
  10. {
  11.     map<char, string> tempMap;      // creates a temporary map to be returned
  12.     for (int i = 0; i < grammar.size(); i++)        // parse through the vector of strings
  13.     {
  14.         string tmp = "";        // creates an initial string for the production
  15.         for (int j = 3; j < (grammar.at(i).size()); j++)    // looks at everything after "->"
  16.         {
  17.             tmp += grammar[i][j];   // adds production to string, character by character
  18.         }
  19.         cout << "map @ " << i << ": " << grammar[i][0] << " -> " << tmp << endl;
  20.         tempMap.insert({ grammar[i][0], tmp });     // inserts the variable and production to the map
  21.     }
  22.     return tempMap;     // returns completed map
  23. }
  24.  
  25. map<char, set<char>> mapSet(vector <string> grammar)        // returs a map from input strings. Variables = keys. Sets = productions
  26. {
  27.     map<char, set<char>> tempMap;       // creates a temporary map to be returned
  28.     for (int i = 0; i < grammar.size(); i++)        // parse through the vector of strings
  29.     {
  30.         tempMap.insert({ grammar[i][0], {} });      // creates empty sets for each variable
  31.     }
  32.     return tempMap;     // returns completed map
  33. }
  34.  
  35. vector<string> getSubProd(string Prod)      // returns a vector of all the individual sub-productions of a variable. ( D->Aa|d|# returns 0:Aa, 1:d, 2:# )
  36. {
  37.     vector<string> temp;    // create a temp vector to be returned
  38.     string str;     // creates a tmp string that takes in each individual sub-production
  39.     for (int i = 0; i < Prod.size(); i++)   // parse through the entire production
  40.     {
  41.         if (Prod.at(i) == '|')      // if OR statement is reached
  42.         {
  43.             temp.push_back(str);    // add the string before the OR statement to the vector list.
  44.             str = "";       // resets the temp string
  45.         }
  46.         else
  47.         {
  48.             str += Prod.at(i);      // add the current character to the sub-Production string
  49.         }
  50.     }
  51.     if (str.size() > 0)     // no OR statement found
  52.     {
  53.         temp.push_back(str);    // add the string to the vector list
  54.     }
  55.     return temp;    // returns the vector list of strings.
  56. }
  57.  
  58. set<char> getUnion(const set<char>& a, const set<char>& b)      // union two sets
  59. {
  60.     set<char> result = a;
  61.     result.insert(b.begin(), b.end());
  62.     return result;
  63. }
  64.  
  65. void printSet(set<char> set)        // print the contents of a set
  66. {
  67.     cout << "{ ";
  68.     for (auto it = set.begin(); it != set.end(); it++)
  69.     {
  70.         cout << *it << ", ";
  71.     }
  72.     cout << "}";
  73. }
  74.  
  75. set<char> First(map<char, string> &map, char S)     // returns the First() set of a Variable. Takes in the map to be used as reference, and a character you want to return the First() set of.
  76. {
  77.     set<char> finalSet;     // set that will be returned to the function
  78.     string production;      // entire string value that is associated with each variable key. Will be broken down later by getSubProd()
  79.  
  80.     auto it = map.find(S);  // Look for the key associated with input character
  81.     if (it != map.end())    // if foudn
  82.     {
  83.         production = it->second;    // assign production to the string value mapped to Variable 'S'
  84.     }
  85.     else    // 'S' not found in map keys
  86.     {
  87.         finalSet.insert(S);     // insert unidentified Terminal into finalSet
  88.         return finalSet;
  89.     }
  90.  
  91.     vector<string> initSet;
  92.     initSet = getSubProd(production);       // a vector of the sub-Productions of char 'S'
  93.  
  94.     for (int i = 0; i < initSet.size(); i++)    // check each sub-Production. ( Aa | d | # )
  95.     {
  96.         int j = 0;
  97.         char firstChar = initSet[i][j];     // firstChar = first character of each sub-production ( A | d | # )
  98.         if (map.find(firstChar) == map.end())       // if first character is a Terminal
  99.         {
  100.             finalSet.insert(firstChar);     // add character to finalSet
  101.         }
  102.         else        // first character is a Non-Terminal
  103.         {
  104.             finalSet = getUnion(finalSet, First(map, firstChar));   // unions finalSet with finalSet of the Non-Terminal
  105.             while (finalSet.find('#') != finalSet.end() && (j + 1) < initSet.at(i).size())      // while epsilon is returned from First() and it's not the last Variable in the production
  106.             {
  107.                 finalSet.erase('#');        // erase epsilon
  108.                 char nextChar = initSet[i][++j];        // look at the next character in the production
  109.                 finalSet = getUnion(finalSet, First(map, nextChar));    // find First() of the next character
  110.             }
  111.         }
  112.     }
  113.     return finalSet;
  114. }
  115.  
  116. set<char> Follow(map<char, string> &Map, char S)
  117. {
  118.     set<char> finalSet;     // set that will be returned to the function
  119.     string production;
  120.  
  121.     if (S == 'S')       // S is the first Key in the map. AKA starting production
  122.     {
  123.         finalSet.insert('$');
  124.     }
  125.  
  126.     auto itr = Map.begin();
  127.  
  128.     for (itr = Map.begin(); itr != Map.end(); itr++)        // for each key in the map
  129.     {
  130.         production = itr->second;           // production = production string in map
  131.         vector<string> initSet;
  132.         initSet = getSubProd(production);       // create a vector of sub-Productions givin the production
  133.  
  134.         for (int j = 0; j < initSet.size(); j++)        // for each sub-Production in the vector
  135.         {
  136.             for (int k = 0; k < initSet.at(j).size(); k++)      // for each character in the sub-Production
  137.             {
  138.                 if (initSet[j][k] == S)     // found Variable in sub-Production
  139.                 {
  140.                     int l = k + 1;      // points to next character in the sub-Production
  141.                     if (l >= initSet.at(j).size())      // if Variable is last character of sub-Production
  142.                     {
  143.                         finalSet = getUnion(finalSet, Follow(Map, itr->first));     // Follow() of Variable = Follow() of Variable on left side of the production
  144.                     }
  145.                     else
  146.                     {
  147.                         char nextChar = initSet[j][l];  // next character in the sub-Production
  148.                         finalSet = getUnion(finalSet, First(Map, nextChar));  // Follow() = First(nextChar)
  149.                         while (finalSet.find('#') != finalSet.end() && (l+1) < initSet.at(j).size())        // next character is a Non-Terminal that contains '#' && Not at end of sub-Production
  150.                         {
  151.                             finalSet.erase('#');
  152.                             finalSet = getUnion(finalSet, First(Map, initSet[j][++l]));     // Moves onto the next character in the sub-Production
  153.                         }
  154.                         if (finalSet.find('#') != finalSet.end())       // if the last character returned an epsilon
  155.                         {
  156.                             finalSet.erase('#');
  157.                             finalSet = getUnion(finalSet, Follow(Map, itr->first)); // Follow() of Variable = Follow() of Variable on left side of the production
  158.                         }
  159.                     }
  160.                 }
  161.             }
  162.         }
  163.     }
  164.     return finalSet;
  165. }
  166.  
  167. int main()
  168. {
  169.     vector <string> grammar;
  170.  
  171.     grammar.push_back("S->ABCD");
  172.     grammar.push_back("A->a|#");
  173.     grammar.push_back("B->CD|b");
  174.     grammar.push_back("C->c|#");
  175.     grammar.push_back("D->Aa|d|#");
  176.  
  177.     cout << endl;
  178.  
  179.     map<char, string> gramMap;
  180.     gramMap = mapGrammar(grammar);      // creates a map of the grammar
  181.  
  182.     map<char, set<char>> firstMap, followMap;
  183.     firstMap = mapSet(grammar);     // creates a map for the first set
  184.     followMap = mapSet(grammar);    // creates a map for the follow set
  185.  
  186.     cout << endl;
  187.  
  188.     for (int i = 0; i < grammar.size(); i++)    // assigns First() to each Variable in the grammar
  189.     {
  190.         set<char> temp = First(gramMap, grammar[i][0]);
  191.         firstMap.find(grammar[i][0])->second = temp;
  192.         cout << "First(" << grammar[i][0] << ") = ";
  193.         printSet(temp);
  194.         cout << endl;
  195.     }
  196.  
  197.     cout << endl;
  198.  
  199.     for (int i = 0; i < grammar.size(); i++)    // assigns First() to each Variable in the grammar
  200.     {
  201.         set<char> temp = Follow(gramMap, grammar[i][0]);
  202.         followMap.find(grammar[i][0])->second = temp;
  203.         cout << "Follow(" << grammar[i][0] << ") = ";
  204.         printSet(temp);
  205.         cout << endl;
  206.     }
  207.  
  208.     cout << endl;
  209.  
  210.     system("pause");
  211.     return 0;
  212. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement