static void expandOn(const map<string, Definition>& grammar, int aNonTerminalPos, vector<string>& aResult)
{
    if(aNonTerminalPos == -1)
    {
      // Base case //
      
      return;
    }
    else
    { 
      // Recursive case //

      auto iterator = grammar.find(aResult[aNonTerminalPos]);

      // If non-terminal is not defined then display error msg and exit.
      if(iterator == grammar.end()) {
        cout << "Could not find \"" << aResult[aNonTerminalPos] << "\" in the grammar file." << endl;
        exit (EXIT_FAILURE);  
      }

      Definition myDefinition = iterator->second;

      Production myRandProduction = myDefinition.getRandomProduction();
      
      // Get iterator 1 passed pos to insert.
      auto resultIterator = aResult.begin()+aNonTerminalPos+1;
      aResult.insert(resultIterator, myRandProduction.begin(), myRandProduction.end());
      
      // Get new valid iterator and delete expanded non-terminal.
      resultIterator = aResult.begin()+aNonTerminalPos;
      aResult.erase(resultIterator);

      // Iterate through result vector to expand on non-terminals.
      // Start from previously expanded position.
      int newNonTerminalPos = -1;
      int pos = aNonTerminalPos;
      for(auto start = aResult.begin()+aNonTerminalPos; start != aResult.end(); start++)
      {
        // Check if non-terminal.
        if( (*start)[0] == '<')
        {
          newNonTerminalPos = pos;
          break;
        }
        pos++;
      }
      
      // Recurse.      
      expandOn(grammar, newNonTerminalPos, aResult);
    }
}
Beispiel #2
0
static void expendProduction(Production& production, const map<string, Definition>& grammar) {

	for (auto iter = production.begin(); iter < production.end(); ++iter) {
		string str = *iter;

		if (str.find('<') == std::string::npos) {
			cout << str << " ";
		} else {
			Definition def = grammar.at(str);
			Production prod = def.getRandomProduction();
			expendProduction(prod, grammar);
		}
	}
}
static void generateRandomSentences(const map<string, Definition>& grammar, 
				    int numSentencesNeeded)
{
   
  for (int i = 0; i < numSentencesNeeded; i++) {
    map<string,Definition>::const_iterator it;
    it = grammar.find("<start>");
    
    const Production startProduction = it->second.getRandomProduction();

    vector<string> sentence;
    // Copy startProduction into a vector
    for (auto pi = startProduction.begin(); pi != startProduction.end(); ++pi) {
      string word = *pi;
      sentence.push_back(word);
    }
    
    printProduction (grammar, sentence);
  }
  cout << endl;

}
static void printProduction( const map<string, Definition>& grammar, vector<string> sentence)
{

  bool nonterminalExpanded = false;
  vector<string> nextSentence;

  // Generate next sentence, expanding at most 1 nonterminal
  for (auto vi = sentence.begin(); vi != sentence.end(); ++vi) {
    string word = *vi;
    
    if (word.front() == '<' && !nonterminalExpanded) { //if 1st nonterminal
      map<string,Definition>::const_iterator it;
      it = grammar.find(word);

      // if expansion is in grammar
      if (it != grammar.end()) {
        const Production nextProduction = it->second.getRandomProduction();
        for (auto pi = nextProduction.begin(); pi != nextProduction.end(); ++pi) {
          nextSentence.push_back(*pi);
        }
        nonterminalExpanded = true;
      }  
      // else expansion references an undefined non-terminal, exit program
      else {
        cerr << "Could not find \"" << word << "\" in the grammar file." << endl;
        exit(0);
      }
       
    }
    else if (nonterminalExpanded) {
      nextSentence.push_back(word);
    }
    else {
      nextSentence.push_back(word);
    }
  }

  // If nonterminals were expanded we print next Sentence
  if (nonterminalExpanded == true) {
    printProduction(grammar, nextSentence);
  }
  else {
    for (auto vi = nextSentence.begin(); vi != nextSentence.end(); ++vi) {
      vi++;
      if (vi != nextSentence.end()) {
        string nextWord = *vi;
        vi--;
        if (nextWord.compare(",") == 0 || nextWord.compare(".") == 0 ||
            nextWord.compare("?") == 0 || nextWord.compare("!") == 0 ||
            nextWord.compare(":") == 0) {
          cout << *vi;
        } 
        else {
          cout << *vi << " ";
        }
      }
      else {
        vi--;
        cout << *vi << " ";
      }
    }
  }
}