Compiler Design
Compiler Design
Compiler Design
DATE:
ALGORITHM:
1. Start the program.
2. Include the necessary header files.
3. Initialise the 2D array for transition states.
4. Input the regular expression.
5. Use conditional statements to identify concatenation, union or Kleene closure in the
regular expression.
6. Initialise the state transition matrix with states using step 5.
7. Print the transitions.
8. End the program.
PROGRAM:
#include<stdio.h>
#include<string.h>
int main()
{
char reg[20];
int q[20][3],i,j,len,a,b;
for(a=0;a<20;a++)
{
for(b=0;b<3;b++)
{
q[a][b]=0;
}
}
printf("Regular expression: \n");
scanf("%s",reg);
len=strlen(reg);
i=0;
j=1;
while(i<len)
1
{
if(reg[i]=='a'&®[i+1]!='/'&®[i+1]!='*')
{
q[j][0]=j+1;
j++;
}
if(reg[i]=='b'&®[i+1]!='/'&®[i+1]!='*')
{
q[j][1]=j+1;
j++;
}
if(reg[i]=='e'&®[i+1]!='/'&®[i+1]!='*')
{
q[j][2]=j+1;
j++;
}
if(reg[i]=='a'&®[i+1]=='/'&®[i+2]=='b')
{
q[j][2]=((j+1)*10)+(j+3);
j++;
q[j][0]=j+1;
j++;
q[j][2]=j+3;
j++;
q[j][1]=j+1;
j++;
q[j][2]=j+1;
j++;
i=i+2;
}
if(reg[i]=='b'&®[i+1]=='/'&®[i+2]=='a')
{
q[j][2]=((j+1)*10)+(j+3);
j++;
q[j][1]=j+1;
j++;
q[j][2]=j+3;
j++;
q[j][0]=j+1;
j++;
q[j][2]=j+1;
j++;
i=i+2;
}
2
if(reg[i]=='a'&®[i+1]=='*')
{
q[j][2]=((j+1)*10)+(j+3);
j++;
q[j][0]=j+1;
j++;
q[j][2]=((j+1)*10)+(j-1);
j++;
}
if(reg[i]=='b'&®[i+1]=='*')
{
q[j][2]=((j+1)*10)+(j+3);
j++;
q[j][1]=j+1;
j++;
q[j][2]=((j+1)*10)+(j-1);
j++;
}
if(reg[i]==')'&®[i+1]=='*')
{
q[0][2]=((j+1)*10)+1;
q[j][2]=((j+1)*10)+1;
j++;
}
i++;
}
printf("Transition function \n");
for(i=0;i<=j;i++)
{
if(q[i][0]!=0)
printf("\n q[%d,a]-->%d",i,q[i][0]);
if(q[i][1]!=0)
printf("\n q[%d,b]-->%d",i,q[i][1]);
if(q[i][2]!=0)
{
if(q[i][2]<10)
printf("\n q[%d,e]-->%d",i,q[i][2]);
else
printf("\n q[%d,e]-->%d & %d",i,q[i][2]/10,q[i][2]%10);
}
}
return 0;
}
3
OUTPUT:
RESULT: The program for conversion of Regular Expression to NFA was successfully
executed and the output was verified.
4
EX.2 CONVERSION OF NFA TO DFA
DATE:
ALGORITHM:
1. Start the program.
2. Include necessary header files.
3. Initialise the NFA transition table matrix (NFAtab[][]) with values.
4. In case of transition to a new state, print the transition for the new state.
5. In case of transition to a null state, create new state and print the transition for the new
state.
6. Print the DFA transition table matrix (DFAtab[][]).
7. End the program.
PROGRAM:
#include <stdio.h>
#include <string.h>
int N_symbols;
int NFA_states;
char *NFAtab[STATES][SYMBOLS];
int DFA_states;
int DFAtab[STATES][SYMBOLS];
printf(“DFA is:\n”);
5
printf(“Q = { “);
for(i=0; i<nstates; i++)
{
printf(“%c “, stname++);
}
printf(“}\n”);
printf(“Sigma = { “);
for(i=0; i<nsymbols; i++)
{
printf(“%d “, i);
}
printf(“}\n”);
printf(“ | “);
for (I = 0; I < nsymbols; i++) printf(“ %c “, ‘0’+i);
printf(“\n-----+--");
for (I = 0; I < nsymbols; i++) printf(“-----");
printf(“\n”);
void init_NFA_table()
{
NFAtab[0][0] = “12”;
NFAtab[0][1] = “13”;
NFAtab[1][0] = “12”;
NFAtab[1][1] = “13”;
NFAtab[2][0] = “4”;
NFAtab[2][1] = “”;
6
NFAtab[3][0] = “”;
NFAtab[3][1] = “4”;
NFAtab[4][0] = “4”;
NFAtab[4][1] = “4”;
NFA_states = 5;
DFA_states = 0;
N_symbols = 2;
}
strcpy(s, temp);
}
temp[0] = ‘\0’;
for (I = 0; I < strlen(cur_states); i++)
string_merge(temp, nfa[cur_states[i]-‘0’][symbol]);
strcpy(nextstates, temp);
}
7
{
int I;
strcpy(statename[i], state);
return (*pn)++;
}
char nextstate[STATES];
int j;
strcpy(statename[0], “0”);
return n;
}
int main()
{
init_NFA_table();
DFA_states = nfa_to_dfa(NFAtab, NFA_states, N_symbols, DFAtab);
put_dfa_table(DFAtab, DFA_states, N_symbols);
return 0;
}
8
OUTPUT:
RESULT: The program for conversion of NFA to DFA was successfully executed and the
output was verified.
9
EX.3 CONVERSION OF REGULAR EXPRESSION TO DFA
DATE:
ALGORITHM:
1. Start the program.
2. Include the necessary header files.
3. Initialise the 2D array for transition states.
4. Input the regular expression.
5. Use conditional statements to identify concatenation, union or Kleene closure in the
regular expression.
6. Initialise the state transition matrix with states using step 5.
7. Print the transitions.
8. End the program.
PROGRAM:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
int ret[100];
static int pos=0;
static int sc=0;
void dfa(int st, int p, char* s)
{
int i,sp,fs[15],fsc=0;
sp=st;
pos=p;
sc=st;
while(*s!=NULL)
{
if(isalpha(*s))
{
ret[pos++]=sp;
ret[pos++]=*s;
10
if(*(s+1)!='*')
ret[pos++]=++sc;
}
if(*s=='.')
{
sp=sc;
}
if(*s=='+')
{
sp=st;
fs[fsc++]=sc;
}
if(*s=='*')
{
ret[pos++]=sc;
}
if(*s=='(')
{
char ps[50];
int i=0, flag=1;
s++;
while(flag!=0)
{
ps[i++]=*s;
if(*s=='(')
flag++;
if(*s==')')
flag--;
s++;
}
ps[--i]='\0';
dfa(sc,pos,ps);
s--;
}
s++;
}
sc++;
}
void main()
{
int i;
char *inp;
printf("\nenter the regular expression: ");
gets(inp);
11
dfa(1,0,inp);
printf("\nstate input state\n");
for(i=0;i<pos;i+=3)
printf("%d -->%c--> %d\n",ret[i],ret[i+1],ret[i+2]);
printf("\n");
getch();
}
OUTPUT:
RESULT: The program for conversion of Regular Expression to DFA was successfully
executed and the output was verified.
12
EX.4 COMPUTATION OF FIRST & FOLLOW SETS
DATE:
AIM: To write a C program to compute the First and Follow sets of an input grammar.
ALGORITHM:
1. Start the program.
2. Include the necessary header files.
3. Input the number of productions.
4. Input the productions.
5. Print FIRST(NT) for the non-terminals NT in the input productions.
6. Print FOLLOW(NT) for the non-terminals NT in the input productions.
7. End the program.
PROGRAM:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
int n,m=0,p,i=0,j=0, k;
char a[10][10],f[10];
void follow(char c);
void first(char c);
int main(){
int i,z;
char c,ch;
printf("Enter the no of productions:\n");
scanf("%d",&n);
printf("Enter the productions:\n");
for(i=0;i<n;i++)
scanf("%s%c",a[i],&ch);
for(k=0; k<n; k++)
{
c=a[k][0];
first(c);
printf("First(%c)={",c);
13
for(i=0;i<m;i++)
printf("%c",f[i]);
printf("}\n");
strcpy(f," ");
m=0;
follow(c);
printf("Follow(%c)={",c);
for(i=0;i<m;i++)
printf("%c",f[i]);
printf("}\n");
}
return(0);
}
void first(char c)
{
int k;
if(!isupper(c))
f[m++]=c;
for(k=0;k<n;k++)
{
if(a[k][0]==c)
{
if(a[k][3]=='$')
follow(a[k][0]);
else if(islower(a[k][3]))
f[m++]=a[k][3];
else first(a[k][3]);
}
}
}
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')
14
first(a[i][j+1]);
if(a[i][j+1]=='\0' && c!=a[i][0])
follow(a[i][0]);
}
}
}
}
OUTPUT:
RESULT: The program for computation of First and Follow sets was successfully
executed and the output was verified.
15
EX.5 COMPUTATION OF LEADING & TRAILING SETS
DATE:
AIM: To write a C program to compute the Leading and Trailing sets of an input grammar.
ALGORITHM:
1. Start the program.
2. Include the necessary header files.
3. Input the number of productions.
4. Input the productions.
5. Print the leading for the non-terminals in the input productions.
6. Print the trailing for the non-terminals in the input productions.
7. End the program.
PROGRAM:
#include<stdio.h>
#include<ctype.h>
#include<conio.h>
#include<string.h>
#define MAX_LEN 30
void get_productions(int);
void addToResultSet(char arr[],char c);
void lead_trail(int);
void lead(char*,char,int);
void trail(char*,char,int);
struct prod {
char lhs[MAX_LEN];
char rhs[MAX_LEN];
} pin[MAX_LEN];
struct letr_tab {
char NT[MAX_LEN];
char lead[MAX_LEN];
16
char trail[MAX_LEN];
} lt[MAX_LEN];
void get_productions(int n) {
int i,j,k,l;
char pr[MAX_LEN];
for(i = 0; i < n; i++) {
j = 0;
scanf("%s",pr);
while(pr[j] != '\0') {
if(pr[j] == '-' && pr[j+1] == '>') {
for(k = 0; k < j; k++) {
pin[i].lhs[k] = pr[k];
}
pin[i].lhs[k] = '\0';
l = j + 2;
}
j++;
}
j = l;
k = 0;
while(pr[j] != '\0') {
pin[i].rhs[k] = pr[j];
k++;
j++;
}
pin[i].rhs[k] = '\0';
}
}
17
int i,j,k,lead_flag;
char subResult[MAX_LEN] = "\0";
for(i = 0; i < n; i++) {
if( pin[i].lhs[0] == c ) {
lead_flag = 1;
for(j = 0; pin[i].rhs[j] != '\0';j++) {
if(lead_flag == 1) {
if(!isupper(pin[i].rhs[j])) {
addToResultSet(Result,pin[i].rhs[j]);
lead_flag = -1;
}
else {
if(c == pin[i].rhs[j]) {
continue;
}
lead(subResult,pin[i].rhs[j],n);
for(k=0;subResult[k]!='\0';k++) {
addToResultSet(Result,subResult[k]);
}
lead_flag = -1;
}
}
if(pin[i].rhs[j] == '|') {
lead_flag = 1;
}
}
}
}
}
18
addToResultSet(Result,rev[j]);
trail_flag = -1;
}
else {
if(c == rev[j]) {
continue;
}
trail(subResult,rev[j],n);
for(k = 0; subResult[k] != '\0'; k++) {
addToResultSet(Result,subResult[k]);
}
}
}
if(rev[j] == '|') {
trail_flag = 1;
}
}
}
}
}
void lead_trail(int n) {
int i;
for(i = 0; i < n; i++) {
strcpy(lt[i].NT,pin[i].lhs);
lead(lt[i].lead,lt[i].NT[0],n);
printf("LEAD OF %c: %s\n",lt[i].NT[0],lt[i].lead);
}
for(i = 0; i < n; i++) {
trail(lt[i].trail,lt[i].NT[0],n);
printf("TRAIL OF %c: %s\n",lt[i].NT[0],lt[i].trail);
}
}
void main() {
int n;
get_productions(n);
lead_trail(n);
}
19
OUTPUT:
RESULT: The program for computation of Leading and Trailing sets was successfully
executed and the output was verified.
20
EX.6 CONSTRUCTION OF PREDICTIVE PARSING TABLE
DATE:
AIM: To write a C program to construct the Predictive Parsing Table for the given
grammar.
ALGORITHM:
1. Start the program.
2. Include the necessary header files.
3. Input the number of productions.
4. Input the productions.
5. Print the FIRST and FOLLOW for the non-terminals in the input productions.
6. Print the transitions of the predictive parsing table for the input productions using
FIRST and FOLLOW from step 5.
7. End the program.
PROGRAM:
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char fin[10][20],st[10][20],ft[20][20],fol[20][20];
int a=0,e,i,t,b,c,n,k,l=0,j,s,m,p;
printf("enter the no. of coordinates\n");
scanf("%d",&n);
printf("enter the productions in a grammar\n");
for(i=0;i<n;i++)
scanf("%s",st[i]);
for(i=0;i<n;i++)
fol[i][0]='\0';
for(s=0;s<n;s++)
{
for(i=0;i<n;i++)
21
{
j=3;
l=0;
a=0;
l1:if(!((st[i][j]>64)&&(st[i][j]<91)))
{
for(m=0;m<l;m++)
{
if(ft[i][m]==st[i][j])
goto s1;
}
ft[i][l]=st[i][j];
l=l+1;
s1:j=j+1;
}
else
{
if(s>0)
{
while(st[i][j]!=st[a][0])
{
a++;
}
b=0;
while(ft[a][b]!='\0')
{
for(m=0;m<l;m++)
{
if(ft[i][m]==ft[a][b])
goto s2;
}
ft[i][l]=ft[a][b];
l=l+1;
s2:b=b+1;
}
}
}
while(st[i][j]!='\0')
{
if(st[i][j]=='|')
{
j=j+1;
goto l1;
}
22
j=j+1;
}
ft[i][l]='\0';
}
}
printf("first pos\n");
for(i=0;i<n;i++)
printf("FIRS[%c]=%s\n",st[i][0],ft[i]);
fol[0][0]='$';
for(i=0;i<n;i++)
{
k=0;
j=3;
if(i==0)
l=1;
else
l=0;
k1:while((st[i][0]!=st[k][j])&&(k<n))
{
if(st[k][j]=='\0')
{
k++;
j=2;
}
j++;
}
j=j+1;
if(st[i][0]==st[k][j-1])
{
if((st[k][j]!='|')&&(st[k][j]!='\0'))
{
a=0;
if(!((st[k][j]>64)&&(st[k][j]<91)))
{
for(m=0;m<l;m++)
{
if(fol[i][m]==st[k][j])
break;
}
fol[i][l]=st[k][j];
l++;
}
else
23
{
while(st[k][j]!=st[a][0])
{
a++;
}
p=0;
while(ft[a][p]!='\0')
{
if(ft[a][p]!='@')
{
for(m=0;m<l;m++)
{
if(fol[i][m]==ft[a][p])
goto q2;
}
fol[i][l]=ft[a][p];
l=l+1;
}
else
e=1;
q2:p++;
}
if(e==1)
{
e=0;
goto a1;
}
}
}
else
{
a1:c=0;
a=0;
while(st[k][0]!=st[a][0])
{
a++;
}
while((fol[a][c]!='\0')&&(st[a][0]!=st[i][0]))
{
for(m=0;m<l;m++)
{
if(fol[i][m]==fol[a][c])
goto q1;
}
24
fol[i][l]=fol[a][c];
l++;
q1:c++;
}
}
goto k1;
}
fol[i][l]='\0';
}
printf("follow pos\n");
for(i=0;i<n;i++)
printf("FOLLOW[%c]=%s\n",st[i][0],fol[i]);
printf("\n");
s=0;
for(i=0;i<n;i++)
{
j=3;
while(st[i][j]!='\0')
{
if((st[i][j-1]=='|')||(j==3))
{
for(p=0;p<=2;p++)
{
fin[s][p]=st[i][p];
}
t=j;
for(p=3;((st[i][j]!='|')&&(st[i][j]!='\0'));p++)
{
fin[s][p]=st[i][j];
j++;
}
fin[s][p]='\0';
if(st[i][k]=='@')
{
b=0;
a=0;
while(st[a][0]!=st[i][0])
{
a++;
}
while(fol[a][b]!='\0')
{
printf("M[%c,%c]=%s\n",st[i][0],fol[a][b],fin[s]);
b++;
25
}
}
else if(!((st[i][t]>64)&&(st[i][t]<91)))
printf("M[%c,%c]=%s\n",st[i][0],st[i][t],fin[s]);
else
{
b=0;
a=0;
while(st[a][0]!=st[i][3])
{
a++;
}
while(ft[a][b]!='\0')
{
printf("M[%c,%c]=%s\n",st[i][0],ft[a][b],fin[s]);
b++;
}
}
s++;
}
if(st[i][j]=='|')
j++;
}
}
getch();
}
26
OUTPUT:
RESULT: The program for construction of predictive parsing table was successfully
executed and the output was verified.
27
EX.7 RECURSIVE DESCENT PARSING
DATE:
AIM: To write a C program to implement Recursive Descent Parsing for a given input
string.
ALGORITHM:
1. Start the program.
2. Include the necessary header files.
3. Define functions for the non-terminals in a set of productions.
4. Input the string.
5. Recursively invoke the functions in step 3 according to the input string in step 4 and
increment count.
6. If count == strlen(input_string), print “String accepted”.
7. End the program.
PROGRAM:
#include<stdio.h>
#include<ctype.h>
#include<string.h>
void Tprime();
void Eprime();
void E();
void check();
void T();
char expression[10];
int count, flag;
int main()
{
count = 0;
flag = 0;
printf("\nEnter an Algebraic Expression:\t");
28
scanf("%s", expression);
E();
if((strlen(expression) == count) && (flag == 0))
{
printf("\nThe Expression %s is Valid\n", expression);
}
else
{
printf("\nThe Expression %s is Invalid\n", expression);
}
}
void E()
{
T();
Eprime();
}
void T()
{
check();
Tprime();
}
void Tprime()
{
if(expression[count] == '*')
{
count++;
check();
Tprime();
}
}
void check()
{
if(isalnum(expression[count]))
{
count++;
}
else if(expression[count] == '(')
{
count++;
E();
29
if(expression[count] == ')')
{
count++;
}
else
{
flag = 1;
}
}
else
{
flag = 1;
}
}
void Eprime()
{
if(expression[count] == '+')
{
count++;
T();
Eprime();
}
}
OUTPUT:
RESULT: The program for implementation of Recursive Descent Parsing was successfully
executed and the output was verified.
30
EX.8 IMPLEMENTATION OF SHIFT REDUCE PARSING
DATE:
AIM: To write a C program to perform Shift Reduce Parsing on a given input string.
ALGORITHM:
1. Check if the first element of a non-terminals production is a terminal.
2. Accept the action, given that the input string is given and each symbol is pushed to a
stack. In reduce action the element is pushed out.
3. Parsing is complete in case of ACCEPT action.
4. Print the Shift Reduce Parsing table.
5. End the program.
PROGRAM:
#include<stdio.h>
#include<conio.h>
#include<string.h>
int k=0,z=0,i=0,j=0,c=0;
char a[16],ac[20],stk[15],act[10];
void check();
int main()
{
31
a[j]=' ';
a[j+1]=' ';
printf("\n$%s\t%s$\t%sid",stk,a,act);
check();
}
else
{
stk[i]=a[j];
stk[i+1]='\0';
a[j]=' ';
printf("\n$%s\t%s$\t%ssymbols",stk,a,act);
check();
}
}
getch();
}
void check()
{
strcpy(ac,"REDUCE TO E");
for(z=0; z<c; z++)
if(stk[z]=='i' && stk[z+1]=='d')
{
stk[z]='E';
stk[z+1]='\0';
printf("\n$%s\t%s$\t%s",stk,a,ac);
j++;
}
for(z=0; z<c; z++)
if(stk[z]=='E' && stk[z+1]=='+' && stk[z+2]=='E')
{
stk[z]='E';
stk[z+1]='\0';
stk[z+2]='\0';
printf("\n$%s\t%s$\t%s",stk,a,ac);
i=i-2;
}
for(z=0; z<c; z++)
if(stk[z]=='E' && stk[z+1]=='*' && stk[z+2]=='E')
{
stk[z]='E';
stk[z+1]='\0';
stk[z+1]='\0';
printf("\n$%s\t%s$\t%s",stk,a,ac);
i=i-2;
32
}
for(z=0; z<c; z++)
if(stk[z]=='(' && stk[z+1]=='E' && stk[z+2]==')')
{
stk[z]='E';
stk[z+1]='\0';
stk[z+1]='\0';
printf("\n$%s\t%s$\t%s",stk,a,ac);
i=i-2;
}
}
OUTPUT:
RESULT: The program for Shift Reduce Parsing was successfully executed and the output
was verified.
33
EX.9 COMPUTATION OF LR(0) ITEMS
DATE:
AIM: To write a C program to compute the LR(0) items for an input grammar.
ALGORITHM:
1. Start the program.
2. Include the necessary header files.
3. Input the productions.
4. Print the augmented grammar for input production.
5. Print the LR(0) set of items until the accept state.
6. End the program.
PROGRAM:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char items[30][10][12];
char ag[100][100], t[10], nt[10];
int np = 0, ns = 0, ni[30], noft = 0, nofnt = 0;
char FIRST[2][10][10];
char FOLLOW[10][10];
int si = 0, gsi = 0, cii = 0;
int check(char c) {
int i;
for(i = 0; i < noft; i++)
if(t[i] == c)
return 1;
return 0;
}
void generate_t() {
int i, j;
int index = 0;
for(i = 0; i < np; i++) {
for(j = 0; ag[i][j] != '>'; j++);
j++;
34
for(; ag[i][j] != '\0'; j++) {
if(ag[i][j] < 65 || ag[i][j] > 90) {
if(!check(ag[i][j])) {
t[index] = ag[i][j];
noft++;
index++;
}
}
}
}
t[index] = '$';
noft++;
index++;
t[index] = '\0';
}
int check2(char c, int index) {
int i;
for(i = 0; i < index; i++)
if(nt[i] == c)
return 1;
return 0;
}
void generate_nt() {
int i, index = 0;
for(i = 0; i < np; i++)
if(!check2(ag[i][0], index)) {
nt[index] = ag[i][0];
index++;
}
nofnt = index;
nt[index] = '\0';
}
void initialize_items() {
int i;
generate_t();
generate_nt();
for(i = 0; i < 30; i++)
ni[i] = 0;
}
void generate_item(char *s, char *t) {
int i;
for(i = 0; i < 3; i++)
t[i] = s[i];
t[i] = '.';
35
if(s[i] != '@')
for(; i < strlen(s); i++)
t[i+1] = s[i];
t[i+1] = '\0';
}
int item_found(char *s) {
int i;
for(i = 0; i < cii; i++) {
if(!strcmp(s, items[si][i]))
return 1;
}
return 0;
}
int isterminal(char s) {
int i;
for(i = 0; i < noft; i++)
if(s == t[i])
return 1;
return 0;
}
void closure(char *s) {
int i, j;
for(i = 0; s[i] != '.'; i++);
i++;
if(!item_found(s)) {
strcpy(items[si][cii], s);
cii++;
}
if(s[i] == s[0] && s[i-2] == '>')
return;
if(isterminal(s[i]))
return;
else {
for(j = 0; j < np; j++) {
char temp[100];
if(ag[j][0] == s[i]) {
generate_item(ag[j], temp);
closure(temp);
}
}
}
}
int Goto1(char s, char temp[][100]) {
int i, j;
36
int n = 0;
char t, temp2[100];
if(s == '\0') {
return n;
}
for(i = 0; i < ni[gsi]; i++) {
strcpy(temp2, items[gsi][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 state_found(char *s) {
int i;
return 0;
}
void compute_closure_goto() {
37
char temp[100][100], transition_items[100];
int i, no_of_goto_items,j, transition_index = 0;
generate_item(ag[0], temp[0]);
closure(temp[0]);
ni[si] = cii;
cii = 0;
si++;
while(gsi < 30) {
transition_index = 0;
transition_items[transition_index] = '\0';
for(i = 0; i < ni[gsi]; i++) {
for(j = 0; items[gsi][i][j] != '.'; j++);
j++;
if(!transition_item_found(transition_items, items[gsi][i][j], transition_index)) {
transition_items[transition_index] = items[gsi][i][j];
transition_index++;
}
}
transition_items[transition_index] = '\0';
for(i = 0; i < transition_index; i++) {
int add_flag = 0;
no_of_goto_items = Goto1(transition_items[i], temp);
for(j = 0; j < no_of_goto_items; j++) {
if(!state_found(temp[j])) {
add_flag = 1;
closure(temp[j]);
}
else
break;
}
if(add_flag) {
ni[si] = cii;
cii = 0;
si++;
}
}
gsi++;
}
ns = si;
}
void print() {
int i, j;
printf("\nNumber of states = %d.\n", ns);
38
for(i = 0; i < ns; i++) {
printf("\n\nItems in State %d...\n\n", i);
for(j = 0; j < ni[i]; j++)
printf("%s\n", items[i][j]);
}
}
int main() {
int i;
char str[100];
printf("Enter number of productions:");
scanf("%d", &np);
printf("Enter the productions...\n");
for(i = 1; i <= np; i++)
scanf("%s", ag[i]);
printf("\n\nAugmented Grammar is...\n\n");
strcpy(ag[0], "Z->");
str[0] = ag[1][0];
str[1] = '\0';
strcat(ag[0], str);
np++;
for(i = 0; i < np; i++)
printf("%s\n", ag[i]);
initialize_items();
compute_closure_goto();
print();
return 0;
}
39
OUTPUT:
RESULT: The program for computation of LR(0) items was successfully executed and the
output was verified.
40
EX.10 CONSTRUCTION OF DAG
DATE:
ALGORITHM:
1. Start the program.
2. Include the necessary header files.
3. Input the expression to create the DAG.
4. Print the DAG table having left pointer and right pointer as per condition.
5. End the program.
PROGRAM:
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<conio.h>
int main()
{
struct da
{
int ptr,left,right;
char label;
}dag[25];
int ptr,l,j,change,n=0,i=0,state=1,x,y,k;
char store,*input1,input[25],var;
for(i=0;i<25;i++)
{dag[i].ptr=NULL;
dag[i].left=NULL;
dag[i].right=NULL;
dag[i].label=NULL;
}
printf("\n\nENTER THE EXPRESSION\n\n");
scanf("%s",input1);
for(i=0;i<25;i++)
input[i]=NULL;
41
l=strlen(input1);
a:
for(i=0;input1[i]!=')';i++);
for(j=i;input1[j]!='(';j--);
for(x=j+1;x<i;x++) {
if (isalpha(input1[x]))
input[n++] = input1[x];
else if (input1[x] != '0')
store = input1[x];
}
input[n++]=store;
for(x=j;x<=i;x++)
input1[x]='0';
if(input1[0]!='0')goto a;
for(i=0;i<n;i++)
{
dag[i].label=input[i];
dag[i].ptr=i;
if(!isalpha(input[i])&&!isdigit(input[i]))
{
dag[i].right=i-1;
ptr=i;
var=input[i-1];
if(isalpha(var))
ptr=ptr-2;
else
{
ptr=i-1;
b:
if(!isalpha(var)&&!isdigit(var))
{
ptr=dag[ptr].left;
var=input[ptr];
goto b;
}
else
ptr=ptr-1;
}
dag[i].left=ptr;
}
}
printf("\n SYNTAX TREE FOR GIVEN EXPRESSION\n\n");
printf("\n\n PTR \t\t LEFT PTR \t\t RIGHT PTR \t\t LABEL\n\n");
for(i=0;i<n;i++)
42
printf("\n%d\t%d\t%d\t%c\n",dag[i].ptr,dag[i].left,dag[i].right,dag[i].label);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if((dag[i].label==dag[j].label&&dag[i].left==dag[j].left)&&dag[i].right==dag[j].right)
{
for(k=0;k<n;k++)
{
if(dag[k].left==dag[j].ptr)
dag[k].left=dag[i].ptr;
if(dag[k].right==dag[j].ptr)
dag[k].right=dag[i].ptr;
}
dag[j].ptr=dag[i].ptr;
}
}
}
printf("\n DAG FOR GIVEN EXPRESSION\n\n");
printf("\n\n PTR \t LEFT PTR \t RIGHT PTR \t LABEL \n\n");
for(i=0;i<n;i++)
printf("\n %d\t\t%d\t\t%d\t\t%c\n",dag[i].ptr,dag[i].left,dag[i].right,dag[i].label);
return 0;
}
43
OUTPUT:
RESULT: The program for construction of DAG was successfully executed and the output
was verified.
44
EX.11 INTERMEDIATE CODE GENERATION:
THREE ADDRESS CODES
DATE:
ALGORITHM:
1. Start the program.
2. Include the necessary header files.
3. Display the choices for the type of input expression. (assignment, arithmetic,
relational)
4. Choose an option for type of input expression.
5. Input an expression.
6. Print three address code for the input expression.
7. End the program.
PROGRAM:
#include<stdio.h>
#include<conio.h>
#include<string.h>
void pm();
void plus();
void div();
int i,ch,j,l,addr=100;
char ex[10],exp[10],exp1[10],exp2[10],id1[5],op[5],id2[5];
void main()
{
clrscr();
while(1)
{
printf("\n1.assignment\n2.arithmetic\n3.relational\n4.Exit\nEnter the choice:");
scanf("%d",&ch);
switch(ch)
{
45
case 1:
printf("\nEnter the expression with assignment operator:");
scanf("%s",exp);
l=strlen(exp);
exp2[0]='\0';
i=0;
while(exp[i]!='=')
{
i++;
}
strncat(exp2,exp,i);
strrev(exp);
exp1[0]='\0';
strncat(exp1,exp,l-(i+1)); strrev(exp1);
exp1[0]='\0';
for(i=0;i<l;i++)
{
if(exp[i]=='+'||exp[i]=='-')
{
if(exp[i+2]=='/'||exp[i+2]=='*')
{
pm();
break;
}
else
{
plus();
break;
}
}
else if(exp[i]=='/'||exp[i]=='*')
{
div();
break;
}
}
46
break;
case 3:
printf("Enter the expression with relational operator");
scanf("%s%s%s",&id1,&op,&id2);if(((strcmp(op,"<")==0)||(strcmp(op,">")==0)||(strcmp
(op,"<=")==0)||(strcmp(op,">=")==0)||(strcmp(op,"==")==0)||(strcmp(op,"!=")==0))==0)
printf("Expression is error");
else
{
printf("\n%d\tif %s%s%s goto %d",addr,id1,op,id2,addr+1); addr++;
printf("\n%d\t ",addr); addr++;
printf("\n%d\t goto %d",addr,addr+1); addr++;
printf("\n%d\t ",addr);
}
break;
case 4:
exit(0);
}
}
}
void pm()
{
strrev(exp); j=l-i-1;
strncat(exp1,exp,j);
strrev(exp1);
printf("Three address code:\ntemp=%s\ntemp1=%c%ctemp\n",exp1,exp[j+1],exp[j]);
}
void div()
{
strncat(exp1,exp,i+2);
printf("Three address
code:\ntemp=%s\ntemp1=temp%c%c\n",exp1,exp[i+2],exp[i+3]);
}
void plus()
{
strncat(exp1,exp,i+2);
printf("Three address
code:\ntemp=%s\ntemp1=temp%c%c\n",exp1,exp[i+2],exp[i+3]);
}
47
OUTPUT:
RESULT: The program for generation of 3-address codes was successfully executed and
the output was verified.
48
EX.12 INTERMEDIATE CODE GENERATION:
POSTFIX, PREFIX
DATE:
AIM: To write a C program to convert an infix expression to prefix and postfix notations.
ALGORITHM:
1. Start the program.
2. Include the necessary header files.
3. Input the infix expression.
4. Convert to prefix notation using stack.
5. Convert to postfix notation using stack.
6. Print the output.
7. End the program.
PROGRAM:
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<string.h>
#define MAX 50
int precedence(char);
void init(stack *);
int empty(stack *);
int full(stack *);
int pop(stack *);
void push(stack *,int );
int top(stack *);
49
void infix_to_prefix(char infix[],char prefix[]);
void infix_to_postfix(char infix[],char postfix[]);
void eval_prefix(char prefix[]);
void eval_postfix(char postfix[]);
int evaluate(char x,int op1,int op2);
void main()
{ char infix[30],postfix[30],prefix[30];
printf("\nEnter an infix expression : ");
gets(infix);
infix_to_postfix(infix,postfix);
infix_to_prefix(infix,prefix);
printf("\nPostfix : %s\nPrefix: %s ",postfix,prefix);
}
void infix_to_prefix(char infix[],char prefix[])
{ int i,j;
char temp,in1[30];
for(i=strlen(infix)-1,j=0;i>=0;i--,j++)
in1[j]=infix[i];
in1[j]='\0';
for(i=0;in1[i]!='\0';i++)
{
if(in1[i]=='(')
in1[i]=')';
else
if(in1[i]==')')
in1[i]='(';
}
infix_to_postfix(in1,prefix);
for(i=0,j=strlen(prefix)-1;i<j;i++,j--)
{
temp=prefix[i];
prefix[i]=prefix[j];
prefix[j]=temp;
}
}
void infix_to_postfix(char infix[],char postfix[])
{ stack s;
char x;
int i,j;
char token;
init(&s);
j=0;
50
for(i=0;infix[i]!='\0';i++)
{ token=infix[i];
if(isalnum(token))
postfix[j++]=token;
else
if(token == '(')
push(&s,'(');
else
if(token == ')')
while((x=pop(&s))!='(')
postfix[j++]=x;
else
{
while(precedence(token)<=precedence(top(&s)) && !empty(&s))
{
x=pop(&s);
postfix[j++]=x;
}
push(&s,token);
}
}
while(!empty(&s))
{
x=pop(&s);
postfix[j++]=x;
}
postfix[j]='\0';
}
int precedence(char x)
{
if(x == '(') return(0);
if(x == '+' || x == '-') return(1);
if(x == '*' || x == '/' || x == '%') return(2);
return(3);
}
51
if(s->top==-1) return(1);
return(0);
}
int top(stack * p)
{
return(p->data[p->top]);
}
OUTPUT:
RESULT: The program for conversion of an infix expression to prefix and postfix
notations was successfully executed and the output was verified.
52
EX.13 ELIMINATING LEFT RECURSION
DATE:
ALGORITHM:
1. Start the program.
2. Include the necessary header files.
3. Input the production.
4. Convert the input production of type:
A --> A α| β
to:
A --> β A'
A' --> ε | αA'
5. Print the result.
6. End the program.
PROGRAM:
#include<stdio.h>
#include<string.h>
void main() {
char input[100],*l,*r,*temp,productions[25][50];
int i=0,j=0,flag=0;
printf("Enter the production: ");
scanf("%s",input);
l = strtok(input,"->");
r = strtok(NULL,"->");
temp = strtok(r,"|");
printf("\nAfter Eliminating Left Recursion:");
while(temp) {
if(temp[0] == l[0]) {
flag = 1;
sprintf(productions[i++],"%s->%s%s\0",l,temp+1,l);
}
53
else
sprintf(productions[i++],"%s->%s%s'\0",l,temp,l);
temp = strtok(NULL,"|");
}
sprintf(productions[i++],"%s->\356\0",l);
if(flag == 0)
printf("The given productions don't have Left Recursion");
else
for(j=0;j<i;j++) {
printf("\n%s",productions[j]);
}
}
OUTPUT:
RESULT: The program for Eliminating Left Recursion was successfully executed and the
output was verified.
54
EX.14 LEFT FACTORING
DATE:
ALGORITHM:
1. Start the program.
2. Include the necessary header files.
3. Input the production.
4. Convert production of type A-->ab1 | ab2 | ab3
to: A --> aA', A' --> b1 | b2| b3
5. Print the result.
6. End the program.
PROGRAM:
#include<stdio.h>
#include<string.h>
int main()
{
char a[10],a1[10],a2[10],a3[10],a4[10],a5[10];
int i,j=0,k,l;
printf("Enter production S->");
gets(a);
for(i=0;a[i]!='|';i++,j++)
a1[j]=a[i];
a1[j]='\0';
for(j=++i,i=0;a[j]!='\0';j++,i++)
a2[i]=a[j];
a2[i]='\0';
k=0;
l=0;
for(i=0;i<strlen(a1)||i<strlen(a2);i++)
{
if(a1[i]==a2[i])
{
a3[k]=a1[i];
55
k++;
}
else
{
a4[l]=a1[i];
a5[l]=a2[i];
l++;
}}
a3[k]='X';
a3[++k]='\0';
a4[l]='|';
a5[l]='\0';
a4[++l]='\0';
strcat(a4,a5);
printf("\nAfter Left Factoring:\n");
printf("\n S->%s",a3);
printf("\n X->%s",a4);
return 0;
}
OUTPUT:
RESULT: The program for performing Left Factoring was successfully executed and the
output was verified.
56
EX.15 LEXICAL ANALYZER
DATE:
ALGORITHM:
1. Start the program.
2. Get input line of code.
3. Identify the keywords, operators, constants, literals, and identifiers and store in arrays.
4. Print the lexemes according to their tokens.
5. End the program.
PROGRAM:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
void removeduplicate();
void final();
int Isiden(char ch);
int Isop(char ch);
int Isdel(char ch);
int Iskey(char * str);
char op[8]={'+','-','*','/','=','<','>','%'};
char del[8]={'}','{',';','(',')','[',']',','};
char *key[]={"int","void","main","char","float", "if"};
int idi=0,idj=0,k,opi=0,opj=0,deli=0,uqdi=0,uqidi=0,uqoperi=0,kdi=0,liti=0,ci=0;
int uqdeli[20],uqopi[20],uqideni[20],l=0,j;
char uqdel[20],uqiden[20][20],uqop[20][20],keyword[20][20];
char iden[20][20],oper[20][20],delim[20],litral[20][20],lit[20],constant[20][20];
57
int i=0;
while(str[i]!='\0')
{
if(Isiden(str[i]))
{
while(Isiden(str[i]))
{
iden[idi][idj++]=str[i++];
}
iden[idi][idj]='\0';
idi++;idj=0;
}
else
if(str[i]=='"')
{
lit[l++]=str[i];
for(j=i+1;str[j]!='"';j++)
{
lit[l++]=str[j];
}
lit[l++]=str[j];lit[l]='\0';
strcpy(litral[liti++],lit);
i=j+1;
}
else
if(Isop(str[i]))
{
while(Isop(str[i]))
{
oper[opi][opj++]=str[i++];
}
oper[opi][opj]='\0';
opi++;opj=0;
}
else
if(Isdel(str[i]))
{
while(Isdel(str[i]))
{
delim[deli++]=str[i++];
}
}
else
{
58
i++;
}
}
removeduplicate();
final();
}
59
f=1;
}
return f;
}
void removeduplicate()
{
int i,j;
for(i=0;i<20;i++)
{
uqdeli[i]=0;
uqopi[i]=0;
uqideni[i]=0;
}
for(i=1;i<deli+1;i++)
{
if(uqdeli[i-1]==0)
{
uqdel[uqdi++]=delim[i-1];
for(j=i;j<deli;j++)
{
if(delim[i-1]==delim[j])
uqdeli[j]=1;
}
}
}
for(i=1;i<idi+1;i++)
{
if(uqideni[i-1]==0)
{
strcpy(uqiden[uqidi++],iden[i-1]);
for(j=i;j<idi;j++)
{
if(!strcmp(iden[i-1],iden[j]))
uqideni[j]=1;
}
}
}
for(i=1;i<opi+1;i++)
{
if(uqopi[i-1]==0)
{
60
strcpy(uqop[uqoperi++],oper[i-1]);
for(j=i;j<opi;j++)
{
if(!strcmp(oper[i-1],oper[j]))
uqopi[j]=1;
}
}
}
}
void final()
{
int i=0;
idi=0;
for(i=0;i<uqidi;i++)
{
if(Iskey(uqiden[i]))
strcpy(keyword[kdi++],uqiden[i]);
else
if(isdigit(uqiden[i][0]))
strcpy(constant[ci++],uqiden[i]);
else
strcpy(iden[idi++],uqiden[i]);
}
61
for(i=0;i<kdi;i++)
{
printf("\t");
puts(keyword[i]);
}
62
OUTPUT:
RESULT: The program for performing Lexical Analysis was successfully executed and
the output was verified.
63