Record Contents
Record Contents
AIM: To implement a program to find the ԑ closure of all states of any given NFA with
ԑ transitions.
ALGORITHM:
Step 0: Start
Step 1: Declare arrays result, copy and states to store immediate and final
results.
Step 2: Declare the variables to hold state information and take input n which is
number of states from user.
Step 3: Open the file using fopen function and store its pointer in INPUT.
Step 4: Give state names for the inputted number of states.
Step 5: For each state in the states array,
5.1:- Initialise I to 0 and copy current state to state variable.
5.2:- Call add-state function to add current state to result array at index i.
5.3:- Enter a loop that reads transitions from input file until EOF is reached.
5.3.1:- if current state matches ‘state1’ and input symbol is epsilon(“ ԑ”),
call add_state function to add ‘state2’ to ‘result’ array at index I and
update ‘state’ with value of ‘state2’.
5.4:- Increment i for next iteration.
5.5:- Call the display function to print epsilon closure of current state.
5.6:- Rewind input file to its beginning using rewind function.
Step 6: Close the input file using fclose function.
Step 7: Stop
PROGRAM:
#include<stdio.h>
#include<string.h>
char result[20][20],copy[3],states[20][20];
3
void display(int n){
int k=0;
printf("\n\n\n Epsilon closure of %s = { ",copy);
while(k < n){
printf(" %s",result[k]);
k++;
}
printf(" } \n\n\n");
}
int main(){
FILE *INPUT;
INPUT=fopen("input.txt","r");
char state[3];
int end,i=0,n,k=0;
char state1[3],input[3],state2[3];
printf("\n Enter the no of states: ");
scanf("%d",&n);
printf("\n Enter the states n");
for(k=0;k<3;k++){
scanf("%s",states[k]);
for( k=0;k<n;k++){
i=0;
strcpy(state,states[k]);
4
strcpy(copy,state);
add_state(state,i++);
while(1){
end = fscanf(INPUT,"%s%s%s",state1,input,state2);
if (end == EOF ){
break;
}
if( strcmp(state,state1) == 0 ){
if( strcmp(input,"e") == 0 ) {
add_state(state2,i++);
strcpy(state, state2);
}
}
}
display(i);
rewind(INPUT);
}
return 0;
}
OUTPUT:
Enter the no of states: 3
5
Epsilon closure of q0 = { q0 q1 q2 }
Epsilon closure of q1 = { q1 q2 }
Epsilon closure of q2 = { q2 }
6
EXPERIMENT - 2
ALGORITHM:
PROGRAM:
#include<stdio.h>
#include<stdlib.h>
struct node
{
int st;
7
struct node *link;
};
void findclosure(int,int);
void insert_trantbl(int ,char, int);
int findalpha(char);
void findfinalstate(void);
void unionclosure(int);
void print_e_closure(int);
static int
set[20],nostate,noalpha,s,notransition,nofinal,start,finalstate[20],r,buffer[20];
static char c;
char alphabet[20];
static int e_closure[20][20]={0};
struct node * transition[20][20]={NULL};
void main()
{
int i,j,k,m,t,n;
printf("\nEnter alphabets?\n");
for(i=0;i<noalpha;i++)
{
alphabet[i]=getchar();
getchar();
}
printf("Enter the number of states?\n");
scanf("%d",&nostate);
printf("Enter the start state?\n");
scanf("%d",&start);
printf("Enter the number of final states?\n");
scanf("%d",&nofinal);
printf("Enter the final states?\n");
for(i=0;i<nofinal;i++)
8
scanf("%d",&finalstate[i]);
printf("Enter no of transition?\n");
scanf("%d",¬ransition);
printf("NOTE:- [Transition is in the form--> qno alphabet qno]\n");
printf("NOTE:- [States number must be greater than zero]\n");
printf("\nEnter transition?\n");
for(i=0;i<notransition;i++)
{
scanf("%d %c%d",&r,&c,&s);
insert_trantbl(r,c,s);
printf("\n");
for(i=1;i<=nostate;i++)
{
c=0;
for(j=0;j<20;j++)
{
buffer[j]=0;
e_closure[i][j]=0;
}
findclosure(i,i);
}
printf("Equivalent NFA without epsilon\n");
printf("-----------------------------------\n");
printf("start state:");
print_e_closure(start);
printf("\nAlphabets:");
for(i=0;i<noalpha;i++)
printf("%c ",alphabet[i]);
printf("\nStates :" );
for(i=1;i<=nostate;i++)
print_e_closure(i);
printf("\nTransitions are...:\n");
for(i=1;i<=nostate;i++)
9
{
for(j=0;j<noalpha-1;j++)
{
for(m=1;m<=nostate;m++)
set[m]=0;
for(k=0;e_closure[i][k]!=0;k++)
{
t=e_closure[i][k];
temp=transition[t][j];
while(temp!=NULL)
{
unionclosure(temp->st);
temp=temp->link;
}
}
printf("\n");
print_e_closure(i);
printf("%c\t",alphabet[j] );
printf("{");
for(n=1;n<=nostate;n++)
{
if(set[n]!=0)
printf("q%d,",n);
}
printf("}");
}
}
printf("\nFinal states:");
findfinalstate();
10
if(buffer[x])
return;
e_closure[sta][c++]=x;
buffer[x]=1;
if(alphabet[noalpha-1]=='e' && transition[x][noalpha-1]!=NULL)
{
temp=transition[x][noalpha-1];
while(temp!=NULL)
{
findclosure(temp->st,sta);
temp=temp->link;
}
}
}
int findalpha(char c)
{
int i;
for(i=0;i<noalpha;i++)
if(alphabet[i]==c)
return i;
return(999);
11
void unionclosure(int i)
{
int j=0,k;
while(e_closure[i][j]!=0)
{
k=e_closure[i][j];
set[k]=1;
j++;
}
}
void findfinalstate()
{
int i,j,k,t;
for(i=0;i<nofinal;i++)
{
for(j=1;j<=nostate;j++)
{
for(k=0;e_closure[j][k]!=0;k++)
{
if(e_closure[j][k]==finalstate[i])
{
print_e_closure(j);
}
}
}
}
void print_e_closure(int i)
{
int j=0;
printf("{");
if(e_closure[i][j]!=0)
printf("q%d,",e_closure[i][0]);
printf("}\t");
}
12
OUTPUT:
Enter alphabets?
a
b
e
Enter the number of states?
5
Enter the start state?
1
Enter the number of final states?
1
Enter the final states?
3
Enter no of transition?
7
NOTE:- [Transition is in the form--> qno alphabet qno]
NOTE:- [States number must be greater than zero]
Enter transition?
1a2
1e3
2a1
3b4
4b3
3a5
5b3
{q1,} a {q2,q5,}
{q1,} b {q4,}
13
{q2,} a {q1,q3,}
{q2,} b {}
{q3,} a {q5,}
{q3,} b {q4,}
{q4,} a {}
{q4,} b {q3,}
{q5,} a {}
{q5,} b {q3,}
Final states:{q1,} {q3,}
14
EXPERIMENT - 3
ALGORITHM:
PROGRAM:
#include<stdio.h>
#include<stdlib.h>
struct node
{
int st;
struct node *link;
15
};
struct node1
{
int nst[20];
};
16
printf("Enter the number of final states?\n");
scanf("%d",&nofinal);
printf("Enter the final states?\n");
for(i=0;i<nofinal;i++)
scanf("%d",&finalstate[i]);
printf("Enter no of transition?\n");
scanf("%d",¬ransition);
printf("NOTE:- [Transition is in the form–> qno alphabet qno]\n");
printf("NOTE:- [States number must be greater than zero]\n");
printf("\nEnter transition?\n");
for(i=0;i<notransition;i++)
{
scanf("%d %c %d",&r,&c,&s);
insert(r,c,s);
}
for(i=0;i<20;i++)
{
for(j=0;j<20;j++)
hash[i].nst[j]=0;
}
complete=-1;
i=-1;
printf("\nEquivalent DFA.....\n");
printf("Trnsitions of DFA\n");
newstate.nst[start]=start;
insertdfastate(newstate);
while(i!=complete)
{
i++;
newstate=hash[i];
for(k=0;k<noalpha;k++)
{
c=0;
for(j=1;j<=nostate;j++)
set[j]=0;
for(j=1;j<=nostate;j++)
{
l=newstate.nst[j];
if(l!=0)
17
{
temp=transition[l][k];
while(temp!=NULL)
{
if(set[temp->st]==0)
{
c++;
set[temp->st]=temp->st;
}
temp=temp->link;
}
}
}
printf("\n");
if(c!=0)
{
for(m=1;m<=nostate;m++)
tmpstate.nst[m]=set[m];
insertdfastate(tmpstate);
printnewstate(newstate);
printf("%c\t",alphabet[k]);
printnewstate(tmpstate);
printf("\n");
}
else
{
printnewstate(newstate);
printf("%c\t", alphabet[k]);
printf("NULL\n");
}
}
}
printf("\nStates of DFA:\n");
for(i=0;i<=complete;i++)
printnewstate(hash[i]);
printf("\n Alphabets:\n");
for(i=0;i<noalpha;i++)
printf("%c\t",alphabet[i]);
printf("\n Start State:\n");
18
printf("q%d",start);
printf("\nFinal states:\n");
findfinalstate();
}
int insertdfastate(struct node1 newstate)
{
int i;
for(i=0;i<=complete;i++)
{
if(compare(hash[i],newstate))
return 0;
}
complete++;
hash[complete]=newstate;
return 1;
}
int compare(struct node1 a,struct node1 b)
{
int i;
for(i=1;i<=nostate;i++)
{
if(a.nst[i]!=b.nst[i])
return 0;
}
return 1;
19
temp=(struct node *) malloc(sizeof(struct node));
temp->st=s;
temp->link=transition[r][j];
transition[r][j]=temp;
}
int findalpha(char c)
{
int i;
for(i=0;i<noalpha;i++)
if(alphabet[i]==c)
return i;
return(999);
void findfinalstate()
{
int i,j,k,t;
for(i=0;i<=complete;i++)
{
for(j=1;j<=nostate;j++)
{
for(k=0;k<nofinal;k++)
{
if(hash[i].nst[j]==finalstate[k])
{
printnewstate(hash[i]);
printf("\t");
j=nostate;
break;
}
}
}
}
}
20
{
int j;
printf("{");
for(j=1;j<=nostate;j++)
{
if(state.nst[j]!=0)
printf("q%d,",state.nst[j]);
}
printf("}\t");
OUTPUT:
Enter transition?
1a1
1b1
1a2
2b2
2a3
21
3a4
3b4
4b3
Equivalent DFA.....
Trnsitions of DFA
{q1,} a {q1,q2,}
{q1,} b {q1,}
{q1,q2,} a {q1,q2,q3,}
{q1,q2,} b {q1,q2,}
{q1,q2,q3,} a {q1,q2,q3,q4,}
{q1,q2,q3,} b {q1,q2,q4,}
{q1,q2,q3,q4,} a {q1,q2,q3,q4,}
{q1,q2,q3,q4,} b {q1,q2,q3,q4,}
{q1,q2,q4,} a {q1,q2,q3,}
{q1,q2,q4,} b {q1,q2,q3,}
States of DFA:
{q1,} {q1,q2,} {q1,q2,q3,} {q1,q2,q3,q4,} {q1,q2,q4,}
Alphabets:
a b
Start State:
q1
Final states:
{q1,q2,q3,} {q1,q2,q3,q4,} {q1,q2,q4,}
22
EXPERIMENT - 4
ALGORITHM:
PROGRAM:
#include <stdio.h>
#include <string.h>
#define STATES 99
#define SYMBOLS 20
23
int OptDFA[STATES][SYMBOLS];
char NEW_finals[STATES+1];
/*
Print state-transition table.
State names: 'A', 'B', 'C', ...
*/
void print_dfa_table(
int tab[][SYMBOLS], /* DFA table */
int nstates, /* number of states */
int nsymbols, /* number of input symbols */
char *finals)
{
int i, j;
printf("\n-----+--");
for (i = 0; i < nsymbols; i++) printf("-----");
printf("\n");
/*
Initialize NFA table.
*/
void load_DFA_table()
{
24
DFAtab[2][0] = 'A'; DFAtab[2][1] = 'A';
DFAtab[3][0] = 'F'; DFAtab[3][1] = 'E';
DFAtab[4][0] = 'D'; DFAtab[4][1] = 'F';
DFAtab[5][0] = 'D'; DFAtab[5][1] = 'E';
DFA_finals = "EF";
N_DFA_states = 6;
N_symbols = 2;
}
/*
Get next-state string for current-state string.
*/
void get_next_state(char *nextstates, char *cur_states,
int dfa[STATES][SYMBOLS], int symbol)
{
int i, ch;
/*
Get index of the equivalence states for state 'ch'.
Equiv. class id's are '0', '1', '2', ...
*/
char equiv_class_ndx(char ch, char stnt[][STATES+1], int n)
{
int i;
/*
Check if all the next states belongs to same equivalence class.
Return value:
If next state is NOT unique, return 0.
If next state is unique, return next state --> 'A/B/C/...'
's' is a '0/1' string: state-id's
25
*/
char is_one_nextstate(char *s)
{
char equiv_class; /* first equiv. class */
while (*s) {
if (*s != '@' && *s != equiv_class) return 0;
s++;
}
if (i=is_one_nextstate(state_flags))
return i-'0'; /* deterministic next states */
else {
strcpy(stnt[*pn], state_flags); /* state-division info */
return (*pn)++;
}
}
/*
Divide DFA states into finals and non-finals.
*/
26
int init_equiv_class(char statename[][STATES+1], int n, char *finals)
{
int i, j;
return 2;
}
/*
Get optimized DFA 'newdfa' for equiv. class 'stnt'.
*/
int get_optimized_DFA(char stnt[][STATES+1], int n,
int dfa[][SYMBOLS], int n_sym, int newdfa[][SYMBOLS])
{
int n2=n; /* 'n' + <num. of state-division info> */
int i, j;
char nextstate[STATES+1];
return n2;
}
/*
27
char 'ch' is appended at the end of 's'.
*/
void chr_append(char *s, char ch)
{
int n=strlen(s);
*(s+n) = ch;
*(s+n+1) = '\0';
}
/*
Divide first equivalent class into subclasses.
stnt[i1] : equiv. class to be segmented
stnt[i2] : equiv. vector for next state of stnt[i1]
Algorithm:
- stnt[i1] is splitted into 2 or more classes 's1/s2/...'
- old equiv. classes are NOT changed, except stnt[i1]
- stnt[i1]=s1, stnt[n]=s2, stnt[n+1]=s3, ...
Return value: number of NEW equiv. classses in 'stnt'.
*/
int split_equiv_class(char stnt[][STATES+1],
int i1, /* index of 'i1'-th equiv. class */
int i2, /* index of equiv. vector for 'i1'-th class */
int n, /* number of entries in 'stnt' */
int n_dfa) /* number of source DFA entries */
{
char *old=stnt[i1], *vec=stnt[i2];
int i, n2, flag=0;
28
char newstates[STATES][STATES+1]; /* max. 'n' subclasses */
/*
Equiv. classes are segmented and get NEW equiv. classes.
*/
int set_new_equiv_class(char stnt[][STATES+1], int n,
int newdfa[][SYMBOLS], int n_sym, int n_dfa)
{
int i, j, k;
return n;
}
29
{
int i;
/*
State-minimization of DFA: 'dfa' --> 'newdfa'
Return value: number of DFA states.
*/
int optimize_DFA(
int dfa[][SYMBOLS], /* DFA state-transition table */
int n_dfa, /* number of DFA states */
int n_sym, /* number of input symbols */
char *finals, /* final states of DFA */
char stnt[][STATES+1], /* state name table */
int newdfa[][SYMBOLS]) /* reduced DFA table */
{
char nextstate[STATES+1];
int n; /* number of new DFA states */
int n2; /* 'n' + <num. of state-dividing info> */
while (1) {
print_equiv_classes(stnt, n);
n2 = get_optimized_DFA(stnt, n, dfa, n_sym, newdfa);
if (n != n2)
n = set_new_equiv_class(stnt, n, newdfa, n_sym, n_dfa);
else break; /* equiv. class segmentation ended!!! */
}
/*
Check if 't' is a subset of 's'.
*/
int is_subset(char *s, char *t)
30
{
int i;
/*
New finals states of reduced DFA.
*/
void get_NEW_finals(
char *newfinals, /* new DFA finals */
char *oldfinals, /* source DFA finals */
char stnt[][STATES+1], /* state name table */
int n) /* number of states in 'stnt' */
{
int i;
void main()
{
load_DFA_table();
print_dfa_table(DFAtab, N_DFA_states, N_symbols, DFA_finals);
OUTPUT:
31
B | E F
C | A A
D | F E
E | D F
F | D E
Final states = EF
32
Introduction to Lex
Lex is a tool or a computer program that generates Lexical Analyzers (converts the
stream of characters into tokens). The Lex tool itself is a compiler. The Lex
compiler takes the input and transforms that input into input patterns. It is
commonly used with YACC(Yet Another Compiler Compiler).
{ definitions }
%%
{ rules }
%%
{ user subroutines }
33
Introduction to YACC
Each translation rule input to YACC has a string specification that resembles a
production of a grammar-it has a nonterminal on the LHS and a few alternatives on
the RHS. For simplicity, we will refer to a string specification as a production. YACC
generates an LALR(1) parser for language L from the productions, which is a
bottom-up parser. The parser would operate as follows: For a shift action, it would
invoke the scanner to obtain the next token and continue the parse by using that
token. While performing a reduced action in accordance with production, it would
perform the semantic action associated with that production.
34
EXPERIMENT - 5
AIM: To implement a lexical analyser for given language using C and lexical
analyser should ignore redundant spaces, tabs and newlines.
ALGORITHM:
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main()
{
char ch, buffer[15], buf[15], operators[] = "+-*/%=,;()";
FILE *fp;
int i, j = 0;
int ido = 0;
35
fp = fopen("inputfile.txt", "r");
if (fp == NULL)
{
printf("error while opening the file\n");
exit(0);
}
while ((ch = fgetc(fp)) != EOF)
{
for (i = 0; i < 10; i++)
{
if (ch == operators[i] && kwd(buffer) == 0)
printf("id ");
}
if (isalnum(ch))
{
buffer[j++] = ch;
}
36
else if ((ch == ' ' || ch == '\n') && (j != 0))
{
buffer[j] = '\0';
j = 0;
if (kwd(buffer) == 1)
printf("kwd ");
}
}
fclose(fp);
return 0;
}
int kwd(char buffer[])
{
char keywords[32][10] = {"auto", "break", "case", "char", "const", "continue",
"default",
"do", "double", "else", "enum", "extern", "float", "for", "goto",
"if", "int", "long", "register", "return", "short", "signed",
"sizeof", "static", "struct", "switch", "typedef", "union",
"unsigned", "void", "volatile", "while"};
int i, flag = 0;
// returns 1 if the buffer is a keyword
for (i = 0; i < 32; ++i)
{
if (strcmp(keywords[i], buffer) == 0)
{
flag = 1;
break;
}
}
return flag;
}
OUTPUT:
Input.txt
int a=b+c;
37
RESULT: Program to implement lexical analyser using C by ignoring redundant
spaces, tabs and newline was successfully implemented.
38
EXPERIMENT - 6
Lexical Program to recognize all strings which does not first four
characters of your name as substring
AIM: To implement a lexical program to recognize all strings which does not first
four characters of your name as substring.
ALGORITHM:
PROGRAM:
%{
#include<stdio.h>
#include<math.h>
FILE *file;
%}
%%
[a-zA-Z]*"nand"[a-zA-Z]* {}
[a-zA-Z]* {printf("%s\n",yytext);}
%%
int main()
{
file = fopen("input.txt", "r");
if (!file)
{
printf("could not open the file");
exit(0);
}
39
yyin = file;
yylex();
printf("\n");
return (0);
}
int yywrap()
{
return (1);
}
OUTPUT:
Input.txt
my name is nandini
lex pgm.l
gcc lex.yy.c
./a.out
my
name
is
RESULT: Lexical program to recognize all strings which does not first four
characters of your name as substring was successfully implemented.
40
EXPERIMENT - 7
AIM: To implement a YACC Program to recognize a valid variable which starts with
a letter followed by any number of letters or digits.
ALGORITHM:
PROGRAM:
Yacc program:
%{
#include<stdio.h>
#include<stdlib.h>
%}
%token LET DIG
%%
variable:var
;
var:var DIG
|var LET
|LET
;
%%
int main() {
printf("Enter the variable:\n");
yyparse();
printf("Valid variable\n");
return 0;
}
41
int yyerror()
{
printf("Invalid variable \n");
exit(0);
}
Lex Program:
%{
#include "y.tab.h"
%}
%%
[a-zA-Z] {return LET;}
[0-9] {return DIG;}
. {return yytext[0];}
\n {return 0;}
%%
int yywrap() {
return 1;
}
OUTPUT:
lex pgm.l
yacc -d pgm.y
gcc lex.yy.c y.tab.c
./a.out
RESULT: YACC Program to recognize a valid variable which starts with a letter
followed by any number of letters or digits was successfully implemented.
42
EXPERIMENT - 8
ALGORITHM:
PROGRAM:
Yacc Program
%{
#include<stdio.h>
int flag=0;
%}
%token NUMBER
%%
43
ArithmeticExpression: E{
printf("\nResult=%d\n",$$);
return 0;
};
E:E'+'E {$$=$1+$3;}
|E'-'E {$$=$1-$3;}
|E'*'E {$$=$1*$3;}
|E'/'E {$$=$1/$3;}
|E'%'E {$$=$1%$3;}
|'('E')' {$$=$2;}
| NUMBER {$$=$1;}
%%
void main()
yyparse();
if(flag==0)
44
}
void yyerror()
flag=1;
Lex Program
%{
#include<stdio.h>
#include "y.tab.h"
%}
%%
[0-9]+ {
yylval=atoi(yytext);
return NUMBER;
[\t] ;
[\n] return 0;
. return yytext[0];
45
%%
int yywrap()
return 1;
OUTPUT:
lex pgm.l
yacc -d pgm.y
gcc lex.yy.c y.tab.c -w
./a.out
Enter Any Arithmetic Expression which can have operations Addition, Subtraction,
Multiplication, Divison, Modulus and Round brackets:
((5+6+10+4+5)/5)%2
Result=0
Enter Any Arithmetic Expression which can have operations Addition, Subtraction,
Multiplication, Divison, Modulus and Round brackets:
(9=0)
RESULT: Implementation of calculator using lex and yacc was successfully done.
46
EXPERIMENT - 9
AIM: To convert BNF rules into YACC form and write code to generate abstract
syntax tree.
ALGORITHM:
PROGRAM:
Yacc Program
%{
#include<string.h>
#include<stdio.h>
struct quad
{
char op[5];
char arg1[10];
char arg2[10];
char result[10];
}QUAD[30];
struct stack
{
int items[100];
int top;
}stk;
int Index=0,tIndex=0,StNo,Ind,tInd;
extern int LineNo;
%}
47
%union
{
char var[10];
}
%token <var> NUM VAR RELOP
%token MAIN IF ELSE WHILE TYPE
%type <var> EXPR ASSIGNMENT CONDITION IFST ELSEST WHILELOOP
%left '-' '+'
%left '*' '/'
%%
PROGRAM : MAIN BLOCK
;
BLOCK: '{' CODE '}'
;
CODE: BLOCK
| STATEMENT CODE
| STATEMENT
;
STATEMENT: DESCT ';'
| ASSIGNMENT ';'
| CONDST
| WHILEST
;
DESCT: TYPE VARLIST
;
VARLIST: VAR ',' VARLIST
| VAR
;
ASSIGNMENT: VAR '=' EXPR{
strcpy(QUAD[Index].op,"=");
strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,$1);
strcpy($$,QUAD[Index++].result);
}
;
EXPR: EXPR '+' EXPR {AddQuadruple("+",$1,$3,$$);}
| EXPR '-' EXPR {AddQuadruple("-",$1,$3,$$);}
| EXPR '*' EXPR {AddQuadruple("*",$1,$3,$$);}
| EXPR '/' EXPR {AddQuadruple("/",$1,$3,$$);}
| '-' EXPR {AddQuadruple("UMIN",$2,"",$$);}
| '(' EXPR ')' {strcpy($$,$2);}
48
| VAR
| NUM
;
CONDST: IFST{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}
| IFST ELSEST
;
IFST: IF '(' CONDITION ')' {
strcpy(QUAD[Index].op,"==");
strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"FALSE");
strcpy(QUAD[Index].result,"-1");
push(Index);
Index++;
}
BLOCK {
strcpy(QUAD[Index].op,"GOTO");
strcpy(QUAD[Index].arg1,"");
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,"-1");
push(Index);
Index++;
};
ELSEST: ELSE{
tInd=pop();
Ind=pop();
push(tInd);
sprintf(QUAD[Ind].result,"%d",Index);
}
BLOCK{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
};
CONDITION: VAR RELOP VAR {AddQuadruple($2,$1,$3,$$);
StNo=Index-1;
}
| VAR
| NUM
49
;
WHILEST: WHILELOOP{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",StNo);
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}
;
WHILELOOP: WHILE '(' CONDITION ')' {
strcpy(QUAD[Index].op,"==");
strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"FALSE");
strcpy(QUAD[Index].result,"-1");
push(Index);
Index++;
}
BLOCK {
strcpy(QUAD[Index].op,"GOTO");
strcpy(QUAD[Index].arg1,"");
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,"-1");
push(Index);
Index++;
}
;
%%
extern FILE *yyin;
int main(int argc,char *argv[])
{
FILE *fp;
int i;
if(argc>1)
{
fp=fopen(argv[1],"r");
if(!fp)
{
printf("\n File not found");
exit(0);
}
yyin=fp;
}
yyparse();
50
printf("\n\n\t\t -----------------------------------""\n\t\t Pos Operator Arg1 Arg2
Result" "\n\t\t -----------------------------------");
for(i=0;i<Index;i++)
{
printf("\n\t\t %d\t %s\t %s\t
%s\t%s",i,QUAD[i].op,QUAD[i].arg1,QUAD[i].arg2,QUAD[i].result);
}
printf("\n\t\t -----------------------------------");
printf("\n\n");
return 0;
}
void push(int data)
{
stk.top++;
if(stk.top==100)
{
printf("\n Stack overflow\n");
exit(0);
}
stk.items[stk.top]=data;
}
int pop()
{
int data;
if(stk.top==-1)
{
printf("\n Stack underflow\n");
exit(0);
}
data=stk.items[stk.top--];
return data;
}
void AddQuadruple(char op[5],char arg1[10],char arg2[10],char result[10])
{
strcpy(QUAD[Index].op,op);
strcpy(QUAD[Index].arg1,arg1);
strcpy(QUAD[Index].arg2,arg2);
sprintf(QUAD[Index].result,"t%d",tIndex++);
strcpy(result,QUAD[Index++].result);
}
yyerror()
{
51
printf("\n Error on line no:%d",LineNo);
}
Lex Program
%{
#include"y.tab.h"
#include<stdio.h>
#include<string.h>
int LineNo=1;
%}
identifier [a-zA-Z][_a-zA-Z0-9]*
number [0-9]+|([0-9]*\.[0-9]+)
%%
main\(\) return MAIN;
if return IF;
else return ELSE;
while return WHILE;
int |
char |
float return TYPE;
{identifier} {strcpy(yylval.var,yytext);
return VAR;}
{number} {strcpy(yylval.var,yytext);
return NUM;}
\< |
\> |
\>= |
\<= |
== {strcpy(yylval.var,yytext);
return RELOP;}
[ \t] ;
\n LineNo++;
. return yytext[0];
%%
int yywrap()
{
return 1;
}
52
OUTPUT:
lex pgm.l
yacc -d pgm.y
gcc lex.yy.c y.tab.c -w
./a.out
main(){
int a,b,c;
if(a<b)
{
a=a+b;
}
while(a<b)
{
a=a+b;
}
if(a<=b)
{
c=a-b;
}
else
{
c=a+b;
}
}
-----------------------------------
Pos Operator Arg1 Arg2 Result
-----------------------------------
0 < a b t0
1 == t0 FALSE 5
2 + a b t1
3 = t1 a
4 GOTO 5
5 < a b t2
6 == t2 FALSE 10
7 + a b t3
8 = t3 a
9 GOTO 5
10 <= a b t4
11 == t4 FALSE 15
53
12 - a b t5
13 = t5 c
14 GOTO 17
15 + a b t6
16 = t6 c
-----------------------------------
RESULT: Conversion of BNF rules into Yacc form to generate abstract syntax tree
was successfully implemented.
54
EXPERIMENT - 10
AIM: To convert BNF rules into YACC form and write code to generate abstract
syntax tree.
ALGORITHM:
PROGRAM:
Yacc Program
%{
#include<stdio.h>
int valid=1;
%}
%token FOR LPAREN TYPE ID EQ NUMBER COMMA COMP RPAREN UPD
%%
FORSTMT:FOR LPAREN TYPE ID EQ NUMBER COMMA ID COMP NUMBER COMMA
ID UPD RPAREN
%%
int yyerror()
{
printf("Not Valid For Syntax");
valid=0;
return 0;
}
int main()
{
yyparse();
if(valid)
{
55
printf("Valid Syntax");
}
return 0;
}
Lex Program
%{
#include<stdio.h>
#include "y.tab.h"
%}
%%
for {return FOR;}
[(] {return LPAREN;}
int|double|float {return TYPE;}
[a-zA-Z_][a-zA-Z0-9_]* {return ID;}
[=] {return EQ;}
[0-9]+ {return NUMBER;}
[;] {return COMMA;}
[<>] {return COMP;}
[<>][=] {return COMP;}
[)] {return RPAREN;}
[+][+] {return UPD;}
[-][-] {return UPD;}
[ ] {}
[\n] {return 0;}
%%
int yywrap()
{
return 1;
}
OUTPUT:
lex pgm.l
yacc -d pgm.y
gcc lex.yy.c y.tab.c -w
./a.out
for(int i=0;i<10;i++)
Valid Syntax
for(int =0
56
Not Valid For Syntax
RESULT: Yacc program to check the syntax of for statement in C was successfully
implemented.
57
EXPERIMENT - 11
ALGORITHM:
PROGRAM:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char *input;
int i=0;
char lasthandle[6],stack[50],handles[][5]={")E(","E*E","E+E","i","E^E"};
int top=0,l;
58
char prec[9][9]={
/*input*/
/*stack + - * / ^ i ( ) $ */
/* + */ '>', '>','<','<','<','<','<','>','>',
/* - */ '>', '>','<','<','<','<','<','>','>',
/* * */ '>', '>','>','>','<','<','<','>','>',
/* / */ '>', '>','>','>','<','<','<','>','>',
/* ^ */ '>', '>','>','>','<','<','<','>','>',
/* i */ '>', '>','>','>','>','e','e','>','>',
/* ( */ '<', '<','<','<','<','<','<','>','e',
/* ) */ '>', '>','>','>','>','e','e','>','>',
/* $ */ '<', '<','<','<','<','<','<','<','>',
};
int getindex(char c)
{
switch(c)
{
case '+':return 0;
case '-':return 1;
case '*':return 2;
case '/':return 3;
case '^':return 4;
case 'i':return 5;
case '(':return 6;
case ')':return 7;
case '$':return 8;
}
}
59
int shift()
{
stack[++top]=*(input+i++);
stack[top+1]='\0';
}
int reduce()
{
int i,len,found,t;
for(i=0;i<5;i++)//selecting handles
{
len=strlen(handles[i]);
if(stack[top]==handles[i][0]&&top+1>=len)
{
found=1;
for(t=0;t<len;t++)
{
if(stack[top-t]!=handles[i][t])
{
found=0;
break;
}
}
if(found==1)
{
stack[top-t+1]='E';
top=top-t+1;
strcpy(lasthandle,handles[i]);
stack[top+1]='\0';
return 1;//successful reduction
}
}
}
return 0;
}
void dispstack()
{
60
int j;
for(j=0;j<=top;j++)
printf("%c",stack[j]);
}
void dispinput()
{
int j;
for(j=i;j<l;j++)
printf("%c",*(input+j));
}
void main()
{
int j;
input=(char*)malloc(50*sizeof(char));
printf("\nEnter the string\n");
scanf("%s",input);
input=strcat(input,"$");
l=strlen(input);
strcpy(stack,"$");
printf("\nSTACK\tINPUT\tACTION");
while(i<=l)
{
shift();
printf("\n");
dispstack();
printf("\t");
dispinput();
printf("\tShift");
if(prec[getindex(stack[top])][getindex(input[i])]=='>')
{
while(reduce())
{
printf("\n");
dispstack();
printf("\t");
61
dispinput();
printf("\tReduced: E->%s",lasthandle);
}
}
}
if(strcmp(stack,"$E$")==0)
printf("\nAccepted;");
else
printf("\nNot Accepted;");
}
OUTPUT:
62
EXPERIMENT - 12
AIM: To develop a program to simulate first and follow of any given grammar.
ALGORITHM:
First():-
Follow():-
PROGRAM:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int count, n = 0;
63
// Stores the final result
// of the First Sets
char calc_first[10][100];
int kay;
char done[count];
int ptr = -1;
64
}
}
int point1 = 0, point2, xxx;
if (xxx == 1)
continue;
// Function call
findfirst(c, 0, 0);
ptr += 1;
if (first[i] == calc_first[point1][lark]) {
chk = 1;
break;
}
}
if (chk == 0) {
printf("%c, ", first[i]);
calc_first[point1][point2++] = first[i];
}
65
}
printf("}\n");
jm = n;
point1++;
}
printf("\n");
printf("-----------------------------------------------"
"\n\n");
char donee[count];
ptr = -1;
// Checking if Follow of ck
// has already been calculated
for (kay = 0; kay <= ptr; kay++)
if (ck == donee[kay])
xxx = 1;
if (xxx == 1)
continue;
land += 1;
// Function call
follow(ck);
ptr += 1;
66
// Printing the Follow Sets of the grammar
for (i = 0 + km; i < m; i++) {
int lark = 0, chk = 0;
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++;
}
}
void follow(char c)
{
int i, j;
if (production[i][j + 1] == '\0'
&& c != production[i][0]) {
67
// Calculate the follow of the
// Non-Terminal in the L.H.S. of the
// production
follow(production[i][0]);
}
}
}
}
}
68
findfirst(production[j][2], j, 3);
}
}
}
}
69
}
}
}
OUTPUT:
First(X) = { q, n, o, p, #, }
First(T) = { q, #, }
First(S) = { p, #, }
First(R) = { o, p, q, #, }
-----------------------------------------------
Follow(X) = { $, }
Follow(T) = { n, m, }
Follow(S) = { $, q, m, }
Follow(R) = { m, }
70
EXPERIMENT - 13
ALGORITHM:
PROGRAM:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SUCCESS 1
#define FAILED 0
int main()
{
//puts("Enter the string");
// scanf("%s", string);
sscanf("i+(i+i)*i", "%s", string);
71
cursor = string;
puts("");
puts("Input Action");
puts("--------------------------------");
int E()
{
printf("%-16s E -> T E'\n", cursor);
if (T()) {
if (Edash())
return SUCCESS;
else
return FAILED;
} else
return FAILED;
}
int Edash()
{
if (*cursor == '+') {
printf("%-16s E' -> + T E'\n", cursor);
cursor++;
if (T()) {
if (Edash())
return SUCCESS;
else
return FAILED;
} else
return FAILED;
} else {
printf("%-16s E' -> $\n", cursor);
72
return SUCCESS;
}
}
int T()
{
printf("%-16s T -> F T'\n", cursor);
if (F()) {
if (Tdash())
return SUCCESS;
else
return FAILED;
} else
return FAILED;
}
int Tdash()
{
if (*cursor == '*') {
printf("%-16s T' -> * F T'\n", cursor);
cursor++;
if (F()) {
if (Tdash())
return SUCCESS;
else
return FAILED;
} else
return FAILED;
} else {
printf("%-16s T' -> $\n", cursor);
return SUCCESS;
}
}
int F()
{
if (*cursor == '(') {
printf("%-16s F -> ( E )\n", cursor);
cursor++;
if (E()) {
if (*cursor == ')') {
cursor++;
73
return SUCCESS;
} else
return FAILED;
} else
return FAILED;
} else if (*cursor == 'i') {
cursor++;
printf("%-16s F ->i\n", cursor);
return SUCCESS;
} else
return FAILED;
}
OUTPUT:
Input Action
--------------------------------
i+(i+i)*i E -> T E'
i+(i+i)*i T -> F T'
+(i+i)*i F ->i
+(i+i)*i T' -> $
+(i+i)*i E' -> + T E'
(i+i)*i T -> F T'
(i+i)*i F -> ( E )
i+i)*i E -> T E'
i+i)*i T -> F T'
+i)*i F ->i
+i)*i T' -> $
+i)*i E' -> + T E'
i)*i T -> F T'
)*i F ->i
)*i T' -> $
)*i E' -> $
*i T' -> * F T'
F ->i
T' -> $
E' -> $
--------------------------------
String is successfully parsed
74
EXPERIMENT - 14
ALGORITHM:
PROGRAM:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char ip_sym[15],stack[15];
int ip_ptr=0,st_ptr=0,len,i;
char temp[2],temp2[2];
char act[15];
void check();
void main()
{
printf("\n\t\t SHIFT REDUCE PARSER\n");
printf("\n GRAMMER\n");
printf("\n E->E+E\n E->E/E");
printf("\n E->E*E\n E->a/b");
printf("\n enter the input symbol:\t");
75
gets(ip_sym);
printf("\n\t stack implementation table");
printf("\n stack \t\t input symbol\t\t action");
printf("\n________\t\t____________\t\t____________\n");
printf("\n $\t\t%s$\t\t\t--",ip_sym);
strcpy(act,"shift");
temp[0]=ip_sym[ip_ptr];
temp[1]='\0';
strcat(act,temp);
len=strlen(ip_sym);
for(i=0;i<=len-1;i++)
{
stack[st_ptr]=ip_sym[ip_ptr];
stack[st_ptr+1]='\0';
ip_sym[ip_ptr]=' ';
ip_ptr++;
printf("\n $%s\t\t%s$\t\t\t%s",stack,ip_sym,act);
strcpy(act,"shift");
temp[0]=ip_sym[ip_ptr];
temp[1]='\0';
strcat(act,temp);
check();
st_ptr++;
}
st_ptr++;
check();
}
void check()
{
int flag=0;
temp2[0]=stack[st_ptr];
temp2[1]='\0';
if((!strcmp(temp2,"a"))||(!strcmp(temp2,"b")))
{
stack[st_ptr]='E';
if(!strcmp(temp2,"a"))
printf("\n $%s\t\t%s$\t\t\tE->a",stack,ip_sym);
else
printf("\n $%s\t\t%s$\t\t\tE->b",stack,ip_sym);
flag=1;
}
if((!strcmp(temp2,"+"))||(strcmp(temp2,"*"))||(!strcmp(temp2,"/"))) { flag=1;
76
}
if((!strcmp(stack,"E+E"))||(!strcmp(stack,"E\E"))||(!strcmp(stack,"E*E")))
{
strcpy(stack,"E");
st_ptr=0;
if(!strcmp(stack,"E+E"))
printf("\n $%s\t\t%s$\t\t\tE->E+E",stack,ip_sym);
else
if(!strcmp(stack,"E\E"))
printf("\n $%s\t\t%s$\t\t\tE->E\E",stack,ip_sym);
else if(!strcmp(stack,"E*E"))
printf("\n $%s\t\t%s$\t\t\tE->E*E",stack,ip_sym);
else
printf("\n $%s\t\t%s$\t\t\tE->E+E",stack,ip_sym);
flag=1;
}
if(!strcmp(stack,"E")&&ip_ptr==len)
{
printf("\n $%s\t\t%s$\t\t\tACCEPT",stack,ip_sym);
exit(0);
}
if(flag==0)
{
printf("\n%s\t\t\t%s\t\t reject",stack,ip_sym);
exit(0);
}
return;
}
OUTPUT:
GRAMMER
E->E+E
E->E/E
E->E*E
E->a/b
enter the input symbol: a+b
77
________ ____________ ____________
$ a+b$ --
$a +b$ shifta
$E +b$ E->a
$E+ b$ shift+
$E+b $ shiftb
$E+E $ E->b
$E $ E->E+E
$E $ ACCEPT
RESULT: Program to construct shift reduce parser for a given language was
successfully implemented.
78
EXPERIMENT – 15
ALGORITHM:
PROGRAM:
#include<stdio.h>
#include<string.h>
char op[2],arg1[5],arg2[5],result[5];
void main()
{
FILE *fp1,*fp2;
fp1=fopen("input.txt","r");
79
fp2=fopen("output.txt","w");
while(!feof(fp1))
{
fscanf(fp1,"%s%s%s%s",op,arg1,arg2,result);
if(strcmp(op,"+")==0)
{
fprintf(fp2,"\nMOV R0,%s",arg1);
fprintf(fp2,"\nADD R0,%s",arg2);
fprintf(fp2,"\nMOV %s,R0",result);
}
if(strcmp(op,"*")==0)
{
fprintf(fp2,"\nMOV R0,%s",arg1);
fprintf(fp2,"\nMUL R0,%s",arg2);
fprintf(fp2,"\nMOV %s,R0",result);
}
if(strcmp(op,"-")==0)
{
fprintf(fp2,"\nMOV R0,%s",arg1);
fprintf(fp2,"\nSUB R0,%s",arg2);
fprintf(fp2,"\nMOV %s,R0",result);
}
if(strcmp(op,"/")==0)
{
fprintf(fp2,"\nMOV R0,%s",arg1);
fprintf(fp2,"\nDIV R0,%s",arg2);
fprintf(fp2,"\nMOV %s,R0",result);
}
if(strcmp(op,"=")==0)
{
fprintf(fp2,"\nMOV R0,%s",arg1);
fprintf(fp2,"\nMOV %s,R0",result);
}
}
fclose(fp1);
fclose(fp2);
80
OUTPUT:
MOV R0,a
ADD R0,b
MOV t1,R0
MOV R0,c
MUL R0,d
MOV t2,R0
MOV R0,t1
SUB R0,t2
MOV t,R0
MOV R0,t
MOV x,R0
MOV R0,t
MOV x,R0
81
EXPERIMENT – 16
AIM: To implement the back end of the compiler which takes the three address
code and produces the 8086 assembly language instructions that can be
assembled and run using an 8086 assembler. The target assembly instructions can
be simple move, add, sub, jump etc.
ALGORITHM:
PROGRAM:
#include<stdio.h>
#include<string.h>
void main(){
char icode[10][30], str[20], opr[10];
int i=0;
printf("\nEnter the set of intermediate code (terminated by exit):\n");
do{
scanf("%s", icode[i]);
}
while(strcmp(icode[i++],"exit")!=0);
printf("\nTarget code generation");
printf("\n*******************");
i=0;
do{
strcpy(str,icode[i]);
switch(str[3]){
case '+':
strcpy(opr,"ADD");
break;
case '-':
strcpy(opr,"SUB");
82
break;
case '*':
strcpy(opr,"MUL");
break;
case '/':
strcpy(opr,"DIV");
break;
OUTPUT:
83
0,,R5
Mov R5t
RESULT: Program to implement the back end of the compiler which takes the
three address code and produces the 8086 assembly language instructions was
successfully done.
84