0% found this document useful (0 votes)
50 views51 pages

Experiment 1

1. The program implements an algorithm to find the ε-closure of states for a given NFA with ε-transitions. 2. It takes the regular expression as input and constructs an NFA by decomposing the regular expression into primitive components and constructing a finite automaton for each. 3. It then finds the ε-closure of each state by recursively adding states reachable via ε-transitions to the closure set.

Uploaded by

Harshit Singh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
50 views51 pages

Experiment 1

1. The program implements an algorithm to find the ε-closure of states for a given NFA with ε-transitions. 2. It takes the regular expression as input and constructs an NFA by decomposing the regular expression into primitive components and constructing a finite automaton for each. 3. It then finds the ε-closure of each state by recursively adding states reachable via ε-transitions to the closure set.

Uploaded by

Harshit Singh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 51

Experiment-1

1. Design and implement a lexical analyser for given language using C and the lexical analyser
should ignore redundant spaces, tabs and new lines.

AIM: Design a lexical analyser for given language and the lexical analyser should ignore redundant
spaces, tabs and new lines. It should also ignore comments. Although the syntax specification states
that identifiers can be arbitrarily long, you may restrict the length to some reasonable value. Simulate
the same in C language.

LOGIC:
1. Read the input Expression

2. Check whether input is alphabet or digits then store it as identifier

3. If the input is is operator store it as symbol

4. Check the input for keywords

#include<string.h>
#include<ctype.h>
#include<stdio.h>
void keyword(char str[10])
{
if(strcmp("for",str)==0||strcmp("while",str)==0||strcmp("do",str)==0||
strcmp("int",str)==0||strcmp("float",str)==0||strcmp("char",str)==0||
strcmp("double",str)==0|| strcmp("static",str)==0||strcmp("switch",str)==0||
strcmp("case",str)==0)
printf("\n%s is a keyword",str);
else
printf("\n%s is an identifier",str);
}
main()
{
FILE *f1,*f2,*f3;
char c,str[10],st1[10];
int num[100],lineno=0,tokenvalue=0,i=0,j=0,k=0;
printf("\nEnter the c program");/*gets(st1);*/
f1=fopen("input","w");
while((c=getchar())!=EOF)
putc(c,f1);
fclose(f1);
f1=fopen("input","r");
f2=fopen("identifier","w");
f3=fopen("specialchar","w");
while((c=getc(f1))!=EOF){
if(isdigit(c))
{

tokenvalue=c-'0';
c=getc(f1);
while(isdigit(c)){
tokenvalue*=10+c-'0';
c=getc(f1);
}
num[i++]=tokenvalue;
ungetc(c,f1);
}
else if(isalpha(c))
{
putc(c,f2);
c=getc(f1);
while(isdigit(c)||isalpha(c)||c=='_'||c=='$')
{
putc(c,f2);
c=getc(f1);
}
putc(' ',f2);
ungetc(c,f1);
}
else if(c==' '||c=='\t')
printf(" ");
else
if(c=='\n')
lineno++;
else
putc(c,f3);
}
fclose(f2);
fclose(f3);
fclose(f1);
printf("\nThe no's in the program are");
for(j=0;j<i;j++)
printf("%d",num[j]);
printf("\n");
f2=fopen("identifier","r");
k=0;
printf("The keywords and identifiersare:");
while((c=getc(f2))!=EOF){
if(c!=' ')
str[k++]=c;
else
{
str[k]='\0';
keyword(str);
k=0;
}

}
fclose(f2);
f3=fopen("specialchar","r");
printf("\nSpecial characters are");
while((c=getc(f3))!=EOF)
printf("%c",c);
printf("\n");
fclose(f3);
printf("Total no. of lines are:%d",lineno);
}
Input:
Enter Program $ for termination:
{
int a[3],t1,t2;
t1=2; a[0]=1; a[1]=2; a[t1]=3;
t2=-(a[2]+t1*6)/(a[2]-t1);
if t2>5 then
print(t2);
else {
int t3;
t3=99;
t2=-25;
print(-t1+t2*t3); /* this is a comment on 2 lines */
} endif
}
(cntrl+z)

Output:
Variables : a[3] t1 t2 t3
Operator : - + * / >
Constants : 2 1 3 6 5 99 -25
Keywords : int if then else endif
Special Symbols : , ; ( ) { }
Comments : this is a comment on 2 lines

Experiment-2
IMPLEMENTATION OF A LEXICAL ANALYZER USING LEX (WITH OUTPUT)

AIM: To write a program for implementing a Lexical analyser using LEX tool in Linux
platform.

ALGORITHM:

Step1: Lex program contains three sections: definitions, rules, and user subroutines. Each section
must be separated from the others by a line containing only the delimiter, %%. The format is as
follows: definitions %% rules %% user subroutines .

Step2: In definition section, the variables make up the left column, and their definitions make up the
right column. Any C statements should be enclosed in %{..}%. Identifier is defined such that the first
letter of an identifier is alphabet and remaining letters are alphanumeric.

Step3: In rules section, the left column contains the pattern to be recognized in an input file to
yylex(). The right column contains the C program fragment executed when that pattern is recognized.
The various patterns are keywords, operators, new line character, number, string, identifier, beginning
and end of block, comment statements, preprocessor directive statements etc.

Step4: Each pattern may have a corresponding action, that is, a fragment of C source code to execute
when the pattern is matched.

