#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
#define NON_TERMINALS 26
#define TERMINALS 26
// Global arrays for the grammar
char nonTerminals[NON_TERMINALS];
char terminals[TERMINALS];
int numNonTerminals = 0;
int numTerminals = 0;
// Array of rules
char rules[NON_TERMINALS][MAX][MAX];
int ruleCount[NON_TERMINALS];
// Function to check if a character is a terminal symbol
int isTerminal(char c) {
return c >= 'a' && c <= 'z';
}
// Function to find the FIRST set of a non-terminal
void findFirst(char nonTerminal, char FIRST[NON_TERMINALS][TERMINALS], int* visited) {
int index = nonTerminal - 'A';
if (visited[index]) return; // Avoid cyclic calls
visited[index] = 1; // Mark the current non-terminal as visited
// Traverse all rules for this non-terminal
for (int i = 0; i < ruleCount[index]; i++) {
char *rule = rules[index][i];
// Rule could have the form A -> X1 X2 ... Xn
for (int j = 0; rule[j] != '\0'; j++) {
char symbol = rule[j];
// If symbol is a terminal, add to FIRST
if (isTerminal(symbol)) {
FIRST[index][symbol - 'a'] = 1;
break;
}
// If symbol is a non-terminal, recursively find its FIRST set
else if (symbol >= 'A' && symbol <= 'Z') {
findFirst(symbol, FIRST, visited);
// If the non-terminal can derive epsilon, continue to next symbols
if (FIRST[symbol - 'A'][0] == 1) {
continue;
}
else {
break;
}
}
}
}
}
// Function to print the FIRST sets
void printFirst(char FIRST[NON_TERMINALS][TERMINALS]) {
for (int i = 0; i < numNonTerminals; i++) {
printf("FIRST(%c) = {", nonTerminals
[i
]); int firstFound = 0;
for (int j = 0; j < TERMINALS; j++) {
if (FIRST[i][j]) {
if (firstFound) {
}
firstFound = 1;
}
}
if (firstFound == 0) {
// If no terminal found, it means FIRST set is empty
}
}
}
int main() {
// Input the number of non-terminals and terminals
printf("Enter the number of non-terminals: "); scanf("%d", &numNonTerminals
);
printf("Enter the non-terminals (e.g., S A B): "); for (int i = 0; i < numNonTerminals; i++) {
scanf(" %c", &nonTerminals
[i
]); }
printf("Enter the number of rules for each non-terminal:\n"); for (int i = 0; i < numNonTerminals; i++) {
printf("Number of rules for %c: ", nonTerminals
[i
]); scanf("%d", &ruleCount
[i
]); printf("Enter the rules for %c (e.g., A -> a, A -> AB):\n", nonTerminals
[i
]); for (int j = 0; j < ruleCount[i]; j++) {
scanf("%s", rules
[i
][j
]); }
}
// Initialize the FIRST table
char FIRST[NON_TERMINALS][TERMINALS] = {0};
// To avoid cyclic calls
int visited[NON_TERMINALS] = {0};
// Compute FIRST sets for each non-terminal
for (int i = 0; i < numNonTerminals; i++) {
findFirst(nonTerminals[i], FIRST, visited);
}
// Print the FIRST sets
printFirst(FIRST);
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2RlZmluZSBNQVggMTAwCiNkZWZpbmUgTk9OX1RFUk1JTkFMUyAyNgojZGVmaW5lIFRFUk1JTkFMUyAyNgoKLy8gR2xvYmFsIGFycmF5cyBmb3IgdGhlIGdyYW1tYXIKY2hhciBub25UZXJtaW5hbHNbTk9OX1RFUk1JTkFMU107CmNoYXIgdGVybWluYWxzW1RFUk1JTkFMU107CmludCBudW1Ob25UZXJtaW5hbHMgPSAwOwppbnQgbnVtVGVybWluYWxzID0gMDsKCi8vIEFycmF5IG9mIHJ1bGVzCmNoYXIgcnVsZXNbTk9OX1RFUk1JTkFMU11bTUFYXVtNQVhdOwppbnQgcnVsZUNvdW50W05PTl9URVJNSU5BTFNdOwoKLy8gRnVuY3Rpb24gdG8gY2hlY2sgaWYgYSBjaGFyYWN0ZXIgaXMgYSB0ZXJtaW5hbCBzeW1ib2wKaW50IGlzVGVybWluYWwoY2hhciBjKSB7CiAgICByZXR1cm4gYyA+PSAnYScgJiYgYyA8PSAneic7Cn0KCi8vIEZ1bmN0aW9uIHRvIGZpbmQgdGhlIEZJUlNUIHNldCBvZiBhIG5vbi10ZXJtaW5hbAp2b2lkIGZpbmRGaXJzdChjaGFyIG5vblRlcm1pbmFsLCBjaGFyIEZJUlNUW05PTl9URVJNSU5BTFNdW1RFUk1JTkFMU10sIGludCogdmlzaXRlZCkgewogICAgaW50IGluZGV4ID0gbm9uVGVybWluYWwgLSAnQSc7CiAgICAKICAgIGlmICh2aXNpdGVkW2luZGV4XSkgcmV0dXJuOyAgLy8gQXZvaWQgY3ljbGljIGNhbGxzCiAgICB2aXNpdGVkW2luZGV4XSA9IDE7ICAvLyBNYXJrIHRoZSBjdXJyZW50IG5vbi10ZXJtaW5hbCBhcyB2aXNpdGVkCiAgICAKICAgIC8vIFRyYXZlcnNlIGFsbCBydWxlcyBmb3IgdGhpcyBub24tdGVybWluYWwKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcnVsZUNvdW50W2luZGV4XTsgaSsrKSB7CiAgICAgICAgY2hhciAqcnVsZSA9IHJ1bGVzW2luZGV4XVtpXTsKICAgICAgICAKICAgICAgICAvLyBSdWxlIGNvdWxkIGhhdmUgdGhlIGZvcm0gQSAtPiBYMSBYMiAuLi4gWG4KICAgICAgICBmb3IgKGludCBqID0gMDsgcnVsZVtqXSAhPSAnXDAnOyBqKyspIHsKICAgICAgICAgICAgY2hhciBzeW1ib2wgPSBydWxlW2pdOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gSWYgc3ltYm9sIGlzIGEgdGVybWluYWwsIGFkZCB0byBGSVJTVAogICAgICAgICAgICBpZiAoaXNUZXJtaW5hbChzeW1ib2wpKSB7CiAgICAgICAgICAgICAgICBGSVJTVFtpbmRleF1bc3ltYm9sIC0gJ2EnXSA9IDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBJZiBzeW1ib2wgaXMgYSBub24tdGVybWluYWwsIHJlY3Vyc2l2ZWx5IGZpbmQgaXRzIEZJUlNUIHNldAogICAgICAgICAgICBlbHNlIGlmIChzeW1ib2wgPj0gJ0EnICYmIHN5bWJvbCA8PSAnWicpIHsKICAgICAgICAgICAgICAgIGZpbmRGaXJzdChzeW1ib2wsIEZJUlNULCB2aXNpdGVkKTsKICAgICAgICAgICAgICAgIC8vIElmIHRoZSBub24tdGVybWluYWwgY2FuIGRlcml2ZSBlcHNpbG9uLCBjb250aW51ZSB0byBuZXh0IHN5bWJvbHMKICAgICAgICAgICAgICAgIGlmIChGSVJTVFtzeW1ib2wgLSAnQSddWzBdID09IDEpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgovLyBGdW5jdGlvbiB0byBwcmludCB0aGUgRklSU1Qgc2V0cwp2b2lkIHByaW50Rmlyc3QoY2hhciBGSVJTVFtOT05fVEVSTUlOQUxTXVtURVJNSU5BTFNdKSB7CiAgICBwcmludGYoIkZJUlNUIHNldHM6XG4iKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtTm9uVGVybWluYWxzOyBpKyspIHsKICAgICAgICBwcmludGYoIkZJUlNUKCVjKSA9IHsiLCBub25UZXJtaW5hbHNbaV0pOwogICAgICAgIGludCBmaXJzdEZvdW5kID0gMDsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IFRFUk1JTkFMUzsgaisrKSB7CiAgICAgICAgICAgIGlmIChGSVJTVFtpXVtqXSkgewogICAgICAgICAgICAgICAgaWYgKGZpcnN0Rm91bmQpIHsKICAgICAgICAgICAgICAgICAgICBwcmludGYoIiwgIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwcmludGYoIiVjIiwgJ2EnICsgaik7CiAgICAgICAgICAgICAgICBmaXJzdEZvdW5kID0gMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoZmlyc3RGb3VuZCA9PSAwKSB7CiAgICAgICAgICAgIC8vIElmIG5vIHRlcm1pbmFsIGZvdW5kLCBpdCBtZWFucyBGSVJTVCBzZXQgaXMgZW1wdHkKICAgICAgICAgICAgcHJpbnRmKCLOtSIpOwogICAgICAgIH0KICAgICAgICBwcmludGYoIn1cbiIpOwogICAgfQp9CgppbnQgbWFpbigpIHsKICAgIC8vIElucHV0IHRoZSBudW1iZXIgb2Ygbm9uLXRlcm1pbmFscyBhbmQgdGVybWluYWxzCiAgICBwcmludGYoIkVudGVyIHRoZSBudW1iZXIgb2Ygbm9uLXRlcm1pbmFsczogIik7CiAgICBzY2FuZigiJWQiLCAmbnVtTm9uVGVybWluYWxzKTsKICAgIAogICAgcHJpbnRmKCJFbnRlciB0aGUgbm9uLXRlcm1pbmFscyAoZS5nLiwgUyBBIEIpOiAiKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtTm9uVGVybWluYWxzOyBpKyspIHsKICAgICAgICBzY2FuZigiICVjIiwgJm5vblRlcm1pbmFsc1tpXSk7CiAgICB9CgogICAgcHJpbnRmKCJFbnRlciB0aGUgbnVtYmVyIG9mIHJ1bGVzIGZvciBlYWNoIG5vbi10ZXJtaW5hbDpcbiIpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1Ob25UZXJtaW5hbHM7IGkrKykgewogICAgICAgIHByaW50ZigiTnVtYmVyIG9mIHJ1bGVzIGZvciAlYzogIiwgbm9uVGVybWluYWxzW2ldKTsKICAgICAgICBzY2FuZigiJWQiLCAmcnVsZUNvdW50W2ldKTsKICAgICAgICBwcmludGYoIkVudGVyIHRoZSBydWxlcyBmb3IgJWMgKGUuZy4sIEEgLT4gYSwgQSAtPiBBQik6XG4iLCBub25UZXJtaW5hbHNbaV0pOwogICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgcnVsZUNvdW50W2ldOyBqKyspIHsKICAgICAgICAgICAgc2NhbmYoIiVzIiwgcnVsZXNbaV1bal0pOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBJbml0aWFsaXplIHRoZSBGSVJTVCB0YWJsZQogICAgY2hhciBGSVJTVFtOT05fVEVSTUlOQUxTXVtURVJNSU5BTFNdID0gezB9OwogICAgCiAgICAvLyBUbyBhdm9pZCBjeWNsaWMgY2FsbHMKICAgIGludCB2aXNpdGVkW05PTl9URVJNSU5BTFNdID0gezB9OwoKICAgIC8vIENvbXB1dGUgRklSU1Qgc2V0cyBmb3IgZWFjaCBub24tdGVybWluYWwKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtTm9uVGVybWluYWxzOyBpKyspIHsKICAgICAgICBmaW5kRmlyc3Qobm9uVGVybWluYWxzW2ldLCBGSVJTVCwgdmlzaXRlZCk7CiAgICB9CiAgICAKICAgIC8vIFByaW50IHRoZSBGSVJTVCBzZXRzCiAgICBwcmludEZpcnN0KEZJUlNUKTsKCiAgICByZXR1cm4gMDsKfQo=