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); } }
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 << " "; } } } }