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

CDExperiment 3-6

The program removes left recursion from a context-free grammar by: 1. Taking input from the user on the number of non-terminals and their productions. 2. Checking each production for left recursion. 3. For productions with left recursion of the form A->Aα, it replaces them with A->βiA', A'->αjA'|ε, where βi are the non-recursive productions for A and αj are the recursively referenced parts. 4. The modified set of non-terminals and productions without left recursion are then printed.

Uploaded by

savatid730
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

CDExperiment 3-6

The program removes left recursion from a context-free grammar by: 1. Taking input from the user on the number of non-terminals and their productions. 2. Checking each production for left recursion. 3. For productions with left recursion of the form A->Aα, it replaces them with A->βiA', A'->αjA'|ε, where βi are the non-recursive productions for A and αj are the recursively referenced parts. 4. The modified set of non-terminals and productions without left recursion are then printed.

Uploaded by

savatid730
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

Experiment - 3

Write a program to recognize white spaces, count the number of identifiers,


characters, tabs and the length of the input string.

C program that recognizes white spaces, counts the number of identifiers, characters, tabs, and the
length of the input string:

#include <stdio.h>
#include <ctype.h>
#include <string.h>

int main() {
char input[1000];
int identifiers = 0, characters = 0, tabs = 0, length = 0;
int inIdentifier = 0;

printf("Enter a string: ");


fgets(input, sizeof(input), stdin);

for (int i = 0; input[i] != '\0'; i++) {


length++;

if (isspace(input[i])) {
if (input[i] == '\t') {
tabs++;
}
inIdentifier = 0;
} else {
if (!inIdentifier && isalnum(input[i])) {
identifiers++;
inIdentifier = 1;
}
if (isalnum(input[i]) || input[i] == '_') {
characters++;
}
}
}

printf("Number of identifiers: %d\n", identifiers);


printf("Number of characters: %d\n", characters);
printf("Number of tabs: %d\n", tabs);
printf("Length of the input string: %d\n", length);

return 0;
}
Example String (Output):

Enter a string: Hello World !


Number of identifiers: 2
Number of characters: 10
Number of tabs: 1
Length of the input string: 14

Here's how the program works:


1. The program declares variables to store the count of identifiers, characters, tabs, and the length of
the input string.
2. It prompts the user to enter a string using `fgets`.
3. It iterates through each character in the input string using a `for` loop.
4. For each character:
- If the character is a white space, it checks if it's a tab and increments the `tabs` counter
accordingly. It also resets the `inIdentifier` flag to 0.
- If the character is not a white space and `inIdentifier` is 0 and the character is alphanumeric, it
increments the `identifiers` counter and sets `inIdentifier` to 1.
- If the character is alphanumeric or an underscore, it increments the `characters` counter.
- It increments the `length` counter for every character, including white spaces.
5. After iterating through the entire string, the program prints the count of identifiers, characters,
tabs, and the length of the input string.
Experiment - 4
Write a C program to identify whether a given line is a comment or not.

#include <stdio.h>
#include <string.h>

int isComment(char *line) {


// Check for single-line comments
if (strncmp(line, "//", 2) == 0) {
return 1;
}

// Check for multi-line comments


if (strncmp(line, "/*", 2) == 0) {
return 1;
}

// Check for end of multi-line comment


if (strncmp(line, "*/", 2) == 0) {
return 1;
}

return 0;
}

int main() {
char line[1000];

printf("Enter a line of code: ");


fgets(line, sizeof(line), stdin);

// Remove the newline character from the end of the line


line[strcspn(line, "\n")] = '\0';

if (isComment(line)) {
printf("The line is a comment.\n");
} else {
printf("The line is not a comment.\n");
}

return 0;
}
Example String (Output):

INPUT: int x = 10; // This is a comment at the end of a line

OUTPUT: The line is not a comment.

Here's how the program works:


