0% found this document useful (0 votes)
0 views

cd_file

The document contains multiple C programs aimed at various tasks related to grammar and parsing, including generating verbs from words, finding leading and trailing terminals, computing FIRST and FOLLOW sets, building parse trees, validating strings against grammars, and removing left recursion. Each program is accompanied by source code and a brief description of its aim. The programs utilize standard libraries and data structures to achieve their respective functionalities.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
0 views

cd_file

The document contains multiple C programs aimed at various tasks related to grammar and parsing, including generating verbs from words, finding leading and trailing terminals, computing FIRST and FOLLOW sets, building parse trees, validating strings against grammars, and removing left recursion. Each program is accompanied by source code and a brief description of its aim. The programs utilize standard libraries and data structures to achieve their respective functionalities.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

Program – 9

Aim: Program to make verb of any word using lexer table.

Source Code:
%{
#include <stdio.h>
#include <string.h>

void suggestVerb(char *word) {


if (strstr(word, "ing") || strstr(word, "ed") || strstr(word, "ize")) {
printf("\"%s\" is already a verb\n", word);
}
else if (strcmp(word, "beauty") == 0) {
printf("\"%s\" :- \"beautify\"\n", word);
}
else if (strcmp(word, "simple") == 0) {
printf("\"%s\" :- \"simplify\"\n", word);
}
else if (strcmp(word, "active") == 0) {
printf("\"%s\" :- \"activate\"\n", word);
}
else {
printf("\"%s\" :- \"%sing\"\n", word, word); // Default verb suggestion
}
}
%}

%%
[a-zA-Z]+ { suggestVerb(yytext); }
[ \t\n]+ ; // Ignore whitespace
. { printf("Unknown character: %s\n", yytext); }
%%

int main() {
printf("Enter words:\n");
yylex();
return 0;
}

int yywrap() {
return 1;
}

Output:
Program – 10

Aim: C Program to find the “leading terminals” of a grammar.

Source Code:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX_RULES 10
#define MAX_SYMBOLS 10

typedef struct {
char nonTerminal;
char productions[MAX_RULES][MAX_SYMBOLS];
int count;
} Rule;
Rule grammar[MAX_RULES];
int ruleCount = 0;

void findLeadingTerminals(char nonTerminal, int visited[]) {


for (int i = 0; i < ruleCount; i++) {
if (grammar[i].nonTerminal == nonTerminal) {
for (int j = 0; j < grammar[i].count; j++) {
char firstSymbol = grammar[i].productions[j][0];

if (islower(firstSymbol) || firstSymbol == '+' || firstSymbol == '-' || firstSymbol == '*' ||


firstSymbol == '/') {
printf("%c ", firstSymbol); }
else if (isupper(firstSymbol) && !visited[firstSymbol - 'A']) {
visited[firstSymbol - 'A'] = 1;
findLeadingTerminals(firstSymbol, visited); }
}
}
}
}
int main() {
int i, j, n;
printf("Enter number of grammar rules: ");
scanf("%d", &ruleCount);
for (i = 0; i < ruleCount; i++) {
printf("Enter non-terminal: ");
scanf(" %c", &grammar[i].nonTerminal);
printf("Enter number of productions for %c: ", grammar[i].nonTerminal);
scanf("%d", &grammar[i].count);
for (j = 0; j < grammar[i].count; j++) {
printf("Enter production %d for %c: ", j + 1, grammar[i].nonTerminal);
scanf("%s", grammar[i].productions[j]); }
}
printf("\nLeading Terminals:\n");
for (i = 0; i < ruleCount; i++) {
int visited[26] = {0};
printf("Leading(%c): ", grammar[i].nonTerminal);
findLeadingTerminals(grammar[i].nonTerminal, visited);
printf("\n"); }
return 0;
}

Output:
Program – 11

Aim: C Program to find the “trailing terminals” of a grammar.

Source Code:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX_RULES 10
#define MAX_SYMBOLS 10

typedef struct {
char nonTerminal;
char productions[MAX_RULES][MAX_SYMBOLS];
int count;
} Rule;
Rule grammar[MAX_RULES];
int ruleCount = 0;