Step5: When yylex() matches a string in the input stream, it copies the matched text to an external
character array, yytext, before it executes any actions in the rules section.

Step6: In user subroutine section, main routine calls yylex(). yywrap() is used to get more input.

Step7: The lex command uses the rules and actions contained in file to generate a program, lex.yy.c,
which can be compiled with the cc command. That program can then receive input, break the input
into the logical pieces defined by the rules in file, and run program fragments contained in the actions
in file.

PROGRAM CODE:

//Implementation of Lexical Analyzer using Lex tool


%{
int COMMENT=0;
%}
identifier [a-zA-Z][a-zA-Z0-9]*
%%
#.* {printf("\n%s is a preprocessor directive",yytext);}
int |
float |
char |
double |
while |

for |
struct |
typedef |
do |
if |
break |
continue |
void |
switch |
return |
else |
goto {printf("\n\t%s is a keyword",yytext);}
"/*" {COMMENT=1;}{printf("\n\t %s is a COMMENT",yytext);}
{identifier}\( {if(!COMMENT)printf("\nFUNCTION \n\t%s",yytext);}
\{ {if(!COMMENT)printf("\n BLOCK BEGINS");}
\} {if(!COMMENT)printf("BLOCK ENDS ");}
{identifier}(\[[0-9]*\])? {if(!COMMENT) printf("\n %s
IDENTIFIER",yytext);} \".*\" {if(!COMMENT)printf("\n\t %s is a
STRING",yytext);}
[0-9]+ {if(!COMMENT) printf("\n %s is a NUMBER ",yytext);}
\)(\:)? {if(!COMMENT)printf("\n\t");ECHO;printf("\n");}
\( ECHO;
= {if(!COMMENT)printf("\n\t %s is an ASSIGNMENT
OPERATOR",yytext);} \<= |
\>= |
\< |
== |
\> {if(!COMMENT) printf("\n\t%s is a RELATIONAL OPERATOR",yytext);}
%%
int main(int argc, char **argv)
{
FILE *file;
file=fopen("var.c","r");
if(!file)
{
printf("could not open the file");
exit(0);
}
yyin=file;
yylex();
printf("\n");
return(0);
}
int yywrap()
{
return(1);
}
INPUT:
//var.c

#include<stdio.h>
#include<conio.h>
void main()
{
int a,b,c;
a=1;
b=2;
c=a+b;
printf("Sum:%d",c);
}
OUTPUT:
6

Experiment-3
3. Generate YACC specification for a few syntactic categories.
a) Program to recognize a valid arithmetic expression that uses operator +, – , * and /. b)
Program to recognize a valid variable which starts with a letter followed by any number of
letters or digits.

Code:
%{
/* Definition section*/
#include "y.tab.h"
extern yylval;
%}
%%
[0-9]+ {
yylval = atoi(yytext);
return NUMBER;
}

[a-zA-Z]+ { return ID; }


[ \t]+; /*For skipping whitespaces*/

\n { return 0; }
{ return yytext[0]; }
%%

Parser Source Code:


%{
/* Definition section */
#include <stdio.h>
%}

%token NUMBER ID
// setting the precedence
// and associativity of operators
%left '+' '-'
%left '*' '/'

/* Rule Section */
%%
E : T{
printf("Result = %d\n", $$);
return 0;
}

T:
T '+' T { $$ = $1 + $3; }
| T '-' T { $$ = $1 - $3; }
| T '*' T { $$ = $1 * $3; }

| T '/' T { $$ = $1 / $3; }
| '-' NUMBER { $$ = -$2; }
| '-' ID { $$ = -$2; }
| '(' T ')' { $$ = $2; }
| NUMBER { $$ = $1; }
| ID { $$ = $1; };
%%

int main() {
printf("Enter the expression\n");
yyparse();
}

/* For printing error messages */


int yyerror(char* s) {
printf("\nExpression is invalid\n");
}
Input: 7*(5-3)/2
Output: 7

Input: 6/((3-2)*(-5+2))
Output: -2

Output:

8
Part (3B)
PROGRAM :

YACC PART:
CODE:(vid.y)
%{

#include<stdio.h>

#include<stdlib.h>

%}

%token DIGIT LETTER UND NL

%%

stmt: variable NL {printf("valid identifiers\n"); exit(0);}

variable: LETTER alphanumeric;

alphanumeric: LETTER alphanumeric | DIGIT alphanumeric | UND alphanumeric | LETTER |DIGIT |


UND;

%%

int yyerror(char *msg)

printf("Invalid variable\n");
exit(0);

main()

printf("enter the variable: \n");

yyparse();

9
}
LEX PART:(vid.l)

CODE:

%{

#include"y.tab.h"

%}

%%

[a-z A-Z] {return LETTER;}

[0-9] {return DIGIT;}

[_] {return UND;}

[\n] {return NL;}

{return yytext[0];}

%%

OUTPUT :

yacc -d vid.y

lex vid.l

cc y.tab.c lex.yy.c -ly -ll

./a.out

enter the variable:

abc

valid identifiers

yacc -d vid.y
lex vid.l

cc y.tab.c lex.yy.c -ly -ll

10
./a.out
enter the variable:

(+cd-)

Invalid variable
11

Experiment-4
Aim: - Write program to find ε – closure of all states of any given NFA with ε transition.

Procedure: -

1. Start the Program.


2. Enter the regular expression R over alphabet E.
3. Decompose the regular expression R into its primitive components
4. For each component construct finite automata.
5. To construct components for the basic regular expression way that corresponding to that
way compound regular expression.
6. Stop the Program.

Program: -
#include<stdio.h>
#include<stdlib.h>
struct node
{ int st;
struct node *link;
};
void findclosure(int,int);
void insert_trantbl(int, cha, int);
int findalpha(char);
void print_e_closure(int);
staic int set[20],nostate, noalpha, s, notransition, c,r,buffer[20];
char alphabet[20];
static int e_closure[20][20]={0};
struct node * transition[20][20]={NULL};
voidmain()
{
int i,j,k,m,t,n;
struct node *temp;

12

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("\nEnter the number of states?\n");
scanf("%d",&nostate);
printf("\nEnter no of transition?\n");
scanf("%d",&notransition);
printf("NOTE:-[Transition is in the form_>qno alphabet qno]\n",notransition);
printf("NOTE:-[State 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")
printf("e-closure of states...\n");
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("\ne-closure(q%d):"i);
print_e_closure(i);
}
}
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_>;
}
}

}
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=trabsition[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 print_e_closure(int i)
{
int j;
printf("{");

for(j=0;e_closure[i][j]!=0;j++)
printf("q%d",e_closure[i][j[);
printf("}");
}
Experiment No.:5
Aim: -Construction of DFA from NFA

Procedure: -

1. Start the program.


2. Create state table from the given NDFA.
3. Create a blank state table under possible input alphabets for the equivalent DFA.
4. Mark the start state of the DFA by q0 (Same as the NDFA).
5. Find out the combination of States {Q0, Q1,... , Qn} for each possible input alphabet. 6. Each
time we generate a new DFA state under the input alphabet columns, we have to apply step 4
again, otherwise go to step 6.
7. The states which contain any of the final states of the NDFA are the final states of the
equivalent DFA
Program: -

#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<process.h>
typedef struct
{
int num[10],top;
}
stack;
stack s;
int mark[16][31],e_close[16][31],n,st=0;
char data[15][15];
void push(int a)
{
s.num[s.top]=a;
s.top=s.top+1;
}
int pop()
{
int a;
if(s.top==0)
return(-1);
s.top=s.top-1;
a=s.num[s.top];
return(a);
}
void epi_close(int s1,int s2,int c)
{
int i,k,f;
for(i=1;i<=n;i++)

17

{
if(data[s2][i]=='e')
{
f=0;
for(k=1;k<=c;k++)
if(e_close[s1][k]==i)
f=1;
if(f==0)
{
c++;
e_close[s1][c]=i;
push(i);
}
}
}
while(s.top!=0) epi_close(s1,pop(),c);
}
int move(int sta,char c)
{
int i;
for(i=1;i<=n;i++)
{
if(data[sta][i]==c)
return(i);
}
return(0);
}
void e_union(int m,int n)
{
int i=0,j,t;
for(j=1;mark[m][i]!=-1;j++)
{
while((mark[m][i]!=e_close[n][j])&&(mark[m][i]!=-1))
i++;
if(mark[m][i]==-1)mark[m][i]=e_close[n][j];
}
}
void main()
{
int i,j,k,Lo,m,p,q,t,f;
clrscr();
printf("\n enter the NFA state table entries:");
scanf("%d",&n);
printf("\n");
for(i=0;i<=n;i++)
printf("%d",i);
printf("\n");
for(i=0;i<=n;i++)
printf("------");
printf("\n");
for(i=1;i<=n;i++)
{
printf("%d|",i);
fflush(stdin);
for(j=1;j<=n;j++)
scanf("%c",&data[i][j]);
}
for(i=1;i<=15;i++)
for(j=1;j<=30;j++)
{
e_close[i][j]=-1;
mark[i][j]=-1;
}
for(i=1;i<=n;i++)
{
e_close[i][1]=i;
s.top=0;
epi_close(i,i,1);
}
for(i=1;i<=n;i++)
{
for(j=1;e_close[i][j]!=-1;j++)
for(k=2;e_close[i][k]!=-1;k++)
if(e_close[i][k-1]>e_close[i][k])
{
t=e_close[i][k-1];
e_close[i][k-1]=e_close[i][k];
e_close[i][k]=t;
}
}
printf("\n the epsilon closures are:");
for(i=1;i<=n;i++)
{
printf("\n E(%d)={",i);
for(j=1;e_close[i][j]!=-1;j++)
printf("%d",e_close[i][j]);
printf("}");
}
j=1;
while(e_close[1][j]!=-1)
{
mark[1][j]=e_close[1][j];
j++;
}
st=1;
printf("\n DFA Table is:");
printf("\n a b ");
printf("\n--------------------------------------");
for(i=1;i<=st;i++)
{
printf("\n{");
for(j=1;mark[i][j]!=-1;j++)
printf("%d",mark[i][j]);
printf("}");
while(j<7)
{
printf(" ");
j++;
}
for(Lo=1;Lo<=2;Lo++)
{
for(j=1;mark[i][j]!=-1;j++)
{
if(Lo==1)
t=move(mark[i][j],'a');
if(Lo==2)
t=move(mark[i][j],'b');
if(t!=0)
e_union(st+1,t);
}
for(p=1;mark[st+1][p]!=-1;p++)
for(q=2;mark[st+1][q]!=-1;q++)
{
if(mark[st+1][q-1]>mark[st+1][q])
{
t=mark[st+1][q];
mark[st+1][q]=mark[st+1][q-1];
mark[st+1][q-1]=t;
}
}
f=1;
for(p=1;p<=st;p++)
{
j=1;
while((mark[st+1][j]==mark[p][j])&&(mark[st+1][j]!=-1))
j++;
if(mark[st+1][j]==-1 && mark[p][j]==-1)
f=0;
}
if(mark[st+1][1]==-1)
f=0;
printf("\t{");
for(j=1;mark[st+1][j]!=-1;j++)
{

printf("%d",mark[st+1][j]);
}
printf("}\t");
if(Lo==1)
printf(" ");
if(f==1)
st++;
if(f==0)
{
for(p=1;p<=30;p++)
mark[st+1][p]=-1;
}
}
}
getch();
}
Results:

Enter the NFA state table entries: 11


(Note: Instead of '-' symbol use blank spaces in the output window)

The Epsilon Closures Are:


E(1)={12358}
E(2)={235}
E(3)={3}
E(4)={234578}
E(5)={5}
E(6)={235678}
E(7)={23578}
E(8)={8}
E(9)={9}
E(10)={10}

21
E(11)={11}
DFA Table is:

ab
----------------------------------------------------
{12358} {2345789} {235678}
{2345789} {2345789} {23567810}
{235678} {2345789} {235678}
{23567810} {2345789} {23567811}
{23567811} {2345789} {235678}
Experiment No: 6
Aim: Write program to minimize any given DFA.

ALGORITHM:
1. Get the start state, final state, input symbols as input and also give the edge value for each state.
2. Maintain a stack required for transition from one state to other state.
3. Using Pop or push function perform the insertion and deletion of elements when required. 4.
Finally conversion has been made to change from regular expression to minimized DFA and the
output is displayed as DFA transition table.

#include<stdio.h>
#include<string.h>
#define STATES 50
struct Dstate
{
char name;
char StateString[STATES+1];
char trans[10];
int is_final;
}
Dstates[50];
struct tran
{
char sym;
int tostates[50];
int notran;
};
struct state
{
int no;
struct tran tranlist[50];
};
int stackA[100],stackB[100],c[100],Cptr=-1,Aptr=-1,Bptr=-1;
struct state States[10];
char temp[STATES+1],inp[10];
int nos,noi,nof,j,k,nods=-1;

void pushA(int z)
{
stackA[++Aptr]=z;
}
void pushB(int z)
{
stackB[++Bptr]=z;
}
int popA()
{

23

return stackA[Aptr--];
}
void copy(int i)
{
char temp[STATES+1]=" ";
int k=0;
Bptr=-1;
strcpy(temp,Dstates[i].StateString);
while(temp[k]!='\0')
{
pushB(temp[k]-'0');
k++;
}
}
int popB()
{
return stackB[Bptr--];
}
int peekA()
{
return stackA[Aptr];
}
int peekB()
{
return stackA[Bptr];
}
int seek(int arr[],int ptr,int s)
{
int i;
for(i=0;i<=ptr;i++)
{
if(s==arr[i])
return 1;
}
return 0;
}
void sort()
{
int i,j,temp;
for(i=0;i
{
for(j=0;j<(Bptr-i);j++)
{
if(stackB[j]>stackB[j+1])
{
temp=stackB[j];
stackB[j]=stackB[j+1];
stackB[j+1]=temp;

24

}
}
}
}

void tostring()
{
int i=0;
sort();
for(i=0;i<=Bptr;i++)
{
temp[i]=stackB[i]+'0';
}
temp[i]='\0';
}
void display_DTran()
{
int i,j;
printf("\n\t\t DFA transition table");
printf("\n\t\t ---------------------------------------------- ");
printf("\n States \tString \tInputs\n");
for(i=0;i<noi;i++)
{
printf("\t %c",inp[i]);
}
printf("\n\t ------------------------------------------------- ");
for(i=0;i<nods;i++)
{
if(Dstates[i].is_final==0)
printf("\n%c",Dstates[i].name);
else
printf("\n*%c",Dstates[i].name);
printf("\t%s",Dstates[i].StateString);
for(j=0;j<noi;j++)
{
printf("\t%c",Dstates[i].trans[j]);
}
}
printf("\n");
}

void move(int st,int j)


{
int ctr=0;
while(ctr<States[st].tranlist[j].notran)
{
pushA(States[st].tranlist[j].tostates[ctr++]);
}

25

}
void lambda_closure(int st)
{
int ctr=0,in_state=st,curst=st,chk;
while(Aptr!=-1)
{
curst=popA();
ctr=0;
in_state=curst;
while(ctr<=States[curst].tranlist[noi].notran)
{
chk=seek(stackB,Bptr,in_state);
if(chk==0)
pushB(in_state);
in_state=States[curst].tranlist[noi].tostates[ctr++];
chk=seek(stackA,Aptr,in_state);
if(chk==0 && ctr<=States[curst].tranlist[noi].notran)
pushA(in_state);
}
}
}
void main()
{
int i,final[20],start,fin=0;
char c,ans,st[20];
printf("\n Enter no of states in NFA:");
scanf("%d",&nos);
for(i=0;i<nos;i++)
{
States[i].no=i;
}
printf("\n Enter the start states:");
scanf("%d",&start);
printf("Enter the no of final states:");
scanf("%d",&nof);
printf("Enter the final states:\n");
for(i=0;i<nof;i++)
scanf("%d",&final[i]);
printf("\n Enter the no of input symbols:");
scanf("%d",&noi);
c=getchar();
printf("Enter the input symbols:\n");
for(i=0;i<noi;i++)
{
scanf("%c",&inp[i]);
c=getchar();
}

26

//g1inp[i]='e';
inp=[i]=’e’;
printf("\n Enter the transitions:(-1 to stop)\n");
for(i=0;i<nos;i++)
{
for(j=0;j<=noi;j++)
{
States[i].tranlist[j].sym=inp[j];
k=0;
ans='y';
while(ans=='y')
{
printf("move(%d,%c);",i,inp[j]);
scanf("%d",&States[i].tranlist[j].tostates[k++]);
if((States[i].tranlist[j].tostates[k-1]==-1))
{
k--;
ans='n';
break;
}
}
States[i].tranlist[j].notran=k;
}
}
i=0;nods=0,fin=0;
pushA(start);
lambda_closure(peekA());
tostring();
Dstates[nods].name='A';
nods++;
strcpy(Dstates[0].StateString,temp);
while(i<nods)
{
for(j=0;j<noi;j++)
{
fin=0;
copy(i);
while(Bptr!=-1)
{
move(popB(),j);
}
while(Aptr!=-1)
lambda_closure(peekA());
tostring();
for(k=0;k<nods;k++)
{
if((strcmp(temp,Dstates[k].StateString)==0))
{

27

Dstates[i].trans[j]=Dstates[k].name;
break;
}
}
if(k==nods)
{
nods++;
for(k=0;k<nof;k++)
{
fin=seek(stackB,Bptr,final[k]);
if(fin==1)
{
Dstates[nods-1].is_final=1;
break;
}
}
strcpy(Dstates[nods-1].StateString,temp);
Dstates[nods-1].name='A'+nods-1;
Dstates[i].trans[j]=Dstates[nods-1].name;
}
}
i++;
}
display_DTran();
}
OUTPUT:

Enter the no of input symbols:2

Enter the input symbols:

a ,b

Enter the transitions:(-1 to stop)

move(0,a);-1

move(0,b);-1

move(0,e);1

move(0,e);7
move(0,e);-1

move(1,a);-1

move(1,b);-1

28

move(1,e);2

move(1,e);4

move(1,e);-1

move(2,a);3

move(2,a);3

move(2,a);-1

move(2,b);-1

move(2,e);-1

move(3,a);-1

move(3,b);-1

move(3,e);6

move(3,e);-1

move(4,a);-1

move(4,b);-1

move(4,e);-1

move(5,a);-1

move(5,b);-1

move(5,e);6

move(5,e);1

move(5,e);-1

move(6,a);-1

move(6,b);-1
move(6,e);-1

move(7,a);-1

29

move(7,b);-1

move(7,e);-1

DFA transition table

States String Inputs

ab

-------------------------------------------------

A 01247 B C

B 36 C C

CCC

Experiment No.:7
Aim: -Implementation of Operator Precedence Parser.
Procedure: -

1- Let the input string to be initially the stack contains, when the reduce action takes place, we
have to reach create parent child relationship.
2- See IP to pointer to the first symbol of input string and repeat forever if only $ is on the input
accept and break else begin.
3- Let 'd’ be the top most terminal on the stack and 'b' be current input IF(a<b) or a=b then Begin
push 'b' onto the stack.
4- Advance Input to the stack to the next Input symbol end;
else if(a>b)
5- Repeat pop the stack until the top most terminal is related by < to the terminal most recently
popped else error value routine end;

Program: -
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
char q[9][9]={
{'>','>','<','<','<','<','>','<','>' },
{'>','>','<','<','<','<','>','<','>' },
{'>','>','>','>','<','<','>','<','>' },
{'>','>','>','>','<','<','>','<','>' },
{'>','>','<','<','<','<','>','<','>' },
{'<','<','<','<','<','<','=','<','E' },
{'>','>','>','>','>','E','>','E','>' },
{'>','>','>','>','>','E','>','E','>' },
{'<','<','<','<','<','<','E','<','A' }
};
char s[30],st[30],qs[30];
int top=-1,r=-1,p=0;
void push(char a)
{
top++;
st[top]=a;
}
char pop()
{
char a;
a=st[top];
top--;
return a;
}
int find(char a)
{

31

switch(a)
{
case '+':return 0;
case '-':return 1;
case '*':return 2;
case '/':return 3;
case '^':return 4;
case '(':return 5;
case ')':return 6;
case 'a':return 7;
case '$':return 8;
default :return -1;
}
}
void display(char a)
{
printf("\n Shift %c",a);
}
void display1(char a)
{
if(isalpha(a))
printf("\n Reduce E->%c",a);
else if((a=='+')||(a=='-')||(a=='*')||(a=='/')||(a=='^'))
printf("\n Reduce E->E%cE",a);
else if(a==')')
printf("\n Reduce E->(E)");
}
intrel(char a,char b,char d)
{
if(isalpha(a)!=0)
a='a';
if(isalpha(b)!=0)
b='a';
if(q[find(a)][find(b)]==d)
return 1;
else
return 0;
}
void main()
{
char s[100];
int i=-1;
clrscr();
printf("\n\t Operator Preceding Parser\n");
printf("\n Enter the Arithmetic Expression End with $..");
gets(s);
push('$');
while(i)

32

{
if((s[p]=='$')&&(st[top]=='$'))
{
printf("\n\nAccepted");
break;
}
else if(rel(st[top],s[p],'<')||rel(st[top],s[p],'='))
{
display(s[p]);
push(s[p]);
p++;
}
else if(rel(st[top],s[p],'>'))
{
do
{
r++;
qs[r]=pop();
display1(qs[r]);
}
while(!rel(st[top],qs[r],'<'));
}
}
getch();
}
Results:
Enter the Arithmetic Expression End with $: a-(b*c)^d$
Shift a
Reduce E->a
Shift -
Shift (
Shift b
Reduce E->b
Shift *
Shift c
Reduce E->c
Reduce E->E*E
Shift )
Reduce E->(E)
Shift ^
Shift d
Reduce E->d
Reduce E->E^E
Reduce E->E-E
Accepted

Experiment NO: 8
Aim: Write program to find Simulate First and Follow of any given grammar.

PROGRAM:
// C program to calculate the First and
// Follow sets of a given grammar
#include<stdio.h>
#include<string.h>
int n,m=0,p,i=0,j=0;
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:");
scanf("%d",&n);
printf("Enter the productions(epsilon=$):\n");
for(i=0;i<n;i++)
scanf("%s%c",a[i],&ch);

do
{
m=0;
printf("Enter the element whose FOLLOW is to be found:");

scanf("%c",&c);
follow(c);
printf("FOLLOW(%c) = { ",c);
for(i=0;i<m;i++)
printf("%c ",f[i]);
printf(" }\n");
printf("Do you want to continue(0/1)?");
scanf("%d%c",&z,&ch);
}
while(z==1);
}
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++)
{

34

if(a[i][j]==c)
{
if(a[i][j+1]!='\0')first(a[i][j+1]);

if(a[i][j+1]=='\0'&&c!=a[i][0])
follow(a[i][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][2]=='$') follow(a[i][0]);
else if(islower(a[k][2]))f[m++]=a[k][2];
else first(a[k][2]);
}
}

Output:
First(X) = { q, n, o, p, #,m}
First(T) = { q, #, }
First(S) = { p, #, }
First(R) = { o, p, q, #, }
-----------------------------------------------
Follow(X) = { $, }
Follow(T) = { n, m, }
Follow(S) = { $, q, m, }
Follow(R) = { m, }

35

Experiment No. 09
Aim: -Implementation of Recursive Descent Parser
Procedure: -

Begin
T()
E_prime();
print E-> TE'
end
procedure prime():
ifip_sym+='+' then
begin
advance();
T();
eprime();
prime E'->TE'
end
else
print E'->e
procedure T();
begin
e();
Tprime();
print T->FT';
end;
procedureTprime();
ifip_sym='*' then
begin
advance();
F();
Tprime()
print T'->T*FT'
end
else print T'->e
procedure F()
ifip_sym =id then
begin
advance();
print->id
end
else
Error();
end;
else
Error();

Program:-

36

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
char ip_sym[15],ip_ptr=0;
void e_prime();
void t();
void e();
void t_prime();
void f();
void advance();
void e()
{
printf("\n\t\tE'------->TE'");
t();
e_prime();
}
void e_prime()
{
if(ip_sym[ip_ptr]=='+')
{
printf("\n\t\tE'------->+TE'");
advance();
t();
e_prime();
}
else
printf("\n\t\tE'----->e'");
}
void t()
{
printf("\n\t\tT'------->FT'"); f();
t_prime();
}
void t_prime()
{
if(ip_sym[ip_ptr]=='*')
{
printf("\n\t\tT------>*FT'"); advance();
f();
t_prime();
}
else
{
printf("\n\t\tT'----->e");
}
}
void f()

37

{
if((ip_sym[ip_ptr]=='i')||(ip_sym[ip_ptr]=='j'))
{
printf("\n\t\tF------>i"); advance();
}
else
{
if(ip_sym[ip_ptr]=='(')
{
advance();
e();
if(ip_sym[ip_ptr]==')')
{
advance();
printf("\n\t\tF----->(E)");
}
else
{
printf("\n\t\tSyntax Error");
getch();
exit(1);
}
}
}
}
void advance()
{
ip_ptr++;
}
void main()
{
int i;
clrscr();
printf("\n\t\t GRAMMER WITHOUT RECURSION");
printf("\n\t\t E------>TE'\n\t\tE'/e\r\t\tT----->FT");
printf("\n\t\t T------>*FT/e\n\t\tF------>(E)/id");
printf("\n\t\t Enter the Input Symbol: ");
gets(ip_sym);
printf("\n\t\t Sequence of Production Rules");
e();
getch();
}

Results:

GRAMMER WITHOUT RECURSION


E------>TE'
T----->FT

38

T------>*FT/e
F------>(E)/id
Enter the Input Symbol: T
Sequence of Production Rules
E'------->TE'
T'------->FT'
T'----->e
E'----->e'
Experiment No.:10
Aim: -Implementation of Shift Reduce Parsing Algorithm

Procedure:-
Grammar:
E->E+E
E->E*E
E->E/E
E->a/b
Method:
Stack Input Symbol Action
$ id1*id2$ shift
$id1 *id2 $ shift *
$* id2$ shift id2
$id2 $ shift
$ $ accept

Shift: Shifts the next input symbol onto the stack.


Reduce: Right end of the string to be reduced must be at the top of the stack.
Accept: Announce successful completion of parsing.
Error: Discovers a syntax error and call an error recovery routine

Program: -

#include<conio.h>
#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()
{
clrscr();
printf("\n\n\t Shift Reduce Parser\n");
printf("\n\t***** ****** ******");
printf("\n Grammar\n\n");
printf("E->E+E\nE->E/E\n");
printf("E->E*E\nE->a/b");
printf("\n Enter the Input Symbol:\t");
gets(ip_sym);
printf("\n\n\t Stack Implementation Table");
printf("\n Stack\t\t Input Symbol\t\t Action");

40

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();
getch();
}
void check()
{
int flag=0;
temp2[0]=stack[st_ptr];
temp[1]='\0';
if((!strcmpi(temp2,"a"))||(!strcmpi(temp2,"b")))
{
stack[st_ptr]='E';
if(!strcmpi(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->a",stack,ip_sym);
flag=1;
}
if((!strcmpi(temp2,"+"))||(strcmpi(temp2,"*"))||(!strcmpi(temp2,"/")))
{
flag=1;
}
if((!strcmpi(stack,"E+E"))||(!strcmpi(stack,"E/E"))||(!strcmpi(stack,"E*E")))
{
strcpy(stack,"E");
st_ptr=0;
if(!strcmpi(stack,"E+E"))
printf("\n$%s\t\t%s$\t\t\tE->E+E",stack,ip_sym);

41

else
if(!strcmpi(stack,"E/E"))
printf("\n$%s\t\t\t%s$\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(!strcmpi(stack,"E")&&ip_ptr==len)
{
printf("\n$%s\t\t%s$\t\t\tAccept",ip_sym);
getch();
exit(0);
}
if(flag==0)
{
printf("\n %s \t\t\t %s \t\t Reject",stack,ip_sym);
}
return;
}

Results:

Shift Reduce Parser


***** ****** *****
Grammar
E->E+E
E->E/E
E->E*E
E->a/b
Enter the input symbol: if(a*b)
Stack Implementation Table
Stack Input Symbol Action
$ if(a*b)$ --
$i f(a*b)$ shift i
$if (a*b)$ shift f
$if( a*b)$ shift (
$if(a *b)$ shift a
$if(E *b)$ E->a
$if(E* b)$ shift *
$if(E* b )$ shift b
$if(E*E )$ E->b
$if(E*E) $ shift )
$if(E) $ E->E*E
$if(E) $ reject

42
Experiment No. 11
Aim: Write a program to perform loop unrolling.

Program 1:
// This program does not uses loop unrolling.
#include<stdio.h>

int main(void)
{
for (int i=0; i<5; i++)
printf("Hello\n"); //print hello 5 times

return 0;
}

Program 2:
// This program uses loop unrolling.

#include<stdio.h>
int main(void)
{
// unrolled the for loop in program 1
printf("Hello\n");
printf("Hello\n");
printf("Hello\n");
printf("Hello\n");
printf("Hello\n");

return 0;
}

Agenda
1.Algorithm
2.Program (code)
3.Output

1.Algorithm
1.Start
2.Intialise value N
3.Initialize the count value
4.If perform loop unrolling then,
4.1 Perform each operation upto count.
5.Else, loop rolling
5.1 check the condition.
5.2 Perform the operation.

44
5.3 increment the count.
6.Print the result.
7.Stop

2.Code
#include<stdio.h>
#include<conio.h>

void main() {
unsigned int n;
int x;
char ch;
clrscr();
printf("\nEnter N\n");
scanf("%u", & n);
printf("\n1. Loop Roll\n2. Loop UnRoll\n");
printf("\nEnter ur choice\n");
scanf(" %c", & ch);
switch (ch) {
case '1':
x = countbit1(n);
printf("\nLoop Roll: Count of 1's : %d", x);
break;
case '2':
x = countbit2(n);
printf("\nLoop UnRoll: Count of 1's : %d", x);
break;
default:
printf("\n Wrong Choice\n");

}
getch();
}
int countbit1(unsigned int n) {
int bits = 0, i = 0;
while (n != 0) {
if (n & 1) bits++;
n >>= 1;
i++;
}
printf("\n no of iterations %d", i);
return bits;
}
int countbit2(unsigned int n) {
int bits = 0, i = 0;
while (n != 0) {
if (n & 1) bits++;

45
if (n & 2) bits++;
if (n & 4) bits++;
if (n & 8) bits++;
n >>= 4;
i++;
}
printf("\n no of iterations %d", i);
return bits;
}

Input/Output
Enter N
3
1. Loop Roll
2. Loop UnRoll

Enter ur choice
2

no of iterations 1
Loop UnRoll: Count of 1's :

Experiment No.:12
Aim: -Implementation of Code Optimization Techniques

Procedure:-

Take the input code then perform the following:


• Dead Code Elimination

• Common Sub-expression Elimination

• Copy Propagation

• Code Motion

• Induction Variable Elimination

• Reduction In Strength

Program:-
#include<stdio.h>
#include<conio.h>
#include<string.h>
struct op
{
char l;
char r[20];
}
op[10],pr[10];
void main()
{
int a,i,k,j,n,z=0,m,q;
char *p,*l;
char temp,t;
char *tem;
clrscr();
printf("Enter the Number of Values:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("left: ");
op[i].l=getche();
printf("\tright: ");
scanf("%s",op[i].r);
}
printf("Intermediate Code\n") ;
for(i=0;i<n;i++)
{
printf("%c=",op[i].l);
printf("%s\n",op[i].r);
}
for(i=0;i<n-1;i++)

47
{
temp=op[i].l;
for(j=0;j<n;j++)
{
p=strchr(op[j].r,temp);
if(p)
{
pr[z].l=op[i].l;
strcpy(pr[z].r,op[i].r);
z++;
}
}
}
pr[z].l=op[n-1].l;
strcpy(pr[z].r,op[n-1].r);
z++;
printf("\nAfter Dead Code Elimination\n");
for(k=0;k<z;k++)
{
printf("%c\t=",pr[k].l);
printf("%s\n",pr[k].r);
}
for(m=0;m<z;m++)
{
tem=pr[m].r;
for(j=m+1;j<z;j++)
{
p=strstr(tem,pr[j].r);
if(p)
{
t=pr[j].l;
pr[j].l=pr[m].l;
for(i=0;i<z;i++)
{
l=strchr(pr[i].r,t) ;
if(l)
{
a=l-pr[i].r;
printf("pos: %d",a);
pr[i].r[a]=pr[m].l;
}
}
}
}
}
printf("Eliminate Common Expression\n");
for(i=0;i<z;i++)
{

48
printf("%c\t=",pr[i].l);
printf("%s\n",pr[i].r);
}
for(i=0;i<z;i++)
{
for(j=i+1;j<z;j++)
{
q=strcmp(pr[i].r,pr[j].r);
if((pr[i].l==pr[j].l)&&!q)
{
pr[i].l='\0';
strcpy(pr[i].r,'\0');
}
}
}
printf("Optimized Code\n");
for(i=0;i<z;i++)
{
if(pr[i].l!='\0')
{
printf("%c=",pr[i].l);
printf("%s\n",pr[i].r);
}
}
getch();
}

Results:

Enter the Number of Values: 5


Left: a right: 9
Left: b right: c+d
Left: e right: c+d
Left: f right: b+e
Left: r right: f
Intermediate Code
a=9
b=c+d
e=c+d
f=b+e
r=:f
After Dead Code Elimination
b =c+d
e =c+d
f =b+e
r =:f
Eliminate Common Expression
b =c+d

49
b =c+d
f =b+b
r =:f
Optimized Code
b=c+d
f=b+b
r=:f

Experiment :13
Aim: - Implement Intermediate code generation for simple expressions.

Program

#include<stdio.h>
#include<conio.h>
#include<string.h>
int i=1,j=0,no=0,tmpch=90;
char str[100],left[15],right[15];
void findopr();
void explore();
void fleft(int);
void fright(int);
struct exp
{
int pos;
char op;
}k[15];
void main()
{
printf("\t\tINTERMEDIATE CODE GENERATION\n\n");
printf("Enter the Expression :");
scanf("%s",str);
printf("The intermediate code:\n");
findopr();
explore();
}
void findopr()
{
for(i=0;str[i]!='\0';i++)
if(str[i]==':')

51

{
k[j].pos=i;
k[j++].op=':';
}
for(i=0;str[i]!='\0';i++)
if(str[i]=='/')
{
k[j].pos=i;
k[j++].op='/';
}
for(i=0;str[i]!='\0';i++)
if(str[i]=='*')
{
k[j].pos=i;
k[j++].op='*';
}
for(i=0;str[i]!='\0';i++)
if(str[i]=='+')
{
k[j].pos=i;
k[j++].op='+';
}
for(i=0;str[i]!='\0';i++)
if(str[i]=='-')
{
k[j].pos=i;
k[j++].op='-';
}
}
void explore()
{

52

i=1;
while(k[i].op!='\0')
{
fleft(k[i].pos);
fright(k[i].pos);
str[k[i].pos]=tmpch--;
printf("\t%c := %s%c%s\t\t",str[k[i].pos],left,k[i].op,right);
printf("\n");
i++;
}
fright(-1);
if(no==0)
{
fleft(strlen(str));
printf("\t%s := %s",right,left);
getch();
exit(0);
}
printf("\t%s := %c",right,str[k[--i].pos]);
getch();
}
void fleft(int x)
{
int w=0,flag=0;
x--;
while(x!= -1 &&str[x]!= '+' &&str[x]!='*'&&str[x]!='='&&str[x]!='\0'&&str[x]!='-
'&&str[x]!='/'&&str[x]!=':')
{
if(str[x]!='$'&& flag==0)
{
left[w++]=str[x];

53

left[w]='\0';
str[x]='$';
flag=1;
}
x--;
}
}
void fright(int x)
{
int w=0,flag=0;
x++;
while(x!= -1 && str[x]!= '+'&&str[x]!='*'&&str[x]!='\0'&&str[x]!='='&&str[x]!=':'&&str[x]!='-
'&&str[x]!='/')
{
if(str[x]!='$'&& flag==0)
{
right[w++]=str[x];
right[w]='\0';
str[x]='$';
flag=1;
}
x++;
}
}

54

code generation for


simple expressio
5

You might also like