EXPERIMENT-1
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#define NULLPTR 0
int size = 0;
void insert();
void del();
int search(char lab[]);
void modify();
void display();
struct symbtab {
char label[10];
int addr;
struct symbtab *next;
};
struct symbtab *first = NULLPTR, *last = NULLPTR;
void main() {
int op, y;
char la[10];
clrscr();
do {
printf("\nSYMBOL TABLE IMPLEMENTATION\n");
printf("1. INSERT\n");
printf("2. DISPLAY\n");
printf("3. DELETE\n");
printf("4. SEARCH\n");
printf("5. MODIFY\n");
printf("6. END\n");
printf("Enter your option : ");
scanf("%d", &op);
switch (op) {
case 1:
insert();
display();
break;
case 2:
display();
break;
case 3:
del();
display();
break;
case 4:
printf("Enter the label to be searched : ");
scanf("%s", la);
y = search(la);
if (y == 1) {
printf("The label is already in the symbol Table\n");
} else {
printf("The label is not found in the symbol table\n");
}
break;
case 5:
modify();
display();
break;
case 6:
break;
}
} while (op < 6);
getch();
}
void insert() {
int n;
char l[10];
struct symbtab *p;
printf("Enter the label : ");
scanf("%s", l);
n = search(l);
if (n == 1) {
printf("The label already exists. Duplicate can't be inserted\n");
} else {
p = (struct symbtab *)malloc(sizeof(struct symbtab));
strcpy(p->label, l);
printf("Enter the address : ");
scanf("%d", &p->addr);
p->next = NULLPTR;
if (size == 0) {
first = p;
last = p;
} else {
last->next = p;
last = p;
}
size++;
}
}
void display() {
int i;
struct symbtab *p = first;
printf("\nLABEL\tADDRESS\n");
for (i = 0; i < size; i++) {
printf("%s\t%d\n", p->label, p->addr);
p = p->next;
}
}
int search(char lab[]) {
int i, flag = 0;
struct symbtab *p = first;
for (i = 0; i < size; i++) {
if (strcmp(p->label, lab) == 0) {
flag = 1;
break;
}
p = p->next;
}
return flag;
}
void modify() {
char l[10], nl[10];
int add, choice, i, s;
struct symbtab *p = first;
printf("What do you want to modify?\n");
printf("1. Only the label\n");
printf("2. Only the address of a particular label\n");
printf("3. Both the label and address\n");
printf("Enter your choice : ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter the old label: ");
scanf("%s", l);
printf("Enter the new label: ");
scanf("%s", nl);
s = search(l);
if (s == 0) {
printf("NO such label\n");
} else {
for (i = 0; i < size; i++) {
if (strcmp(p->label, l) == 0) {
strcpy(p->label, nl);
break;
}
p = p->next;
}
}
break;
case 2:
printf("Enter the label whose address is to be modified: ");
scanf("%s", l);
printf("Enter the new address: ");
scanf("%d", &add);
s = search(l);
if (s == 0) {
printf("NO such label\n");
} else {
for (i = 0; i < size; i++) {
if (strcmp(p->label, l) == 0) {
p->addr = add;
break;
}
p = p->next;
}
}
break;
case 3:
printf("Enter the old label: ");
scanf("%s", l);
printf("Enter the new label: ");
scanf("%s", nl);
printf("Enter the new address: ");
scanf("%d", &add);
s = search(l);
if (s == 0) {
printf("NO such label\n");
} else {
for (i = 0; i < size; i++) {
if (strcmp(p->label, l) == 0) {
strcpy(p->label, nl);
p->addr = add;
break;
}
p = p->next;
}
}
break;
}
}
void del() {
char l[10];
struct symbtab *p = first, *q;
printf("Enter the label to be deleted: ");
scanf("%s", l);
if (search(l) == 0) {
printf("Label not found\n");
return;
}
if (strcmp(first->label, l) == 0) {
first = first->next;
free(p);
} else {
q = p->next;
while (strcmp(q->label, l) != 0) {
p = p->next;
q = q->next;
}
p->next = q->next;
if (q == last) {
last = p;
}
free(q);
}
size--;
}
EXPERIMENT-7
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
#define MAX 20
#define MAX_SYMBOLS 10
int n;
char production[MAX][MAX];
char first[MAX][MAX];
char follow[MAX][MAX];
char terminals[MAX_SYMBOLS];
int parsingTable[MAX][MAX_SYMBOLS];
char firstComputed[MAX]; // changed from int to char
char followComputed[MAX]; // changed from int to char
char startSymbol;
void computeFirst(char symbol, int index);
void computeFollow(char symbol, int index);
void addToSet(char set[], char symbol);
int isTerminal(char symbol);
void displaySet(char set[][MAX], char computed[]);
void constructParsingTable();
void displayParsingTable();
int parseInput(char input[]);
void initializeArrays();
void main() {
int i;
char input[MAX];
clrscr();
initializeArrays();
printf("Enter the number of productions: ");
scanf("%d", &n);
fflush(stdin);
printf("Enter the productions (e.g., A=BC or A=a):\n");
for (i = 0; i < n; i++) {
scanf("%s", production[i]);
}
startSymbol = production[0][0];
for (i = 0; i < n; i++) {
char nonTerminal = production[i][0];
if (!firstComputed[nonTerminal - 'A']) {
computeFirst(nonTerminal, i);
}
}
for (i = 0; i < n; i++) {
char nonTerminal = production[i][0];
if (!followComputed[nonTerminal - 'A']) {
computeFollow(nonTerminal, i);
}
}
constructParsingTable();
printf("\nFirst Sets:\n");
displaySet(first, firstComputed);
printf("\nFollow Sets:\n");
displaySet(follow, followComputed);
printf("\nLL(1) Parsing Table:\n");
displayParsingTable();
printf("\nEnter an input string to parse (end with $): ");
scanf("%s", input);
if (parseInput(input)) {
printf("\nString is accepted by LL(1) parser.\n");
} else {
printf("\nString is rejected by LL(1) parser.\n");
}
getch();
}
void initializeArrays() {
int i, j;
for (i = 0; i < MAX; i++) {
firstComputed[i] = 0;
followComputed[i] = 0;
for (j = 0; j < MAX; j++) {
first[i][j] = '\0';
follow[i][j] = '\0';
production[i][j] = '\0';
}
for (j = 0; j < MAX_SYMBOLS; j++) {
parsingTable[i][j] = -1;
}
}
for (i = 0; i < MAX_SYMBOLS; i++) {
terminals[i] = '\0';
}
}
void computeFirst(char symbol, int index) {
int i, j;
for (i = 0; i < n; i++) {
if (production[i][0] == symbol) {
j = 2;
while (production[i][j] != '\0') {
if (isTerminal(production[i][j])) {
addToSet(first[symbol - 'A'], production[i][j]);
break;
} else {
if (!firstComputed[production[i][j] - 'A']) {
computeFirst(production[i][j], production[i][j] - 'A');
}
strcat(first[symbol - 'A'], first[production[i][j] - 'A']);
break;
}
j++;
}
}
}
firstComputed[symbol - 'A'] = 1;
}
void computeFollow(char symbol, int index) {
int i, j, k;
if (symbol == startSymbol) {
addToSet(follow[symbol - 'A'], '$');
}
for (i = 0; i < n; i++) {
for (j = 2; production[i][j] != '\0'; j++) {
if (production[i][j] == symbol) {
if (production[i][j+1] != '\0') {
if (isTerminal(production[i][j+1])) {
addToSet(follow[symbol - 'A'], production[i][j+1]);
} else {
k = 0;
while (first[production[i][j+1] - 'A'][k] != '\0') {
if (first[production[i][j+1] - 'A'][k] != 'e')
addToSet(follow[symbol - 'A'], first[production[i][j+1] - 'A'][k]);
k++;
}
}
} else if (production[i][0] != symbol) {
if (!followComputed[production[i][0] - 'A']) {
computeFollow(production[i][0], production[i][0] - 'A');
}
k = 0;
while (follow[production[i][0] - 'A'][k] != '\0') {
addToSet(follow[symbol - 'A'], follow[production[i][0] - 'A'][k]);
k++;
}
}
}
}
}
followComputed[symbol - 'A'] = 1;
}
void constructParsingTable() {
int i, j, k;
for (i = 0; i < n; i++) {
char nonTerminal = production[i][0];
for (j = 0; first[nonTerminal - 'A'][j] != '\0'; j++) {
if (first[nonTerminal - 'A'][j] != 'e') {
k = first[nonTerminal - 'A'][j] - 'a';
if (k >= 0 && k < MAX_SYMBOLS) {
parsingTable[nonTerminal - 'A'][k] = i;
}
} else {
for (k = 0; follow[nonTerminal - 'A'][k] != '\0'; k++) {
int index = follow[nonTerminal - 'A'][k] - 'a';
if (index >= 0 && index < MAX_SYMBOLS) {
parsingTable[nonTerminal - 'A'][index] = i;
}
}
}
}
}
}
void displayParsingTable() {
int i, j;
printf(" ");
for (i = 0; i < MAX_SYMBOLS; i++) {
printf(" %c ", 'a' + i);
}
printf("\n");
for (i = 0; i < n; i++) {
if (i < n && production[i][0] >= 'A' && production[i][0] <= 'Z') {
printf("%c |", production[i][0]);
for (j = 0; j < MAX_SYMBOLS; j++) {
if (parsingTable[production[i][0] - 'A'][j] != -1) {
printf(" %d ", parsingTable[production[i][0] - 'A'][j]);
} else {
printf(" - ");
}
}
printf("\n");
}
}
}
int parseInput(char input[]) {
char stack[MAX];
int top = 1, ip = 0, i, rule_index;
stack[0] = '$';
stack[1] = startSymbol;
printf("\nParsing Steps:\n");
printf("Stack\tInput\tAction\n");
while (stack[top] != '$') {
printf("%c$\t%s\t", stack[top], &input[ip]);
if (stack[top] == input[ip]) {
printf("Match %c\n", input[ip]);
top--;
ip++;
} else if (isTerminal(stack[top])) {
printf("Error: Terminal mismatch\n");
return 0;
} else {
rule_index = parsingTable[stack[top] - 'A'][input[ip] - 'a'];
if (rule_index == -1) {
printf("Error: No production rule\n");
return 0;
}
printf("Apply %s\n", production[rule_index]);
top--;
for (i = strlen(production[rule_index]) - 1; i >= 2; i--) {
if (production[rule_index][i] != 'e') {
top++;
stack[top] = production[rule_index][i];
}
}
}
}
return (input[ip] == '$');
}
void addToSet(char set[], char symbol) {
int i = 0;
while (set[i] != '\0') {
if (set[i] == symbol)
return;
i++;
}
set[i] = symbol;
set[i+1] = '\0';
}
int isTerminal(char symbol) {
return (symbol >= 'a' && symbol <= 'z') || symbol == '$' || symbol == 'e';
}
void displaySet(char set[][MAX], char computed[]) {
int i;
for (i = 0; i < n; i++) {
if (production[i][0] >= 'A' && production[i][0] <= 'Z') {
printf("%c = { ", production[i][0]);
if (set[production[i][0] - 'A'][0] == '\0')
printf("∅ }\n");
else
printf("%s }\n", set[production[i][0] - 'A']);
}
}
}
input: Enter the productions (e.g., A=BC or A=a):
S=AB
A=aA
A=b
B=c