1. The isComment function takes a line of code as input and checks if it is a comment or not.
● It first checks if the line starts with //, which indicates a single-line comment in C. If it
does, the function returns 1 (true).
● If the line starts with /*, it indicates the start of a multi-line comment. The function
returns 1 (true) in this case.
● If the line starts with */, it indicates the end of a multi-line comment. The function
returns 1 (true) in this case as well.
● If none of the above conditions are met, the function returns 0 (false), indicating that the
line is not a comment.
2. In the main function, the program prompts the user to enter a line of code.
3. The fgets function is used to read the input line from the user, including the newline character.
4. The strcspn function is used to remove the newline character from the end of the input line.
5. The isComment function is called with the input line, and its return value is checked.
● If isComment returns 1 (true), the program prints "The line is a comment."
● If isComment returns 0 (false), the program prints "The line is not a comment."
Experiment - 5
Write a program to remove left recursion.
ALGORITHM:
1. Start the program.
2. Initialize the arrays for taking input from the user.
3. Prompt the user to input the no. of non-terminals having left recursion and no. of
productions for these non-terminals.
4. Prompt the user to input the production for non-terminals.
5. Eliminate left recursion using the following rules:-
A->Aα1| Aα2 | . . . . . |Aαm
A->β1| β2| . . . . .| βn
Then replace it by
A-> βi A’ i=1,2,3,…..m
A’-> αj A’ j=1,2,3,…..n
A’-> Ɛ
6. After eliminating the left recursion by applying these rules, display the productions
without left recursion.
7. Stop.

PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
int n, i, j, k;
printf("\\nEnter number of non terminals: ");
scanf("%d", &n);
printf("\\nEnter non terminals one by one: ");

char **nonter = (char**)malloc(n * sizeof(char*));


int *leftrecr = (int*)calloc(n, sizeof(int));

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


printf("\\nNon terminal %d: ", i + 1);
nonter[i] = (char*)malloc(100 * sizeof(char));
scanf("%s", nonter[i]);
}

char ***prod = (char***)malloc(n * sizeof(char**));

printf("\\nEnter '^' for null");


for (i = 0; i < n; ++i) {
printf("\\nNumber of %s productions: ", nonter[i]);
scanf("%d", &k);
prod[i] = (char**)malloc(k * sizeof(char*));
printf("\\nOne by one enter all %s productions", nonter[i]);
for (j = 0; j < k; ++j) {
printf("\\nRHS of production %d: ", j + 1);
prod[i][j] = (char*)malloc(100 * sizeof(char));
scanf("%s", prod[i][j]);
if (strlen(nonter[i]) <= strlen(prod[i][j]) && strncmp(nonter[i],
prod[i][j], strlen(nonter[i])) == 0) {
leftrecr[i] = 1;
}
}
}

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


printf("%d", leftrecr[i]);
}

int new_n = n;
for (i = 0; i < n; ++i) {
if (leftrecr[i] == 0) {
continue;
}
new_n++;
char *new_nonter = (char*)malloc(100 * sizeof(char));
sprintf(new_nonter, "%s'", nonter[i]);
nonter = (char**)realloc(nonter, new_n * sizeof(char*));
nonter[new_n - 1] = new_nonter;

int new_k = 0;
for (j = 0; j < k; ++j) {
if (strlen(nonter[i]) <= strlen(prod[i][j]) && strncmp(nonter[i],
prod[i][j], strlen(nonter[i])) == 0) {
new_k++;
}
}
char **new_prod = (char**)malloc((new_k + 1) * sizeof(char*));
int p = 0;
for (j = 0; j < k; ++j) {
if (strlen(nonter[i]) <= strlen(prod[i][j]) && strncmp(nonter[i],
prod[i][j], strlen(nonter[i])) == 0) {
new_prod[p] = (char*)malloc(100 * sizeof(char));
sprintf(new_prod[p], "%s%s'", prod[i][j] + strlen(nonter[i]),
nonter[i]);
p++;
} else {
prod[i][j] = (char*)realloc(prod[i][j], (strlen(prod[i][j]) +
strlen(new_nonter) + 1) * sizeof(char));
strcat(prod[i][j], new_nonter);
}
}
new_prod[p] = (char*)malloc(2 * sizeof(char));
strcpy(new_prod[p], "^");
prod = (char***)realloc(prod, new_n * sizeof(char**));
prod[new_n - 1] = new_prod;
}

printf("\\n\\n");
printf("\\nNew set of non-terminals: ");
for (i = 0; i < new_n; ++i) {
printf("%s ", nonter[i]);
}
printf("\\n\\nNew set of productions: ");
for (i = 0; i < new_n; ++i) {
for (j = 0; prod[i][j] != NULL; ++j) {
printf("\\n%s -> %s", nonter[i], prod[i][j]);
}
}

// Free dynamically allocated memory


for (i = 0; i < new_n; ++i) {
free(nonter[i]);
for (j = 0; prod[i][j] != NULL; ++j) {
free(prod[i][j]);
}
free(prod[i]);
}
free(nonter);
free(prod);
free(leftrecr);

return 0;
}

Example String (Output):


Experiment - 6

Write a program to remove Left Factoring.


ALGORITHM :
1. Start
2. Ask the user to enter the set of productions
3. Check for common symbols in the given set of productions by comparing with:
A->aB1|aB2
4. If found, replace the particular productions with:
A->aA’
A’->B1 | B2|ɛ
5. Display the output
6. Exit

PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LEN 100

int main() {
int p, i, j, k, l, e = 1;
char buffer[10];

printf("\\nEnter number of productions: ");


scanf("%d", &p);

char **prodleft = (char **)malloc(p * sizeof(char *));


char **prodright = (char **)malloc(p * sizeof(char *));

printf("\\nEnter productions one by one: ");


for (i = 0; i < p; ++i) {
printf("\\nLeft of production %d: ", i + 1);
prodleft[i] = (char *)malloc(MAX_LEN * sizeof(char));
scanf("%s", prodleft[i]);

printf("\\nRight of production %d: ", i + 1);


prodright[i] = (char *)malloc(MAX_LEN * sizeof(char));
scanf("%s", prodright[i]);
}

for (i = 0; i < p; ++i) {


for (j = i + 1; j < p; ++j) {
if (strcmp(prodleft[j], prodleft[i]) == 0) {
int k = 0;
char com[MAX_LEN] = "";
while (k < strlen(prodright[i]) && k < strlen(prodright[j]) &&
prodright[i][k] == prodright[j][k]) {
strncat(com, &prodright[i][k], 1);
++k;
}

if (k == 0)
continue;

char comleft[MAX_LEN];
strcpy(comleft, prodleft[i]);

if (k == strlen(prodright[i])) {
sprintf(buffer, "%d", e);
strcat(prodleft[i], buffer);
strcat(prodleft[j], buffer);
strcpy(prodright[i], "^");
strcpy(prodright[j], prodright[j] + k);
} else if (k == strlen(prodright[j])) {
sprintf(buffer, "%d", e);
strcat(prodleft[i], buffer);
strcat(prodleft[j], buffer);
strcpy(prodright[j], "^");
strcpy(prodright[i], prodright[i] + k);
} else {
sprintf(buffer, "%d", e);
strcat(prodleft[i], buffer);
strcat(prodleft[j], buffer);
strcpy(prodright[j], prodright[j] + k);
strcpy(prodright[i], prodright[i] + k);
}

for (l = j + 1; l < p; ++l) {


if (strcmp(comleft, prodleft[l]) == 0 &&
strncmp(com, prodright[l], fmin(k, strlen(prodright[l]))) == 0) {
sprintf(buffer, "%d", e);
strcat(prodleft[l], buffer);
strcpy(prodright[l], prodright[l] + k);
}
}

prodleft = (char **)realloc(prodleft, (p + 1) * sizeof(char *));


prodright = (char **)realloc(prodright, (p + 1) * sizeof(char *));

prodleft[p] = (char *)malloc(MAX_LEN * sizeof(char));


prodright[p] = (char *)malloc(MAX_LEN * sizeof(char));

strcpy(prodleft[p], comleft);
sprintf(prodright[p], "%s%s", com, prodleft[i]);

++p;
++e;
}
}
}

printf("\\n\\nNew productions");
for (i = 0; i < p; ++i) {
printf("\\n%s->%s", prodleft[i], prodright[i]);
}

// Free dynamically allocated memory


for (i = 0; i < p; ++i) {
free(prodleft[i]);
free(prodright[i]);
}
free(prodleft);
free(prodright);

return 0;
}

int fmin(int a, int b) {


return (a < b) ? a : b;
}

Example String (Output):

You might also like