Advertisement
kartikkukreja

FIRST set of each variable in a CFG

Apr 24th, 2013
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.22 KB | None | 0 0
  1. /*
  2.  * Author : Kartik Kukreja
  3.  * Description :    Program to find the FIRST set for each grammar symbol for a CFG.
  4.  *                  It reads in the CFG from "CFG.txt" and writes out the FIRST set
  5.  *                  for each variable/non-terminal to the console.
  6.  *
  7.  *                  "CFG.txt" must have the following format :
  8.  *                      P
  9.  *                      Xi x1x2...xn
  10.  *                      :
  11.  *                      :
  12.  *                  Here,   P -> No. of productions. Each production has the form Xi x1x2...xn
  13.  *                                  which means Xi -> x1x2...xn where Xi is a variable and x1,x2,...,xn
  14.  *                                  are variables or terminals
  15.  *                          The variables are A, B, ..., Z and the terminals are a, b, ..., z.
  16.  *                          S is the starting variable and e is reserved for epsilon.
  17.  */
  18.  
  19.  #include <cstdio>
  20.  #include <iostream>
  21.  #include <fstream>
  22.  #include <cctype>
  23.  #include <vector>
  24.  #include <map>
  25.  #define SIZE 26
  26.  using namespace std;
  27.  
  28.  typedef map<char,vector<string> > table;
  29.  
  30.  table productions;
  31.  int FIRST[SIZE];
  32.  
  33.  int main() {
  34.     int P, i, j, prev, next;
  35.     char X;
  36.     string right;
  37.     bool complete = false;
  38.  
  39.     // read in the CFG
  40.     ifstream fin("CFG.txt");
  41.     fin >> P;
  42.     for(i=0; i<P; i++)  {
  43.         fin >> X >> right;
  44.     // if the first symbol on the right side of a production is a terminal,
  45.     // include it in the FIRST set of the variable on the left side of the production.
  46.         if(islower(right[0]))
  47.             FIRST[X - 'A'] |= 1 << (right[0] - 'a');
  48.         else if(productions.find(X) != productions.end())
  49.             productions[X].push_back(right);
  50.         else    {
  51.             vector <string> vec;
  52.             vec.push_back(right);
  53.             productions[X] = vec;
  54.         }
  55.     }
  56.     fin.close();
  57.  
  58.     // iterate until no more elements can be added to FIRST set of any variable
  59.     while(!complete)    {
  60.         complete = true;
  61.         for(table::iterator it=productions.begin(); it != productions.end(); it++)  {
  62.             prev = next = FIRST[it->first - 'A'];
  63.             for(vector<string>::iterator jt=(it->second).begin(); jt != (it->second).end(); jt++)   {
  64.                 for(i=0; i<jt->length(); i++)   {
  65.                     X = (*jt)[i];
  66.                     if(islower(X))  {
  67.                         next |= 1 << (X - 'a'); break;
  68.                     }
  69.                     if((FIRST[X - 'A'] & (1 << 'e' - 'a')) == 0)    {
  70.                         next |= FIRST[X - 'A']; break;
  71.                     } else
  72.                         next |= ~(~FIRST[X - 'A'] | (1 << 'e' - 'a'));
  73.                 }
  74.                 if(i == jt->length())
  75.                     next |= (1 << 'e' - 'a');
  76.             }
  77.             if(prev != next)    {
  78.                 FIRST[it->first - 'A'] = next; complete = false;
  79.             }
  80.         }
  81.     }
  82.  
  83.     // print out the FIRST set of each variable
  84.     for(i=0; i<26; i++)
  85.         if(FIRST[i])    {
  86.             printf("FIRST(%c) = { ", i + 'A');
  87.             for(j=0; j<26; j++)
  88.                 if(FIRST[i] & (1 << j))
  89.                     printf("%c ", j + 'a');
  90.             printf("}\n");
  91.         }
  92.  
  93.     return 0;
  94.  }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement