Compiler Design
Compiler Design
ALBY THEKKEDAN
. .....................................................................................................................................
3
Implement a C program to convert NFA to 17
22/08/23 DFA
4
Implement a C program to minimize any given 27
22/09/23 DFA
Implement a lexical analyzer for given
5
22/09/23 language using C and the lexical analyzer
39
should ignore redundant spaces, tabs and
newlines
8
Implementation of calculator using lex and yacc 47
10/10/23
9
Convert BNF rules into YACC form and write 51
10/10/23 code to generate abstract syntax tree
13
Construct a recursive descent parser for an 77
14/11/23 expression
14
Construct a shift reduce parser for a given 81
14/11/23 language
3
PROGRAM: /*Program to find ԑ closure of NFA*/
#include<stdio.h>
#include<string.h>
char result[20][20],copy[3],states[20][20];
void add_state(char a[3],int i){
strcpy(result[i],a);
}
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]);
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);
}
4
EXPERIMENT - 1
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
5
}
}
display(i);
rewind(INPUT);
}
return 0;
}
OUTPUT:
6
RESULT: Program to find the epsilon closure of all states of an epsilon
NFA was successfully implemented
7
PROGRAM: /*Program to convert ԑ-NFA to NFA*/
#include<stdio.h>
#include<stdlib.h>
struct node
{
int st;
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;
struct node *temp;
printf("enter the number of alphabets?\n");
scanf("%d",&noalpha);
getchar();
printf("NOTE:- [ use letter e as epsilon]\n");
printf("NOTE:- [e must be last character ,if it is present]\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++)
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");
8
EXPERIMENT - 2
ALGORITHM:
9
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++)
{
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)
10
11
printf("q%d,",n);
}
printf("}");
}
}
printf("\nFinal states:");
findfinalstate();
}
void findclosure(int x,int sta)
{
struct node *temp;
int i;
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;
}
}
}
void insert_trantbl(int r,char c,int s)
{
int j;
struct node *temp;
j=findalpha(c);
if(j==999)
{
printf("error\n");
exit(0);
}
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);}
12
13
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");
}
OUTPUT:
14
RESULT: Program to convert ԑ-NFA to NFA was successfully
implemented.
15
PROGRAM: /*Program to convert NFA to DFA*/
#include<stdio.h>
#include<stdlib.h>
struct node
{
int st;
struct node *link;
};
struct node1
{
int nst[20];
};
void insert(int ,char, int);
int findalpha(char);
void findfinalstate(void);
int insertdfastate(struct node1);
int compare(struct node1,struct node1);
void printnewstate(struct node1);
static int set[20],nostate,noalpha,s,notransition,nofinal,start,finalstate[20],r,buffer[20];
static char c;
int complete=-1;
char alphabet[20];
static int eclosure[20][20]={0};
struct node1 hash[20];
struct node * transition[20][20]={NULL};
void main()
{
int i,j,k,m,t,n,l;
struct node *temp;
struct node1 newstate={0},tmpstate={0};
printf("Enter the number of alphabets?\n");
printf("NOTE:- [ use letter e as epsilon]\n");
printf("NOTE:- [e must be last character ,if it is present]\n");
printf("\nEnter No of alphabets and alphabets?\n");
scanf("%d",&noalpha);
getchar();
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++)
16
EXPERIMENT - 3
ALGORITHM:
17
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)
{
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)
18
19
{
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");
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;
20
21
}
void insert(int r,char c,int s)
{
int j;
struct node *temp;
j=findalpha(c);
if(j==999)
{
printf("error\n");
exit(0);
}
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;
}
}
}
}
}
void printnewstate(struct node1 state)
{
int j;
printf("{");
for(j=1;j<=nostate;j++)
{
22
23
if(state.nst[j]!=0)
printf("q%d,",state.nst[j]);
}
printf("}\t");
}
OUTPUT:
24
RESULT: Program to convert NFA to DFA was successfully implemented.
25
PROGRAM: /*Program to minimize any DFA*/
#include <stdio.h>
#include <stdlib.h>
static int nostate, noalpha, s, notransition, nofinal, start, finalstate[20], r;
char alphabet[20];
int transition_map[30][30], table[30][30], nonfinalstate[20], partition[20][20];
int findalpha(char a)
{
int i;
for (i = 0; i < noalpha; i++)
if (alphabet[i] == a)
return i;
return (-1);
}
int main()
{
int i, j, p[20], q[20], k;
char a;
for (i = 0; i < 30; i++)
{
for (j = 0; j < 30; j++)
transition_map[i][j] = -1;
}
printf("Enter the number of alphabets: ");
scanf("%d", &noalpha);
getchar();
printf("Enter the alphabets: ");
for (i = 0; i < noalpha; i++)
{
alphabet[i] = getchar();
getchar();
}
printf("Enter the number of states: ");
scanf("%d", &nostate);
printf("Enter the start state: ");
scanf("%d", &start);
printf("Enter the number of final states: ");
scanf("%d", &nofinal);
printf("Enter the final state(s): ");
for (i = 0; i < nofinal; i++)
scanf("%d", &finalstate[i]);
printf("Enter no of transition: ");
scanf("%d", ¬ransition);
printf("Enter Transition in the form –> state alphabet next_state\n");
for (i = 0; i < notransition; i++)
{
scanf("%d %c %d", &r, &a, &s);
j = findalpha(a);
if (j == -1)
26
EXPERIMENT - 4
ALGORITHM:
27
{
printf("\nerror\n");
exit(1);
}
transition_map[r][j] = s;
}
for (i = 0; i < nostate; i++)
{
for (j = 0; j < i; j++)
{
table[i][j] = 0;
}
}
int f = 0;
k = 0;
for (i = 0; i < nostate; i++)
{
f = 0;
for (j = 0; j < nofinal; j++)
{
if (i == finalstate[j])
{
f = 1;
break;
}
}
if (f == 0)
{
nonfinalstate[k++] = i;
}
}
for (i = 0; i < nofinal; i++)
{
for (j = 0; j < (nostate - nofinal); j++)
if (nonfinalstate[j] > finalstate[i])
table[nonfinalstate[j]][finalstate[i]] = 1;
else
table[finalstate[i]][nonfinalstate[j]] = 1;
}
int change = 1;
while (change == 1)
{
change = 0;
for (i = 0; i < nostate; i++)
{
for (j = 0; j < i; j++)
{
if (table[i][j] != 1)
{
for (k = 0; k < noalpha; k++)
28
29
p[k] = transition_map[i][k];
for (k = 0; k < noalpha; k++)
q[k] = transition_map[j][k];
for (k = 0; k < noalpha; k++)
{
if (p[k] > q[k])
{
if (table[p[k]][q[k]] == 1)
{
change = 1;
table[i][j] = 1;
break;
}
}
else if (p[k] < q[k])
{
if (table[q[k]][p[k]] == 1)
{
change = 1;
table[i][j] = 1;
break;
}
}
}
}
}
}
}
k = 0;
for (i = 0; i < nostate; i++)
{
k = 0;
partition[i][k++] = i;
for (j = 0; j < i; j++)
if (table[i][j] == 0)
{
partition[i][k++] = j;
}
partition[i][k] = -1;
}
int newstate[20] = {0}, m;
printf("\nStates in minimized DFA");
printf("\n----------------------------\n");
for (i = nostate - 1; i >= 0; i--)
{
k = 0;
if (newstate[i] == 0)
{
printf("{");
30
31
while (partition[i][k] != -1)
{
if (newstate[partition[i][k]] == 0)
{
newstate[partition[i][k]] = 1;
printf("q%d ", partition[i][k]);
}
k++;
}
printf("}\n");
}
}
return 0;
}
OUTPUT:
32
RESULT: Program to minimise DFA was successfully implemented.
33
34
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 }
35
36
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.
37
PROGRAM: /*Program to implement lexical analyser*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int kwd(char buffer[]);
int main()
{
char ch, buffer[15], buf[15], operators[] = "+-*/%=,;()";
FILE *fp;
int i, j = 0;
int ido = 0;
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 ");
}
for (i = 0; i < 10; ++i)
{
if (ch == operators[i])
if (operators[i] == '+')
printf("op-plus ");
else if (operators[i] == '-')
printf("op-sub ");
else if (operators[i] == '*')
printf("op-mul ");
else if (operators[i] == '/')
printf("op-div ");
else if (operators[i] == '%')
printf("op-mod ");
else if (operators[i] == '=')
printf("op-equ ");
else if (operators[i] == ';')
printf(";");
else if (operators[i] == ',')
printf(",");
else if (operators[i] == '(')
printf(".");
}
if (isalnum(ch))
{
38
EXPERIMENT - 5
AIM: To implement a lexical analyser for given language using C and lexical
analyser should ignore redundant spaces, tabs and newlines.
ALGORITHM:
39
buffer[j++] = ch;
}
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:
Inputfile.txt
40
RESULT: Program to implement lexical analyser using C by ignoring redundant
spaces, tabs and newline was successfully implemented.
41
PROGRAM: /* Lexical Program to recognize all strings which does not first four characters of
your name as substring*/
%{
#include<stdio.h>
#include<math.h>
FILE *file;
%}
%%
[a-zA-Z]*"alby"[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);
}
yyin = file;
yylex();
printf("\n");
return (0);
}
int yywrap()
{
return (1);
}
OUTPUT:
42
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:
RESULT: Lexical program to recognize all strings which does not first four
characters of your name as substring was successfully implemented.
43
PROGRAM: /*Yacc program to recognize valid variable*/
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;
}
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:
44
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:
RESULT: YACC Program to recognize a valid variable which starts with a letter
followed by any number of letters or digits was successfully implemented.
45
PROGRAM: /*Calculator using lex and yacc*/
Yacc Program
%{
#include<stdio.h>
int flag=0;
%}
%token NUMBER
%left '+' '-'
%left '*' '/' '%'
%left '(' ')'
%%
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()
{
printf("\nEnter Any Arithmetic Expression which can have operations Addition, Subtraction,
Multiplication, Divison, Modulus and Round brackets:\n");
yyparse();
if(flag==0)
printf("\nEntered arithmetic expression is Valid\n\n");
}
void yyerror()
{
printf("\nEntered arithmetic expression is Invalid\n\n");
flag=1;
}
Lex Program
%{
#include<stdio.h>
#include "y.tab.h"
extern int yylval;
%}
%%
[0-9]+ {
yylval=atoi(yytext);
return NUMBER;
}
[\t] ;
46
EXPERIMENT - 8
ALGORITHM:
47
[\n] return 0;
. return yytext[0];
%%
int yywrap()
{
return 1;
}
OUTPUT:
48
RESULT: Implementation of calculator using lex and yacc was successfully done.
49
PROGRAM: /*Yacc program to convert BNF to abstract syntax tree*/
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;
%}
%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{
50
EXPERIMENT - 9
AIM: To convert BNF rules into YACC form and write code to generate abstract
syntax tree.
ALGORITHM:
51
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);}
| 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);
};
52
53
CONDITION: VAR RELOP VAR {AddQuadruple($2,$1,$3,$$);
StNo=Index-1;
}
| VAR
| NUM
;
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();
printf("\n\n\t\t -----------------------------------""\n\t\t Pos Operator Arg1 Arg2 Result" "\n\t\t ----
-------------------------------");
for(i=0;i<Index;i++)
54
55
{
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()
{
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]*
56
57
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;
}
OUTPUT:
Input.c
58
RESULT: Conversion of BNF rules into Yacc form to generate abstract syntax tree
was successfully implemented.
59
PROGRAM: /*Yacc program to check syntax of FOR statement*/
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)
{
printf("Valid Syntax");
}
return 0;
}
60
EXPERIMENT - 10
AIM: To convert BNF rules into YACC form and write code to generate abstract
syntax tree.
ALGORITHM:
61
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:
62
RESULT: Yacc program to check the syntax of for statement in C was successfully
implemented.
63
PROGRAM: /*Operator precedence parser*/
#include<stdio.h>
#include<string.h>
void main(){
char stack[20],ip[20],opt[10][10][1],ter[10];
int i,j,k,n,top=0,col,row;
for(i=0;i<10;i++)
{
stack[i]=0;
ip[i]=0;
for(j=0;j<10;j++)
{
opt[i][j][1]=0;
}
}
printf("Enter the no.of terminals :\n");
scanf("%d",&n);
printf("\nEnter the terminals :\n");
scanf("%s",ter);
printf("\nEnter the table values :\n");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("Enter the value for %c %c:",ter[i],ter[j]);
scanf("%s",opt[i][j]);
}
}
printf("\n**** OPERATOR PRECEDENCE TABLE ****\n");
for(i=0;i<n;i++)
{
printf("\t%c",ter[i]);}
printf("\n");
for(i=0;i<n;i++){printf("\n%c",ter[i]);
for(j=0;j<n;j++){printf("\t%c",opt[i][j][0]);}}
stack[top]='$';
printf("\nEnter the input string:");
scanf("%s",ip);
i=0;
printf("\nSTACK\t\t\tINPUT STRING\t\t\tACTION\n");
printf("\n%s\t\t\t%s\t\t\t",stack,ip);
while(i<=strlen(ip))
{
for(k=0;k<n;k++)
{
if(stack[top]==ter[k])
col=k;
if(ip[i]==ter[k])
64
EXPERIMENT - 11
ALGORITHM:
65
row=k;}
if((stack[top]=='$')&&(ip[i]=='$')){
printf("String is accepted\n");
break;}
else if((opt[col][row][0]=='<') ||(opt[col][row][0]=='='))
{ stack[++top]=opt[col][row][0];
stack[++top]=ip[i];
printf("Shift %c",ip[i]);
i++;}
else{
if(opt[col][row][0]=='>')
{
while(stack[top]!='<'){--top;}
top=top-1;
printf("Reduce");
}
else
{
printf("\nString is not accepted");
break;}}
printf("\n");
for(k=0;k<=top;k++)
{
printf("%c",stack[k]);
}
printf("\t\t\t");
for(k=i;k<strlen(ip);k++){
printf("%c",ip[k]);
}
printf("\t\t\t");
}}
OUTPUT:
66
RESULT: Program to develop an operator precedence parser for a given language
was successfully implemented.
67
PROGRAM: /*First and follow of a grammar*/
#include <stdio.h>
#include <string.h>
int n;
char prods[50][50];
char firsts[26][50];
int is_first_done[26];
char follows[26][50];
int is_follow_done[26];
int isTerminal(char c)
{
if (c < 65 || c > 90)
return 1;
return 0;
}
void first(char nonterm)
{
int index = 0;
char curr_firsts[50];
for (int i = 0; i < n; i++)
{
if (prods[i][0] == nonterm)
{
int curr_prod_index = 2;
int flag = 0;
while (prods[i][curr_prod_index] != '\0' && flag == 0)
{
flag = 1;
if (isTerminal(prods[i][curr_prod_index]))
{
curr_firsts[index] = prods[i][2];
index++;
break;
}
if (!is_first_done[prods[i][curr_prod_index] - 65])
first(prods[i][curr_prod_index]);
int in = 0;
while (firsts[prods[i][curr_prod_index] - 65][in] != '\0')
{
curr_firsts[index] = firsts[prods[i][curr_prod_index] - 65][in];
if (firsts[prods[i][curr_prod_index] - 65][in] == 'e')
{
curr_prod_index++;
flag = 0;
}
index++;
in++;
}
}}
68
EXPERIMENT - 12
AIM: To develop a program to simulate first and follow of any given grammar.
ALGORITHM:
First():-
Follow():-
69
}
curr_firsts[index] = '\0';
index++;
strcpy(firsts[nonterm - 65], curr_firsts);
is_first_done[nonterm - 65] = 1;
}
void follow(char nonterm)
{
int index = 0;
char curr_follows[50];
if (nonterm == prods[0][0])
{
curr_follows[index] = '$';
index++;
}
for (int j = 0; j < n; j++)
{
int k = 2;
int include_lhs_flag;
while (prods[j][k] != '\0')
{
include_lhs_flag = 0;
if (prods[j][k] == nonterm)
{
if (prods[j][k + 1] != '\0')
{
if (isTerminal(prods[j][k + 1]))
{
curr_follows[index] = prods[j][k + 1];
index++;
break;
}
int in = 0;
while (firsts[prods[j][k + 1] - 65][in] != '\0')
{
if (firsts[prods[j][k + 1] - 65][in] == 'e')
{
include_lhs_flag = 1;
in++;
continue;
}
int temp_flag = 0;
for (int z = 0; z < index; z++)
if (firsts[prods[j][k + 1] - 65][in] == curr_follows[z])
{
temp_flag = 1;
in++;
break;
}
if (temp_flag)
70
71
continue;
curr_follows[index] = firsts[prods[j][k + 1] - 65][in];
index++;
in++;
}
}
if (prods[j][k + 1] == '\0' || include_lhs_flag == 1)
{
if (prods[j][0] != nonterm)
{
if (!is_follow_done[prods[j][0] - 65])
follow(prods[j][0]);
int x = 0;
while (follows[prods[j][0] - 65][x] != '\0')
{
int temp_flag = 0;
for (int z = 0; z < index; z++)
if (follows[prods[j][0] - 65][x] == curr_follows[z])
{
temp_flag = 1;
x++;
break;
}
if (temp_flag)
continue;
curr_follows[index] = follows[prods[j][0] - 65][x];
index++;
x++;
}
}
}
}
k++;
}
}
curr_follows[index] = '\0';
index++;
strcpy(follows[nonterm - 65], curr_follows);
is_follow_done[nonterm - 65] = 1;
}
int main()
{
printf("Enter the number of productions: ");
scanf("%d", &n);
printf("Enter the productions: \n");
for (int i = 0; i < n; i++)
scanf("%s", prods[i]);
for (int i = 0; i < 26; i++)
is_first_done[i] = 0;
72
73
for (int i = 0; i < n; i++)
if (is_first_done[prods[i][0] - 65] == 0)
first(prods[i][0]);
for (int i = 0; i < n; i++)
if (is_follow_done[prods[i][0] - 65] == 0)
follow(prods[i][0]);
printf("Firsts:\n");
for (int i = 0; i < 26; i++)
if (is_first_done[i])
printf("%c : %s\n", i + 65, firsts[i]);
printf("Follows:\n");
for (int i = 0; i < 26; i++)
if (is_follow_done[i])
printf("%c : %s\n", i + 65, follows[i]);
}
OUTPUT:
74
RESULT: Program to simulate first and follow of a grammar was successfully
implemented.
75
PROGRAM: /*Recursive descent parser*/
#include <stdio.h>
char inp[100];
int len = 0;
int curr = 0;
int E();
int Z();
int main()
{
printf("Enter input:\n");
scanf("%s", inp);
while (inp[len] != '\0')
len++;
int res = E();
if (res == 1 && curr == len)
printf("Input has been accepted.\n");
else
printf("Input has been rejected.\n");
}
int E()
{
int result;
if (inp[curr] == 'i')
{
curr++;
result = Z();
if (result == 1)
return 1;
else
return -1;
}
return -1;
}
int Z()
{
int result;
if (inp[curr] == '+' && inp[curr + 1] == 'i')
{
curr += 2;
result = Z();
if (result == 1)
return 1;
}
return 1;
}
76
EXPERIMENT - 13
ALGORITHM:
77
OUTPUT:
78
RESULT: Program to construct recursive descent parser for a grammar was
successfully implemented.
79
PROGRAM: /*Shift reduce parser*/
#include <stdio.h>
#include <string.h>
char inp[100];
int len;
char stack[100];
int top = 0;
void print_details(int ind, char *action)
{
printf("$");
for (int i = 0; i <= top; i++)
printf("%c", stack[i]);
printf("\t\t");
for (int i = ind; i < len; i++)
printf("%c", inp[i]);
printf("$\t\t%s\n", action);
}
void check_for_reduce(int i)
{
int flag = 1;
while (flag)
{
flag = 0;
if (stack[top - 2] == 'S' && stack[top - 1] == '+' && stack[top] == 'S')
{
print_details(i + 1, "REDUCE");
stack[top - 2] = 'S';
top = top - 2;
flag = 1;
}
else if (stack[top - 2] == 'S' && stack[top - 1] == '-' && stack[top] == 'S')
{
print_details(i + 1, "REDUCE");
stack[top - 2] = 'S';
top = top - 2;
flag = 1;
}
else if (stack[top - 2] == '(' && stack[top - 1] == 'S' && stack[top] == ')')
{
print_details(i + 1, "REDUCE");
stack[top - 2] = 'S';
top = top - 2;
flag = 1;
}
else if (stack[top] == 'i')
{
print_details(i + 1, "REDUCE");
stack[top] = 'S';
80
EXPERIMENT - 14
ALGORITHM:
81
flag = 1;
}
}
}
int main()
{
printf("Enter input:\n");
scanf("%s", inp);
len = strlen(inp);
printf("Stack\t\tInput\t\tAction\n");
for (int i = 0; i < len; i++)
{
print_details(i, "SHIFT");
stack[top] = inp[i];
check_for_reduce(i);
top++;
}
top--;
if (top == 0 && stack[0] == 'S')
printf("Accepted.\n");
else
printf("Rejected.\n");
}
OUTPUT:
82
RESULT: Program to construct shift reduce parser for a given language was
successfully implemented.
83