void findTrailingTerminals(char nonTerminal, int visited[]) {


for (int i = 0; i < ruleCount; i++) {
if (grammar[i].nonTerminal == nonTerminal) {
for (int j = 0; j < grammar[i].count; j++) {
int len = strlen(grammar[i].productions[j]);
char lastSymbol = grammar[i].productions[j][len - 1];

if (islower(lastSymbol) || lastSymbol == '+' || lastSymbol == '-' || lastSymbol == '*' ||


lastSymbol == '/') {
printf("%c ", lastSymbol); }
else if (isupper(lastSymbol) && !visited[lastSymbol - 'A']) {
visited[lastSymbol - 'A'] = 1;
findTrailingTerminals(lastSymbol, visited); }
}
}
}
}
int main() {
int i, j;
printf("Enter number of grammar rules: ");
scanf("%d", &ruleCount);
for (i = 0; i < ruleCount; i++) {
printf("Enter non-terminal: ");
scanf(" %c", &grammar[i].nonTerminal);
printf("Enter number of productions for %c: ", grammar[i].nonTerminal);
scanf("%d", &grammar[i].count);
for (j = 0; j < grammar[i].count; j++) {
printf("Enter production %d for %c: ", j + 1, grammar[i].nonTerminal);
scanf("%s", grammar[i].productions[j]); }
}
printf("\nTrailing Terminals:\n");
for (i = 0; i < ruleCount; i++) {
int visited[26] = {0};
printf("Trailing(%c): ", grammar[i].nonTerminal);
findTrailingTerminals(grammar[i].nonTerminal, visited);
printf("\n"); }
return 0;
}

Output:
Program – 12

Aim: C program to find FIRST of non-terminals of a grammar.

Source Code:
#include <stdio.h>
#include <ctype.h>
void FIRST(char);
int count, n = 0;
char prodn[10][10], first[10];

int main() {
int i, choice;
char c, ch;
printf("How many productions? : ");
scanf("%d", &count);
printf("Enter %d productions (use '$' for epsilon):\n", count);
for (i = 0; i < count; i++) {
scanf("%s%c", prodn[i], &ch);
}
do{
n = 0;
printf("\nEnter element to find FIRST: ");
scanf("%c", &c);
FIRST(c);
printf("FIRST(%c) = { ", c);
for (i = 0; i < n; i++) {
printf("%c ", first[i]);
}
printf("}\n");
printf("Press 1 to continue: ");
scanf("%d%c", &choice, &ch);
} while (choice == 1);
return 0;
}
void FIRST(char c) {
int j;
if (!isupper(c)) {
first[n++] = c;
return;
}
for (j = 0; j < count; j++) {
if (prodn[j][0] == c) {
if (prodn[j][2] == '$'){
first[n++] = '$'; }
else if (islower(prodn[j][2])) {
first[n++] = prodn[j][2]; }
else {
FIRST(prodn[j][2]); }
}
}
}

Output:
Program – 13

Aim: C program to find FOLLOW of non-terminals of a grammar.

Source Code:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void follow(char c);
void first(char c);
int n, m = 0, i = 0, j = 0;
char a[10][10], f[10];

int main() {
int z;
char c, ch;
printf("Enter the no. of productions: ");
scanf("%d", &n);
printf("Enter the productions (use '$' for epsilon):\n");
for (i = 0; i < n; i++) {
scanf("%s%c", a[i], &ch);
}

do {
m = 0;
printf("\nEnter the element whose FOLLOW is to be found: ");
scanf("%c", &c);
follow(c);
printf("FOLLOW(%c) = { ", c);
for (i = 0; i < m; i++) {
printf("%c ", f[i]);
}
printf("}\n");
printf("Press 1 to continue: ");
scanf("%d%c", &z, &ch);
} while (z == 1);
return 0;
}

void follow(char c) {
if (a[0][0] == c) {
f[m++] = '$';
}
for (i = 0; i < n; i++) {
for (j = 2; j < strlen(a[i]); j++) {
if (a[i][j] == c) {
if (a[i][j + 1] != '\0') {
first(a[i][j + 1]);
}
if (a[i][j + 1] == '\0' && c != a[i][0]) {
follow(a[i][0]);
}
}
}
}
}

