Lab 5
Lab 5
COMPILER DESIGN
LAB – 5
12-10-2021
DONE BY
SUDARSAN KUMAR N
2019503564
1. Write a C program and construct predictive parsing table for the
grammar and find moves made by predictive parser on input id + id *
id and find FIRST and FOLLOW.
E --> E + T
E --> T
T --> T * F
T --> F
F --> (E) | id
CODE
#include<stdio.h>
#include<ctype.h>
#include<string.h>
int count,n=0;
char calc_first[10][100];
char calc_follow[10][100];
int m=0;
char f[10];
int k;
char ck;
int e;
int jm=0;
int km=0;
int i,choice;
char c,ch;
scanf("%d",&count);
for(i=0;i<count;i++)
scanf("%s%c",production[i],&ch);
int kay;
char done[count];
for(k=0;k<count;k++){
for(kay=0;kay<100;kay++){
calc_first[k][kay] = '!';
for(k=0;k<count;k++)
c=production[k][0];
point2 = 0;
xxx = 0;
if(c == done[kay])
xxx = 1;
if (xxx == 1)
continue;
findfirst(c,0,0);
ptr+=1;
done[ptr] = c;
calc_first[point1][point2++] = c;
for(i=0+jm;i<n;i++){
for(lark=0;lark<point2;lark++){
if (first[i] == calc_first[point1][lark]){
chk = 1;
break;
if(chk == 0){
printf("%c, ",first[i]);
calc_first[point1][point2++] = first[i];
printf("}\n");
jm=n;
point1++;
printf("\n");
printf("-----------------------------------------------\n\n");
char donee[count];
ptr = -1;
for(k=0;k<count;k++){
for(kay=0;kay<100;kay++){
calc_follow[k][kay] = '!';
point1 = 0;
int land = 0;
for(e=0;e<count;e++)
ck=production[e][0];
point2 = 0;
xxx = 0;
if(ck == donee[kay])
xxx = 1;
if (xxx == 1)
continue;
land += 1;
follow(ck);
ptr+=1;
donee[ptr] = ck;
calc_follow[point1][point2++] = ck;
for(i=0+km;i<m;i++){
for(lark=0;lark<point2;lark++){
if (f[i] == calc_follow[point1][lark]){
chk = 1;
break;
if(chk == 0){
printf("%c, ",f[i]);
calc_follow[point1][point2++] = f[i];
printf(" }\n\n");
km=m;
point1++;
char ter[10];
for(k=0;k<10;k++){
ter[k] = '!';
int ap,vp,sid = 0;
for(k=0;k<count;k++){
for(kay=0;kay<count;kay++){
vp = 0;
if(production[k][kay] == ter[ap]){
vp = 1;
break;
if(vp == 0){
ter[sid] = production[k][kay];
sid ++;
ter[sid] = '$';
sid++;
printf("\n\t\t\t\t\t\t\t The LL(1) Parsing Table for the above grammer :-");
printf("\n\t\t\t\t\t\t\t^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\
n");
printf("\n\t\t\
t=============================================================
========================================================\n");
printf("\t\t\t\t|\t");
printf("\n\t\t\
t=============================================================
========================================================\n");
char first_prod[count][sid];
for(ap=0;ap<count;ap++){
int destiny = 0;
k = 2;
int ct = 0;
char tem[100];
while(production[ap][k] != '\0'){
if(!isupper(production[ap][k])){
tem[ct++] = production[ap][k];
tem[ct++] = '_';
tem[ct++] = '\0';
k++;
break;
else{
int zap=0;
int tuna = 0;
for(zap=0;zap<count;zap++){
if(calc_first[zap][0] == production[ap][k]){
for(tuna=1;tuna<100;tuna++){
if(calc_first[zap][tuna] != '!'){
tem[ct++] = calc_first[zap]
[tuna];
else
break;
break;
tem[ct++] = '_';
k++;
for(tuna = 0;tuna<ct;tuna++){
if(tem[tuna] == '#'){
zap = 1;
if(zap == 1){
zap = 0;
else
break;
else{
first_prod[ap][destiny++] = tem[tuna];
char table[land][sid+1];
ptr = -1;
table[ap][kay] = '!';
ck = production[ap][0];
xxx = 0;
if(ck == table[kay][0])
xxx = 1;
if (xxx == 1)
continue;
else{
ptr = ptr + 1;
table[ptr][0] = ck;
int tuna = 0;
while(first_prod[ap][tuna] != '\0'){
int to,ni=0;
for(to=0;to<sid;to++){
if(first_prod[ap][tuna] == ter[to]){
ni = 1;
if(ni == 1){
char xz = production[ap][0];
int cz=0;
while(table[cz][0] != xz){
cz = cz + 1;
int vz=0;
while(ter[vz] != first_prod[ap][tuna]){
vz = vz + 1;
tuna++;
for(k=0;k<sid;k++){
for(kay=0;kay<100;kay++){
if(calc_first[k][kay] == '!'){
break;
}
int fz = 1;
while(calc_follow[k][fz] != '!'){
char xz = production[k][0];
int cz=0;
while(table[cz][0] != xz){
cz = cz + 1;
int vz=0;
while(ter[vz] != calc_follow[k][fz]){
vz = vz + 1;
table[k][vz+1] = '#';
fz++;
break;
printf("\t\t\t %c\t|\t",table[ap][0]);
if(table[ap][kay] == '!')
printf("\t\t");
else{
mum -= 65;
printf("%s\t\t",production[mum]);
printf("\n");
printf("\t\t\
t-------------------------------------------------------------------------------------------------------
--------------");
printf("\n");
int j;
char input[100];
scanf("%s%c",input,&ch);
printf("\n\t\t\t\t\
t=============================================================
==============\n");
printf("\t\t\t\t\t\tStack\t\t\tInput\t\t\tAction");
printf("\n\t\t\t\t\
t=============================================================
==============\n");
char stack[100];
stack[0] = '$';
stack[1] = table[0][0];
while(s_ptr != -1){
printf("\t\t\t\t\t\t");
int vamp = 0;
for(vamp=0;vamp<=s_ptr;vamp++){
printf("%c",stack[vamp]);
printf("\t\t\t");
vamp = i_ptr;
while(input[vamp] != '\0'){
printf("%c",input[vamp]);
vamp++;
printf("\t\t\t");
s_ptr--;
if(!isupper(him)){
if(her == him){
i_ptr++;
printf("POP ACTION\n");
else{
exit(0);
}
else{
for(i=0;i<sid;i++){
if(ter[i] == her)
break;
char produ[100];
for(j=0;j<land;j++){
if(him == table[j][0]){
if (table[j][i+1] == '#'){
printf("%c=#\n",table[j][0]);
produ[0] = '#';
produ[1] = '\0';
mum -= 65;
strcpy(produ,production[mum]);
printf("%s\n",produ);
else{
exit(0);
}
int le = strlen(produ);
le = le - 1;
if(le == 0){
continue;
for(j=le;j>=2;j--){
s_ptr++;
stack[s_ptr] = produ[j];
printf("\n\t\t\
t=============================================================
==========================================================\n");
if (input[i_ptr] == '\0'){
else
printf("\t\t\
t=============================================================
==========================================================\n");
void follow(char c)
int i ,j;
if(production[0][0]==c){
f[m++]='$';
for(i=0;i<10;i++)
for(j=2;j<10;j++)
if(production[i][j]==c)
if(production[i][j+1]!='\0'){
followfirst(production[i][j+1],i,(j+2));
if(production[i][j+1]=='\0'&&c!=production[i][0]){
follow(production[i][0]);
int j;
if(!(isupper(c))){
first[n++]=c;
}
for(j=0;j<count;j++)
if(production[j][0]==c)
if(production[j][2]=='#'){
if(production[q1][q2] == '\0')
first[n++]='#';
else
first[n++]='#';
else if(!isupper(production[j][2])){
first[n++]=production[j][2];
else {
findfirst(production[j][2], j, 3);
{
int k;
if(!(isupper(c)))
f[m++]=c;
else{
int i=0,j=1;
for(i=0;i<count;i++)
if(calc_first[i][0] == c)
break;
while(calc_first[i][j] != '!')
if(calc_first[i][j] != '#'){
f[m++] = calc_first[i][j];
else{
if(production[c1][c2] == '\0'){
follow(production[c1][0]);
else{
followfirst(production[c1][c2],c1,c2+1);
j++;
}
}
OUTPUT
2. Write a C program and construct LR parsing table for the
grammar and find moves made by predictive parser on input id + id *
id and find FIRST and FOLLOW.
E --> E + T
E --> T
T --> T * F
T --> F
F --> (E) | id
CODE
CLOSURE_GOTO.h
char items[30][100][100];
char FIRST[2][10][10];
char FOLLOW[10][10];
int check(char c) {
int i;
if(terminals[i] == c)
return 1;
return 0;
void generate_terminals() {
int i, j;
int index = 0;
j++;
if(!check(augmented_grammar[i][j])) {
terminals[index] = augmented_grammar[i][j];
no_of_terminals++;
index++;
terminals[index] = '$';
no_of_terminals++;
index++;
terminals[index] = '\0';
int i;
if(nonterminals[i] == c)
return 1;
return 0;
void generate_nonterminals() {
int i, index = 0;
for(i = 0; i < no_of_productions; i++)
if(!check2(augmented_grammar[i][0], index)) {
nonterminals[index] = augmented_grammar[i][0];
index++;
no_of_nonterminals = index;
nonterminals[index] = '\0';
void initialize_items() {
generate_terminals();
generate_nonterminals();
int i;
no_of_items[i] = 0;
int i;
t[i] = s[i];
t[i] = '.';
if(s[i] != '@')
t[i+1] = s[i];
t[i+1] = '\0';
int i;
return 1;
return 0;
int isterminal(char s) {
int i;
if(s == terminals[i])
return 1;
return 0;
int i, j;
i++;
if(!item_found(s)) {
strcpy(items[state_index][closure_item_index], s);
closure_item_index++;
// printf("%s\n", items[state_index][closure_item_index-1]);
if(s[i] == s[0] && s[i-2] == '>') //To avoid infinite loop due to left recursion.
return;
if(isterminal(s[i]))
return;
if(augmented_grammar[j][0] == s[i]) {
generate_item(augmented_grammar[j], temp);
closure(temp);
int i, j;
int n = 0;
char t, temp2[100];
if(s == '\0') {
return n;
strcpy(temp2, items[goto_state_index][i]);
if(temp2[j+1] == '\0')
continue;
if(temp2[j+1] == s) {
t = temp2[j];
temp2[j] = temp2[j+1];
temp2[j+1] = t;
strcpy(temp[n], temp2);
n++;
return n;
int i;
return 1;
return 0;
}
int transition_item_found(char * t_items, char s, int t_index) {
int i;
if(s == t_items[i])
return 1;
return 0;
void compute_closure_goto() {
generate_item(augmented_grammar[0], temp[0]);
closure(temp[0]);
no_of_items[state_index] = closure_item_index;
closure_item_index = 0;
state_index++;
//state_index is 1 now.
transition_index = 0;
transition_items[transition_index] = '\0';
j++;
if(!transition_item_found(transition_items,
items[goto_state_index][i][j], transition_index)) {
transition_items[transition_index] =
items[goto_state_index][i][j];
transition_index++;
transition_items[transition_index] = '\0';
int add_flag = 0;
if(!state_found(temp[j])) {
add_flag = 1;
closure(temp[j]);
}
else
break;
if(add_flag) {
no_of_items[state_index] = closure_item_index;
closure_item_index = 0;
state_index++;
goto_state_index++;
no_of_states = state_index;
void print() {
int i, j;
printf("%s\n", items[i][j]);
}
void start() {
char str[100];
scanf("%d", &no_of_productions);
int i;
scanf("%s", augmented_grammar[i]);
strcpy(augmented_grammar[0], "Z->");
str[0] = augmented_grammar[1][0];
str[1] = '\0';
strcat(augmented_grammar[0], str);
no_of_productions++;
for(i = 0; i < no_of_productions; i++)
printf("%s\n", augmented_grammar[i]);
initialize_items();
compute_closure_goto();
print();
FISRT_FOLLOW.h
int epsilon_flag = 0;
int i;
FIRST[0][i][0] = '\0';
FIRST[1][i][0] = '\0';
FOLLOW[i][0] = '\0';
void add_symbol(int flag, char *f, char *s) { //Adds a symbol to FIRST or
FOLLOW if it doesn't already exist in it.
int i, j;
int found;
found = 0;
if(s[i] == f[j])
found = 1;
if(!found) {
char temp[2];
temp[0] = s[i];
temp[1] = '\0';
strcat(f, temp);
found = 0;
if(s[i] == '@') {
epsilon_flag = 1;
continue;
if(s[i] == f[j])
found = 1;
if(!found) {
char temp[2];
temp[0] = s[i];
temp[1] = '\0';
strcat(f, temp);
void first(char s) {
FIRST[0][get_pos(0, s)][0] = s;
if(augmented_grammar[i][0] == s) { //Productions
with head as s.
int j;
j++;
flag = 1;
else {
if(flag)
next_sym = augmented_grammar[i][+
+j];
else
continue;
else
void compute_first() {
int i;
first(terminals[i]);
first(nonterminals[i]);
}
//FOLLOW
void follow(char s) {
if(s == nonterminals[0])
int i, j;
epsilon_flag = 0;
if(augmented_grammar[i][j] == s) {
follow(next_sym);
add_symbol(1, FOLLOW[get_pos(1,
s)], FOLLOW[get_pos(1, next_sym)]);
follow(augmented_grammar[i][0]); //Follow
of production head.
compute_follow() {
int i;
PARSE.h
struct Stack { //Holds states.
int states[100];
int top;
} stack;
void push(int a) {
stack.top++;
stack.states[stack.top] = a;
void pop() {
int a = stack.states[stack.top];
stack.top--;
return stack.states[stack.top];
push(0);
int get_int(char *s) { //Get integer part of the strings found in table
entries.
int i, j;
char temp[10];
i++;
temp[i-j] = s[i];
temp[i-j] = '\0';
return atoi(temp);
int i, j;
i++;
for(j = 0; production[i] != '\0'; i++, j++);
return j;
//Start of functions meant only for displaying the result. (Doesn't affect the actual
string parsing)
int i;
char c[5];
strcpy(t, "$");
int n = stack.states[i];
strcat(t, c);
void get_remaining_input(char *string, int index, char *t) { //Stores remaining Input
string in t.
int i, j;
for(i = index, j = 0; string[i] != '\0'; i++, j++)
t[j] = string[i];
t[j] = '\0';
get_stack_contents(t1);
void parse() {
char string[100];
char matched_string[100];
initialize_stack();
printf("\nEnter a string: ");
scanf("%s", string);
matched_string[0] = '\0';
while(1) {
char a = string[index];
index++;
char t1[20];
char state[5];
strcpy(t1, "Shift ");
strcat(t1, state);
matched_string[m_index++] = a;
matched_string[m_index] = '\0';
printf("%-30s\n", t1);
pop();
int t = get_top();
matched_string[m_index++] = A;
matched_string[m_index] = '\0';
char t1[20];
strcat(t1, augmented_grammar[j]);
printf("%-30s\n", t1);
printf("%-30s\n", "Accept!!");
break;
else { //Error.
printf("%-30s\n", "Error!!\n\n");
exit(0);
printf("\nString accepted!\n");
}
PARSER.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"closure_goto.h"
#include"parsingtable.h"
#include"first_follow.h"
#include"parse.h"
int main() {
initialize_first_follow();
compute_first();
compute_follow();
create_parsing_table();
return 0;
PARSINGTABLE.h
//Parsing Table.
char ACTION[30][100][100];
int GOTO[30][100];
} table;
int i, j;
strcpy(table.ACTION[i][j], "e");
table.GOTO[i][j] = -1;
void print_table() {
int i, j;
printf(" | ");
printf("%10c", nonterminals[i]);
printf("\n\n");
if(!strcmp(table.ACTION[i][j], "e"))
printf("%10s", ".");
else
printf("%10s", table.ACTION[i][j]);
printf(" | ");
if(table.GOTO[i][j] == -1)
printf("%10s", ".");
else
printf("%10d", table.GOTO[i][j]);
}
printf("\n");
void Goto(int i, int item, char *temp) { //Computes goto for 'item'th item of 'i'th
state.
char t;
strcpy(temp, items[i][item]);
if(temp[i] == '.') {
t = temp[i];
temp[i] = temp[i+1];
temp[i+1] = t;
break;
int get_state(char *t, int state) { //Returns the state of a given item.
int i, j;
for(i = state; i < (no_of_states + state); i++) { //Start searching from current
state and then wrap around.
for(j = 0; j < no_of_items[i % no_of_states]; j++) {
return i % no_of_states;
int i;
if(flag == 0)
if(terminals[i] == symbol)
return i;
else
if(nonterminals[i] == symbol)
return i;
if(flag == 0)
int i, j;
char production[20];
if(item[i] != '.') {
production[j] = item[i];
j++;
production[j] = '@';
j++;
production[j] = '\0';
if(!strcmp(production, augmented_grammar[i]))
return i;
}
void compute_action() {
int i, item, j;
exit(-1);
if(strcmp(table.ACTION[i][get_pos(0,s[1])], "e")) {
//Multiple entries conflict.
char state[3];
j = get_state(temp, i);
strcpy(temp, "S:");
strcat(temp, state);
j = get_state(temp, i);
table.GOTO[i][get_pos(1, s[1])] = j;
}
else { //dot is at end of string. Rule 2. REDUCE ACTION!!
int k, n;
n = get_production_no(items[i][item]); //Get
production number from Augmented Grammar.
strcpy(temp, "R:");
strcat(temp, production_no);
exit(-1);
}
strcpy(table.ACTION[1][get_pos(0, '$')], "acc"); //Accept-entry for item
[S'->S.]
void create_parsing_table() {
initialize_table();
compute_action();
print_table();
OUTPUT