Untitled
unknown
plain_text
9 months ago
4.4 kB
5
Indexable
#include <iostream> // Correct header for C++ standard input/output
#include <string>
#include <vector>
using namespace std;
struct Production {
char lhs; // Left-hand side (non-terminal)
string rhs; // Right-hand side (production rule)
bool flagged = false; // Flag to mark if the production is left factored
};
vector<Production> productions; // List of all productions
vector<Production> newProductions; // List of new productions after left factoring
vector<char> specialChars; // List of special characters
char epsilon = '^'; // Epsilon symbol
// Function to input special characters
void inputSpecialChars() {
int count;
cout << "Enter the number of special characters (except non-terminals): ";
cin >> count;
cout << "Enter the special characters for your productions: ";
for (int i = 0; i < count; ++i) {
char ch;
cin >> ch;
specialChars.push_back(ch);
}
}
// Function to input the productions
void inputProductions() {
int numProds;
cout << "Enter the number of productions: ";
cin >> numProds;
productions.resize(numProds);
for (int i = 0; i < numProds; ++i) {
cout << "Enter production " << (i + 1) << " (in the form A->alpha): ";
cin >> productions[i].lhs >> productions[i].rhs;
}
}
// Function to perform left factoring
void leftFactor() {
int specialCharIndex = 0; // Index for special characters
// Loop through each pair of productions
for (size_t i = 0; i < productions.size(); ++i) {
for (size_t j = i + 1; j < productions.size(); ++j) {
// Check if the left-hand sides are the same
if (productions[i].lhs == productions[j].lhs) {
string commonPrefix;
size_t k = 0;
// Find the common prefix in the right-hand sides
while (k < productions[i].rhs.length() &&
k < productions[j].rhs.length() &&
productions[i].rhs[k] == productions[j].rhs[k]) {
commonPrefix += productions[i].rhs[k];
++k;
}
// If a common prefix is found
if (!commonPrefix.empty()) {
// Mark the productions as factored
productions[i].flagged = productions[j].flagged = true;
// Create a new production for the common prefix
newProductions.push_back({productions[i].lhs, commonPrefix + specialChars[specialCharIndex]});
// Create a new production for the remaining part of production[i]
if (k < productions[i].rhs.length()) {
newProductions.push_back({specialChars[specialCharIndex], productions[i].rhs.substr(k)});
} else {
newProductions.push_back({specialChars[specialCharIndex], string(1, epsilon)});
}
// Create a new production for the remaining part of production[j]
if (k < productions[j].rhs.length()) {
newProductions.push_back({specialChars[specialCharIndex], productions[j].rhs.substr(k)});
} else {
newProductions.push_back({specialChars[specialCharIndex], string(1, epsilon)});
}
// Move to the next special character for the next factoring
++specialCharIndex;
}
}
}
}
// Add all unflagged productions to the new list
for (const auto& prod : productions) {
if (!prod.flagged) {
newProductions.push_back(prod);
}
}
}
// Function to display the updated productions
void displayProductions() {
cout << "\nUpdated Productions after Left Factoring:\n";
for (const auto& prod : newProductions) {
cout << prod.lhs << " -> " << prod.rhs << "\n";
}
}
int main() {
inputSpecialChars(); // Input special characters
inputProductions(); // Input the productions
leftFactor(); // Perform left factoring
displayProductions(); // Display the new productions
return 0;
}Editor is loading...
Leave a Comment