void first(char c) {
int k;
if (!isupper(c)) {
f[m++] = c;
return;
}
for (k = 0; k < n; k++) {
if (a[k][0] == c) {
if (a[k][2] == '$') {
follow(a[k][0]);
}
else if (islower(a[k][2])){
f[m++] = a[k][2];
}
else {
first(a[k][2]);
}
}
}
}

Output:
Program – 14

Aim: Program to generate a parse tree.

Source Code:
#include <iostream>
#include <string>
#include <stack>
using namespace std;

struct Node{
string value;
Node *left;
Node *right;
Node(string val) : value(val), left(nullptr), right(nullptr) {}
};

Node *buildParseTree(const string &postfix){


stack<Node *> stk;
for (char ch : postfix){
string val(1, ch);
if (isalnum(ch)){
stk.push(new Node(val));
} else {
Node *node = new Node(val);
node->right = stk.top();
stk.pop();
node->left = stk.top();
stk.pop();
stk.push(node);
}
}
return stk.top();
}
void printParseTree(Node *root, int level = 0){
if (root) {
printParseTree(root->right, level + 1);
cout << string(level * 4, ' ') << root->value << endl;
printParseTree(root->left, level + 1);
}
}

int main(){
string postfix;
cout << "Enter a postfix expression: ";
cin >> postfix;
Node *root = buildParseTree(postfix);
cout << "Parse Tree:\n";
printParseTree(root);
return 0;
}

Output:
Program – 15

Aim: Write a program to check whether a string belong to the grammar or not.

Source Code:
#include <iostream>
using namespace std;

string input;

bool isValid(int start, int end) {


if (start > end) return true;
if (input[start] == 'a' && input[end] == 'b') {
return isValid(start + 1, end - 1);
}
return false;
}

int main() {
cout << "Enter a string for grammar aSb|#: ";
cin >> input;
if (isValid(0, input.length() - 1)) {
cout << "The string belongs to the grammar.\n";
} else {
cout << "The string does NOT belong to the grammar.\n";
}
return 0;
}

Output:
Program – 16

Aim: Write a program to check whether a grammar is left recursion and remove left recursion.

Source Code:
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;

bool hasLeftRecursion(string nonTerminal, vector<string> productions) {


for (string prod: productions) {
if (prod[0] == nonTerminal[0]) {
return true;
}
}
return false;
}

void removeLeftRecursion(string nonTerminal, vector<string> productions) {


vector<string> alpha, beta;
for (string prod: productions) {
if (prod[0] == nonTerminal[0]) {
alpha.push_back(prod.substr(1));
} else {
beta.push_back(prod);
}
}

if (alpha.empty()) {
cout << nonTerminal << " - ";
for (size_t i = 0; i < productions.size(); i++) {
cout << productions[i] << (i == productions.size() - 1 ? "" : " | ");
}
cout << endl;
return;
}

string newNonTerminal = nonTerminal + "'";


cout << nonTerminal << " - ";
for (size_t i = 0; i < beta.size(); i++) {
cout << beta[i] << newNonTerminal << (i == beta.size() - 1 ? "" : " | ");
}
cout << endl;
cout << newNonTerminal << " - ";
for (size_t i = 0; i < alpha.size(); i++) {
cout << alpha[i] << newNonTerminal << " | ";
}
cout << "#" << endl;
}

int main() {
int n;
cout << "Enter the number of non-terminals: ";
cin >> n;
cin.ignore();

for (int i = 0; i < n; i++) {


string nonTerminal, productionLine;
cout << "Enter non-terminal: ";
cin >> nonTerminal;
cin.ignore();
cout << "Enter productions (separated by '|'): ";
getline(cin, productionLine);

vector<string> productions;
stringstream ss(productionLine);
string prod;
while (getline(ss, prod, '|')) {
productions.push_back(prod);
}
if (hasLeftRecursion(nonTerminal, productions)) {
cout << "Left recursion detected! Removing it...\n";
removeLeftRecursion(nonTerminal, productions);
} else {
cout << "No left recursion found.\n";
}
cout << endl;
}
return 0;
}

Output:

You might also like