0% found this document useful (0 votes)
18 views

CD Manual

Uploaded by

Bhargavi J
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)
18 views

CD Manual

Uploaded by

Bhargavi J
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/ 82

Blooms

CO# After completion of course, students should able to


Level
CO1 Design, develop, and implement a compiler for any language L6
CO2 Utilize LEX and YACC tools for developing a scanner and a parser L3
CO3 Design and implement LL and LR parsers L6
Design algorithms to perform code optimization in order to improve the performance of
CO4 a program in terms of space and time complexity L6
Design algorithms to perform code optimization in order to improve the performance of
CO5 a program in terms of space and time complexity L6

PROGRAMME OUTCOMES (PO):

PO 1 Engineering Knowledge: Apply the knowledge of mathematics, science,


engineering fundamentals, and an engineering specialization to the solution
of complex engineering problems.
PO 2 Problem Analysis: Identify, formulate, review research literature, and
analyze complex engineering problems reaching substantiated conclusions
using first principles of mathematics, natural sciences, and engineering
sciences.
PO 3 Design/Development of Solutions: Design solutions for complex
engineering problems and design system components or processes that
meet the specified needs with appropriate consideration for the public
health and safety, and the cultural, societal, and environmental
considerations.
PO 4 Conduct Investigations of Complex Problems: Use research-based
knowledge and research methods including design of experiments, analysis
and interpretation of data, and synthesis of the information to provide valid
conclusions.
PO 5 Modern Tool Usage: Create, select, and apply appropriate techniques,
resources, and modern engineering and IT tools including prediction and
modeling to complex engineering activities with an understanding of the
limitations.
PO 6 The Engineer and Society: Apply reasoning informed by the contextual
knowledge to assess societal, health, safety, legal and cultural issues and
the consequent responsibilities relevant to the professional engineering
practice.
PO 7 Environment and Sustainability: Understand the impact of the
professional engineering solutions in societal and environmental contexts,
and demonstrate the knowledge of, and need for sustainable development.
PO 8 Ethics: Apply ethical principles and commit to professional ethics and
responsibilities and norms of the engineering practice.
PO 9 Individual and Team Work: Function effectively as an individual, and as
a member or leader in diverse teams, and in multidisciplinary settings.
PO 10 Communication: Communicate effectively on complex engineering
activities with the engineering community and with society at large, such
as, being able to comprehend and write effective reports and design
documentation, make effective presentations, and give and receive clear
instructions.
PO 11 Project Management and Finance: Demonstrate knowledge and
understanding of the engineering and management principles and apply
these to one’s own work, as a member and leader in a team, to manage
projects and in multidisciplinary environments.
PO 12 Life-long Learning: Recognize the need for, and have the preparation and
ability to engage in independent and life-long learning in the broadest
context of technological change.

PROGRAMSPECIFICOUTCOMES (PSO’ S)

PSO 1 Apply the knowledge of principles of programming languages, data


structures, computer networks and software engineering in modeling of
computer-based application, complex data bases and network protocols.
PSO 2 Identify processes, modules, algorithms and apply standard software
engineering principles to design and develop efficient web based
computational applications under realistic constraints.
PSO 3 Apply theoretical principles of core and advanced computer science to
solve engineering problems
PROGRAM EDUCATIONAL OBJECTIVES

Demonstrate proficiency in fundamental concepts and advanced technologies of computer


PEO 1
science to succeed in their careers and/or obtain a higher degree.

Analyze complex computing problems in multidisciplinary area and creatively solve them
PEO 2
with analytical decision making and programming skills

Recognize ethical dilemmas in work environment and apply professional code of ethics to
PEO 3
excel as successful software professional, researcher and entrepreneur.
SYLLABUS

JAWAHARLAL NEHRU TECHNOLOGICAL UNIVERSITY ANANTAPUR


B.Tech (CSE)– III-II SEM LT PC
(20A05601P) COMPILER DESIGN LAB 0 0 3 1.5
Course Objectives:

To introduce LEX and YACC tools


To learn to develop algorithms to generate code for a target
machine To implement LL and LR parsers

Course Outcomes:
After completion of the course, students will be able to
Design, develop, and implement a compiler for any language
Use LEX and YACC tools for developing a scanner and a
parser Design and implement LL and LR parsers
Design algorithms to perform code optimization in order to improve the performance of
a program in terms of space and time complexity

List of Experiments:

1. Design and implement a lexical analyzer for given language using C and the
lexical analyzer should ignore redundant spaces, tabs and new lines.
2. Implementation of Lexical Analyzer using Lex Tool
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.
c. Implementation of Calculator using LEX and YACC
d. Convert the BNF rules into YACC form and write code to generate abstract
syntax tree
4. Write program to find ε – closure of all states of any given NFA with ε transition.
5. Write program to convert NFA with ε transition to NFA without ε transition.
6. Write program to convert NFA to DFA
7. Write program to minimize any given DFA.
8. Develop an operator precedence parser for a given language.
9. Write program to find Simulate First and Follow of any given grammar.
10. Construct a recursive descent parser for an expression.
11. Construct a Shift Reduce Parser for a given language.
12. Write a program to perform loop unrolling.
13. Write a program to perform constant propagation.
14. Implement Intermediate code generation for simple expressions.
15. Implement SLR (1) Parsing algorithm
16. Design LALR bottom up parser for the given language
RECORD INDEX
S.NO NAME OF THE EXPERIMENT Section – A Section - B
Design and implement a lexical analyzer for given language
1 using C and the lexical analyzer should ignore
redundant spaces, tabs and new lines.
2 Implementation of Lexical Analyzer using Lex Tool
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.

C) Implementation of Calculator using LEX and YACC


D) Convert the BNF rules into YACC form and write code
to generate abstract syntax tree
Write program to find ε – closure of all states of any given
4
NFA with ε transition.
Write program to convert NFA with ε transition to NFA
5
without ε transition.
6 Write program to convert NFA to DFA
7 Write program to minimize any given DFA.
8 Develop an operator precedence parser for a given language.
Write program to find Simulate First and Follow of any given
9
grammar.
10 Construct a recursive descent parser for an expression.
11 Construct a Shift Reduce Parser for a given language.
12 Write a program to perform loop unrolling.
13 Write a program to perform constant propagation.
Implement Intermediate code generation for simple
14
expressions.
CONTENT BEYOND THE EXPERIMENTS
15 Implement SLR (1) Parsing algorithm
16 Design LALR bottom up parser for the given language
1. Design a lexical analyzer for given language and the lexical analyzer should ignore
redundant spaces, tabs and new lines
#include<string.h>

#include<conio.h>

#include<ctype.h>

#include<stdio.h>

void main()

FILE *f1;

char c,str[10];

int lineno=1,num=0,i=0; printf("\

nEnter the c program\n");

f1=fopen("input.txt","w");

while((c=getchar())!=EOF)

putc(c,f1);

fclose(f1);

f1=fopen("input.txt","r");

while((c=getc(f1))!=EOF) // TO READ THE GIVEN FILE

if(isdigit(c)) // TO RECOGNIZE NUMBERS

num=c-48;

c=getc(f1);

while(isdigit(c))

num=num*10+(c-48);
c=getc(f1);

printf("%d is a number \n",num);

ungetc(c,f1);

else if(isalpha(c)) // TO RECOGNIZE KEYWORDS AND IDENTIFIERS

str[i++]=c;

c=getc(f1);

while(isdigit(c)||isalpha(c)||c=='_'||c=='$')

str[i++]=c;

c=getc(f1);

str[i++]='\0'; 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) // TYPE 32 KEYWORDS

printf("%s is a keyword\n",str);

else

printf("%s is a identifier\n",str);

ungetc(c,f1);

i=0;

else if(c==' '||c=='\t') // TO IGNORE THE SPACE


printf("\n");

else if(c=='\n') // TO COUNT LINE NUMBER

lineno++;

else // TO FIND SPECIAL SYMBOL

printf("%c is a special symbol\n",c);

printf("Total no. of lines are: %d\n",lineno);

fclose(f1);

getch();

OUTPUT

Enter the c program

int main()

int

a=10,20;

charch;

float f;

}^Z
2. Implementation of Lexical Analyzer using Lex Tool

AIM:

To write a program for implementing a Lexical analyser using LEX tool

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

/* Number of Character count and number of lines count.*/

%{
#include<stdio.h>
int c=0;
int n1=0;
%}
%%
[a-z,A-Z] {c++;}
\t ;
\n {n1++;}
.;
%%
int yywrap()
{
return 1;
}
int main()
{
printf("enter the
string:"); yylex();
printf("\n Number of words:%d \nNumber of Lines\t%d",c,n1);
}

How to Run A Lex Program :

Save the lex with extension .l then follow the


steps Step 1: Install Flex software

Step 2 : Install Bison Software

Step 3: Install Dev C++ with TDM GCC Setup

Step 4: Set the path in Settings (Click on My Computer/This PC Properties and then Click on Advanced
System Settings and click on Environment Variables then select the path under system variables there add
the Flex and Bison application paths for example if flex and bison installed in C:\GnuWin32\bin and next
the add one more path C:\Dev-Cpp\TDM-GCC-64\bin

Click on OK and close the settings and then open cmd prompt and execute the lex file as shown in output.

OUTPUT :
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.
c. Implementation of Calculator using LEX and YACC
d. Convert the BNF rules into YACC form and write code to generate abstract syntax tree

a. Program to recognize a valid arithmetic expression that uses operator +, – , * and /.

Save the file with name operator.l

%{
#include "operator.tab.h"
%}
%%
[a-zA-Z_][a-zA-Z_0-9]* return id;
[0-9]+(\.[0-9]*)? return num;
[+/*] return op;
. return yytext[0];
\n return 0;
%%
int yywrap()
{
return 1;
}

Save the file with operator.y

%{
#include<stdio.h>
int valid=1;
%}
%token num id op
%%
start :
id'='s';' s: id
x
| num x
|'-' num x
|'(' s ')' x
;
x: op s
|'-' s
|
;
%%
int yyerror()
{
valid=0;
printf("\n Invalid Expression!\n");
return 0;
}

int main()
{
printf("\n Enter the Expression:\n");
yyparse();
if(valid)
{
printf("\n Valid Expression!\n");
}
}

How To Run the Program:

Open the CMD


Prompt Step 1: flex
operator.l
Step 2: bison –d operator.y
Step 3: gcc.lex.cc.y operator.tab.c
Step 4: a.exe

OUTPUT :
b. Program to recognize a valid variable which starts with a letter followed by any
number of letters or digits.

Program var.l

%{
#include"var.tab.h"
%}

%%
[a-zA-Z] {return
ALPHA;} [0-9]+ {return
NUMBER;}
"\n" {return ENTER;}
. {return ER;}
%%
yywrap()
{
}

Program var.y

%{
#include<stdio.h>
#include<stdlib.h>
%}

%token ALPHA NUMBER ENTER ER

%%
var:v ENTER {printf("valid variable\n"); exit(0);}

v: ALPHA exp1
exp1: ALPHA
exp1
|NUMBER exp1
|;

%%

yyerror()
{
printf("Invalid variable\n");
}

main()
{
printf("enter the expression: \n");
yyparse();
}
OUTPUT :
c. Implementation of Calculator using LEX and YACC

Program calculator.l
%{
#include<stdio.h>
#include<math.h>
#include "calculator.tab.h"
%}
%%
[0-9]+ {
yylval.dval=atoi(yytext);
return NUMBER;
}
[t];
n return 0;
. {return yytext[0];}
%%

void yyerror(char *str)


{
printf("\n Invalid Character...");
}
int main()
{
printf("Enter Expression => ");
yyparse();
return(0);
}
void yywrap()
{

Program calculator.y

%{
#include<stdio.h>
int yylex(void);
%}
%union
{
float dval;
}
%token <dval> NUMBER
%left '+''-'
%left '*''/'
%nonassoc UMINUS
%type <dval> exp
%%
state : exp {printf("Answer = %f",$1);}
;
exp : NUMBER
| exp '+' exp{$$=$1+$3;}
| exp '-' exp{$$=$1-$3;}
| exp '*' exp{$$=$1*$3;}
| exp '/' exp{$$=$1/$3;}
| '('exp')'{$$=$2;}
| '-' exp %prec UMINUS{$$=-$2;}
;
%%

OUTPUT :

C:\flex calculator.l C:\


bison –d calculator.y
C:\gcc lex.yy.c calculator.tab.c
C:\a.exe
Enter Expression
: 2*3-5/8
^z
Answer=5.375000
d. Convert the BNF rules into YACC form and write code to generate abstract syntax tree

Program bnf.l

%{
#include"bnf.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;
}
Program bnf.y

%{
#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{
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);
};
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()
{
FILE *fp;
int i;
if(1)
{
fp=fopen("test.c","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++)
{
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);
}
Program test.c

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;
}
}
OUTPUT :
4. Write program to find ε – closure of all states of any given NFA with ε transition.

// Program to find epsilon closure of a given


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.dat","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);
}
}
}
display(i);
rewind(INPUT);
}

return 0;
}

Save the data with file name input.dat

q0 0 q0
q0 1 q1
q0 e q1
q1 1 q2
q1 e q2

OUTPUT :
5. Write program to convert NFA with ε transition to NFA without ε transition.

#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],c,r,buffer[20];
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",&notransition);
printf("NOTE:- [Transition is in the form--> qno alphabet qno]\n",notransition);
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("\n States :" );
for(i=1;i<=nostate;i++)
print_e_closure(i); printf("\
nTnransitions 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)
printf("q%d,",n);
}
printf("}");
}
}
printf("\n Final 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);
}
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;
printf("{");
for(j=0;e_closure[i][j]!=0;j++)
printf("q%d,",e_closure[i][j]);
printf("}\t");
}
OUTPUT :
6. Write program to convert NFA to DFA

#include<stdio.h>
#include<string.h>
#include<math.h>

int ninputs;
int dfa[100][2][100] = {0};
int state[10000] = {0};
char ch[10],
str[1000]; int
go[10000][2] = {0};
int arr[10000] = {0};

int main()
{
int st, fin, in;
int f[10];
int i,j=3,s=0,final=0,flag=0,curr1,curr2,k,l;
int c;

printf("\nFollow the one based indexing\n");

printf("\nEnter the number of states::");


scanf("%d",&st);

printf("\nGive state numbers from 0 to %d",st-1);

for(i=0;i<st;i++)
state[(int)(pow(2,i))] = 1;

printf("\nEnter number of final states\t");


scanf("%d",&fin);

printf("\nEnter final
states::"); for(i=0;i<fin;i++)
{
scanf("%d",&f[i]);
}

int p,q,r,rel;

printf("\nEnter the number of rules according to NFA::");


scanf("%d",&rel);

printf("\n\nDefine transition rule as \"initial state input symbol final state\"\n");


for(i=0; i<rel; i++)
{
scanf("%d%d%d",&p,&q,&r);
if (q==0)
dfa[p][0][r] = 1;
else
dfa[p][1][r] = 1;
}

printf("\nEnter initial state::");


scanf("%d",&in);

in = pow(2,in);

i=0;

printf("\nSolving according to DFA");

int x=0;
for(i=0;i<st;i++)
{
for(j=0;j<2;j++)
{
int stf=0;
for(k=0;k<st;k++)
{
if(dfa[i][j][k]==1)
stf = stf + pow(2,k);
}

go[(int)(pow(2,i))][j] = stf;
printf("%d-%d-->%d\n",(int)(pow(2,i)),j,stf);
if(state[stf]==0)
arr[x++] =
stf; state[stf] = 1;
}

//for new states


for(i=0;i<x;i++)
{
printf("for %d-----",arr[x]);
for(j=0;j<2;j++)
{
int new=0;
for(k=0;k<st;k++)
{
if(arr[i] & (1<<k))
{
int h = pow(2,k);

if(new==0)
new = go[h][j];
new = new | (go[h][j]);

}
}

if(state[new]==0)
{
arr[x++] = new;
state[new] = 1;
}
}
}

printf("\nThe total number of distinct states are::\

n"); printf("STATE 0 1\n");

for(i=0;i<10000;i++)
{
if(state[i]==1)
{
//printf("%d**",i);
int y=0;
if(i==0)
printf("q0 ");

else
for(j=0;j<st;j++)
{
int x =
1<<j;
if(x&i)
{
printf("q%d ",j);
y = y+pow(2,j);
//printf("y=%d ",y);
}
}
//printf("%d",y);
printf(" %d %d",go[y][0],go[y][1]);
printf("\n");
}
}

j=3;
while(j--)
{
printf("\nEnter
string");
scanf("%s",str);
l = strlen(str);
curr1 = in;
flag = 0;
printf("\nString takes the following path-->\
n"); printf("%d-",curr1);

for(i=0;i<l;i++)
{
curr1 = go[curr1][str[i]-'0'];
printf("%d-",curr1);
}

printf("\nFinal state - %d\n",curr1);

for(i=0;i<fin;i++)
{
if(curr1 & (1<<f[i]))
{
flag = 1;
break;
}
}

if(flag)
printf("\nString Accepted");
else
printf("\nString Rejected");

return 0;
}
OUTPUT :
7. Write program to minimize any given DFA.

#include <stdio.h>
#include <string.h>

#define STATES 99
#define SYMBOLS 20

int N_symbols; /* number of input symbols */


int N_DFA_states; /* number of DFA states */
char *DFA_finals; /* final-state string */
int DFAtab[STATES][SYMBOLS];

char StateName[STATES][STATES+1]; /* state-name table */

int N_optDFA_states; /* number of optimized DFA states


*/ 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;

puts("\nDFA: STATE TRANSITION TABLE");

/* input symbols: '0', '1', ...


*/ printf(" | ");
for (i = 0; i < nsymbols; i++) printf(" %c ", '0'+i);

printf("\n- - - -+--");
for (i = 0; i < nsymbols; i++) printf("-- - -");
printf("\n");

for (i = 0; i < nstates; i++) {


printf(" %c | ", 'A'+i); /* state */
for (j = 0; j < nsymbols; j++)
printf(" %c ", tab[i][j]); /* next state
*/ printf("\n");
}
printf("Final states = %s\n", finals);
}

/*
Initialize NFA table.
*/
void load_DFA_table()
{

DFAtab[0][0] = 'B'; DFAtab[0][1] = 'C';


DFAtab[1][0] = 'E'; DFAtab[1][1] = 'F';
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;

for (i = 0; i < strlen(cur_states); i++)


*nextstates++ = dfa[cur_states[i]-'A'][symbol];
*nextstates = '\0';
}

/*
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;

for (i = 0; i < n; i++)


if (strchr(stnt[i], ch)) return i+'0';
return -1; /* next state is NOT defined */
}

/*
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
*/
char is_one_nextstate(char *s)
{
char equiv_class; /* first equiv. class */

while (*s == '@') s++;


equiv_class = *s++; /* index of equiv. class */

while (*s) {
if (*s != '@' && *s != equiv_class) return
0; s++;
}

return equiv_class; /* next state: char type */


}

int state_index(char *state, char stnt[][STATES+1], int n, int


*pn, int cur) /* 'cur' is added only for 'printf()' */
{
int i;
char state_flags[STATES+1]; /* next state info.

*/ if (!*state) return -1; /* no next state */

for (i = 0; i < strlen(state); i++)


state_flags[i] = equiv_class_ndx(state[i], stnt, n);
state_flags[i] = '\0';

printf(" %d:[%s]\t--> [%s] (%s)\n",


cur, stnt[cur], state, state_flags);

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.
*/
int init_equiv_class(char statename[][STATES+1], int n, char *finals)
{
int i, j;

if (strlen(finals) == n) { /* all states are final states */


strcpy(statename[0], finals);
return 1;
}

strcpy(statename[1], finals); /* final state group */

for (i=j=0; i < n; i++) {


if (i == *finals-'A') {
finals++;
} else statename[0][j++] = i+'A';
}
statename[0][j] = '\0';

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];

for (i = 0; i < n; i++) { /* for each pseudo-DFA state */


for (j = 0; j < n_sym; j++) { /* for each input symbol
*/
get_next_state(nextstate, stnt[i], dfa, j);
newdfa[i][j] = state_index(nextstate, stnt, n, &n2, i)+'A';
}
}

return n2;
}

/*
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';
}

void sort(char stnt[][STATES+1], int n)


{
int i, j;
char temp[STATES+1];

for (i = 0; i < n-1; i++)


for (j = i+1; j < n; j+
+)
if (stnt[i][0] > stnt[j][0])
{ strcpy(temp, stnt[i]);
strcpy(stnt[i], stnt[j]);
strcpy(stnt[j], temp);
}
}

/*
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;
char newstates[STATES][STATES+1]; /* max. 'n' subclasses */

for (i=0; i < STATES; i++) newstates[i][0] = '\0';

for (i=0; vec[i]; i++)


chr_append(newstates[vec[i]-'0'],
old[i]);

for (i=0, n2=n; i < n_dfa; i++)


{ if (newstates[i][0]) {
if (!flag) { /* stnt[i1] = s1 */
strcpy(stnt[i1],
newstates[i]);
flag = 1; /* overwrite parent class */
} else /* newstate is appended in 'stnt'
*/ strcpy(stnt[n2++], newstates[i]);
}
}

sort(stnt, n2); /* sort equiv. classes */

return n2; /* number of NEW states(equiv. classes) */


}

/*
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;

for (i = 0; i < n; i++) {


for (j = 0; j < n_sym; j++) {
k = newdfa[i][j]-'A'; /* index of equiv. vector */
if (k >= n) /* equiv. class 'i' should be segmented */
return split_equiv_class(stnt, i, k, n, n_dfa);
}
}

return n;
}

void print_equiv_classes(char stnt[][STATES+1], int n)


{
int i;

printf("\nEQUIV. CLASS CANDIDATE ==>");


for (i = 0; i < n; i++)
printf(" %d:[%s]", i,
stnt[i]); printf("\n");
}

/*
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> */

n = init_equiv_class(stnt, n_dfa, finals);

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!!! */
}

return n; /* number of DFA states */


}

/*
Check if 't' is a subset of 's'.
*/
int is_subset(char *s, char *t)
{
int i;

for (i = 0; *t; i++)


if (!strchr(s, *t++)) return
0; return 1;
}

/*
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;

for (i = 0; i < n; i++)


if (is_subset(oldfinals, stnt[i])) *newfinals++ = i+'A';
*newfinals++ = '\0';
}

void main()
{
load_DFA_table();
print_dfa_table(DFAtab, N_DFA_states, N_symbols, DFA_finals);

N_optDFA_states = optimize_DFA(DFAtab,
N_DFA_states, N_symbols, DFA_finals, StateName,
OptDFA);
get_NEW_finals(NEW_finals, DFA_finals, StateName, N_optDFA_states);

print_dfa_table(OptDFA, N_optDFA_states, N_symbols, NEW_finals);


}
8. Develop an operator precedence parser for a given language.

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
// function f to exit from the loop
// if given condition is not true
void f()
{
printf("Not operator
grammar"); exit(0);
}
void main()
{
char grm[20][20], c;
// Here using flag variable,
// considering grammar is not operator
grammar int i, n, j = 2, flag = 0;
// taking number of productions from
user printf("\n Enter n:");
scanf("%d", &n);
printf("\n Enter Grammer:\
n"); for (i = 0; i < n; i++)
scanf("%s", grm[i]);
for (i = 0; i < n; i++)
{ c = grm[i][2];
while (c != '\0') {
if (grm[i][3] == '+' || grm[i][3] == '-'
|| grm[i][3] == '*' || grm[i][3] == '/')
flag = 1;
else {
flag =
0; f();
}
if (c == '$') {
flag = 0;
f();
}
c = grm[i][++j];
}
}
if (flag == 1)
printf("Operator grammar");
}
OUTPUT :
9. Write program to find Simulate First and Follow of any given grammar.

#include<stdio.h>
#include<string.h>

int i,j,l,m,n=0,o,p,nv,z=0,x=0;
char str[10],temp,temp2[10],temp3[20],*ptr;

struct prod
{
char lhs[10],rhs[10][10],ft[10],fol[10];
int n;
}pro[10];

void findter()
{
int k,t;
for(k=0;k<n;k++)
{
if(temp==pro[k].lhs[0])
{
for(t=0;t<pro[k].n;t++)
{
if( pro[k].rhs[t][0]<65 || pro[k].rhs[t][0]>90 )
pro[i].ft[strlen(pro[i].ft)]=pro[k].rhs[t][0];
else if( pro[k].rhs[t][0]>=65 && pro[k].rhs[t][0]<=90 )
{
temp=pro[k].rhs[t][0];
if(temp=='S')
pro[i].ft[strlen(pro[i].ft)]='#';
findter();
}
}
break;
}
}
}

void findfol()
{
int k,t,p1,o1,chk;
char *ptr1;
for(k=0;k<n;k++)
{
chk=0;
for(t=0;t<pro[k].n;t++)
{
ptr1=strchr(pro[k].rhs[t],temp);
if( ptr1 )
{
p1=ptr1-pro[k].rhs[t];
if(pro[k].rhs[t][p1+1]>=65 && pro[k].rhs[t][p1+1]<=90)
{
for(o1=0;o1<n;o1++)
if(pro[o1].lhs[0]==pro[k].rhs[t][p1+1])
{
strcat(pro[i].fol,pro[o1].ft);
chk++;
}
}
else if(pro[k].rhs[t][p1+1]=='\0')
{
temp=pro[k].lhs[0];
if(pro[l].rhs[j][p]==temp)
continue;
if(temp=='S')
strcat(pro[i].fol,"$");
findfol();
chk++;
}
else
{
pro[i].fol[strlen(pro[i].fol)]=pro[k].rhs[t][p1+1];
chk++;
}
}
}
if(chk>0)
break;
}
}

int main()
{
FILE *f;
//clrscr();

for(i=0;i<10;i++)
pro[i].n=0;

f=fopen("tab5.txt","r");
while(!feof(f))
{
fscanf(f,"%s",pro[n].lhs);
if(n>0)
{
if( strcmp(pro[n].lhs,pro[n-1].lhs) == 0 )
{
pro[n].lhs[0]='\0';
fscanf(f,"%s",pro[n-1].rhs[pro[n-1].n]);
pro[n-1].n++;
continue;
}
}
fscanf(f,"%s",pro[n].rhs[pro[n].n]);
pro[n].n++;
n++;
}

printf("\n\nTHE GRAMMAR IS AS FOLLOWS\n\n");


for(i=0;i<n;i++)
for(j=0;j<pro[i].n;j++)
printf("%s -> %s\n",pro[i].lhs,pro[i].rhs[j]);

pro[0].ft[0]='#';
for(i=0;i<n;i++)
{
for(j=0;j<pro[i].n;j++)
{
if( pro[i].rhs[j][0]<65 || pro[i].rhs[j][0]>90 )
{
pro[i].ft[strlen(pro[i].ft)]=pro[i].rhs[j][0];
}
else if( pro[i].rhs[j][0]>=65 && pro[i].rhs[j][0]<=90 )
{
temp=pro[i].rhs[j][0];
if(temp=='S')
pro[i].ft[strlen(pro[i].ft)]='#';
findter();
}
}
}

printf("\n\nFIRST\n");
for(i=0;i<n;i++)
{
printf("\n%s -> ",pro[i].lhs);
for(j=0;j<strlen(pro[i].ft);j++)
{
for(l=j-1;l>=0;l--)
if(pro[i].ft[l]==pro[i].ft[j])
break
; if(l==-1)
printf("%c",pro[i].ft[j]);
}
}

for(i=0;i<n;i++)
temp2[i]=pro[i].lhs[0];
pro[0].fol[0]='$';
for(i=0;i<n;i++)
{
for(l=0;l<n;l++)
{
for(j=0;j<pro[i].n;j++)
{
ptr=strchr(pro[l].rhs[j],temp2[i]);
if( ptr )
{
p=ptr-pro[l].rhs[j];
if(pro[l].rhs[j][p+1]>=65 && pro[l].rhs[j][p+1]<=90)
{
for(o=0;o<n;o++) if(pro[o].lhs[0]==pro[l].rhs[j]
[p+1])
strcat(pro[i].fol,pro[o].ft);
}
else if(pro[l].rhs[j][p+1]=='\0')
{
temp=pro[l].lhs[0];
if(pro[l].rhs[j][p]==temp)
continue;
if(temp=='S')
strcat(pro[i].fol,"$");
findfol();
}
else
pro[i].fol[strlen(pro[i].fol)]=pro[l].rhs[j][p+1];
}
}
}
}

printf("\n\nFOLLOW\n");
for(i=0;i<n;i++)
{
printf("\n%s -> ",pro[i].lhs);
for(j=0;j<strlen(pro[i].fol);j++)
{
for(l=j-1;l>=0;l--)
if(pro[i].fol[l]==pro[i].fol[j])
break;
if(l==-1)
printf("%c",pro[i].fol[j]);
}
}
printf("\n");
//getch();
}

Save the data with file name tab5.txt

S -> ABE
S -> a
A -> p
A -> t
B -> Aq
S -> f
A -> w

OUTPUT :
10. Construct a recursive descent parser for an expression.

#include <stdio.h>
#include <string.h>

#define SUCCESS 1
#define FAILED 0

int E(), Edash(), T(), Tdash(),

F(); const char *cursor;


char string[64];

int main()
{
puts("Enter the string");
// scanf("%s", string);
sscanf("i+(i+i)*i", "%s",
string); cursor = string;
puts("");
puts("Input Action");
puts("--------------------------------");

if (E() && *cursor == '\0') {


puts("--------------------------------");
puts("String is successfully
parsed"); return 0;
} else
{ puts("--------------------------------");
puts("Error in parsing String");
return 1;

}
}

int E()
{
printf("%-16s E -> T E'\n", cursor);
if (T()) {
if (Edash())
return SUCCESS;
els
e 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);
return SUCCESS;

}
}

int T()
{
printf("%-16s T -> F T'\n", cursor);
if (F()) {
if (Tdash())
return SUCCESS;
els
e 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++;
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 :
11. Construct a Shift Reduce Parser for a given language.

//Including Libraries
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//Global Variables
int z = 0, i = 0, j = 0, c = 0;

// Modify array size to increase


// length of string to be parsed
char a[16], ac[20], stk[15], act[10];

// This Function will check whether


// the stack contain a production rule
// which is to be Reduce.
// Rules can be E->2E2 , E->3E3 , E->4
void check()
{
// Copying string to be printed as action
strcpy(ac,"REDUCE TO E -> ");

// c=length of input string


for(z = 0; z < c; z++)
{
//checking for producing rule E->4
if(stk[z] == '4')
{
printf("%s4", ac);
stk[z] = 'E';
stk[z + 1] = '\0';

//printing action printf("\n$


%s\t%s$\t", stk, a);
}
}

for(z = 0; z < c - 2; z++)


{
//checking for another production
if(stk[z] == '2' && stk[z + 1] == 'E'
&& stk[z + 2] == '2')

{
printf("%s2E2", ac);
stk[z] = 'E';
stk[z + 1] = '\0';
stk[z + 2] = '\0';
printf("\n$%s\t%s$\t", stk, a);
i = i - 2;
}

for(z=0; z<c-2; z++)


{
//checking for E->3E3
if(stk[z] == '3' && stk[z + 1] == 'E'
&& stk[z + 2] == '3')

{
printf("%s3E3", ac);
stk[z]='E';
stk[z + 1]='\0';
stk[z + 1]='\0'; printf("\n$%s\t
%s$\t", stk, a); i = i - 2;
}
}
return ; //return to main
}

//Driver Function
int main()
{
printf("GRAMMAR is -\nE->2E2 \nE->3E3 \nE->4\n");

// a is input string
strcpy(a,"32423");

// strlen(a) will return the length of a to c


c=strlen(a);

// "SHIFT" is copied to act to be


printed strcpy(act,"SHIFT");

// This will print Labels (column


name) printf("\nstack \t input \t
action");

// This will print the initial


// values of stack and input
printf("\n$\t%s$\t", a);

// This will Run upto length of input


string for(i = 0; j < c; i++, j++)
{
// Printing action
printf("%s", act);

// Pushing into stack


stk[i] = a[j];
stk[i + 1] = '\0';

// Moving the pointer


a[j]=' ';

// Printing action printf("\n$


%s\t%s$\t", stk, a);

// Call check function ..which will


// check the stack whether its contain
// any production or not
check();
}

// Rechecking last time if contain


// any valid production then it will
// replace otherwise
invalid check();

// if top of the stack is E(starting symbol)


// then it will accept the input
if(stk[0] == 'E' && stk[1] == '\0')
printf("Accept\n");
else //else reject
printf("Reject\n");
}

OUTPUT ;
12. Write a program to perform loop unrolling.

#include<stdio.h>

#include<conio.h>

void main() {
unsigned int n;
int x;
char ch; 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+
+; if (n & 2)
bits++; if (n &
4) bits++; if (n
& 8) bits++;
n >>=
4; i++;
}
printf("\n no of iterations %d", i);
return bits;
}

OUTPUT :
13. Write a program to perform constant propagation.

Program cons.c

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<conio.h>
void input();
void output();
void change(int p,char *res);
void constant();
struct expr
{
char op[2],op1[5],op2[5],res[5];
int flag;
}arr[10];
int n;

void main()
{
input();
constant();
output();
getch();
}
void input()
{
int i;
printf("\n\nEnter the maximum number of expressions : ");
scanf("%d",&n);
printf("\nEnter the input : \n");
for(i=0;i<n;i++)
{
scanf("%s",arr[i].op);
scanf("%s",arr[i].op1);
scanf("%s",arr[i].op2);
scanf("%s",arr[i].res);
arr[i].flag=0;
}
}
void constant()
{
int i;
int op1,op2,res;
char op,res1[5];
for(i=0;i<n;i++)
{
if(isdigit(arr[i].op1[0]) && isdigit(arr[i].op2[0]) || strcmp(arr[i].op,"=")==0) /*if both digits, store
them in variables*/
{
op1=atoi(arr[i].op1);
op2=atoi(arr[i].op2);
op=arr[i].op[0];
switch(op)
{
case '+':
res=op1+op2;
break;
case '-':
res=op1-op2;
break;
case '*':
res=op1*op2;
break;
case '/':
res=op1/op2;
break;
case '=':
res=op1;
break;
}
sprintf(res1,"%d",res);
arr[i].flag=1; /*eliminate expr and replace any operand below that uses result of this expr */
change(i,res1);
}
}
}
void output()
{
int i=0;
printf("\nOptimized code is : ");
for(i=0;i<n;i++)
{
if(!arr[i].flag)
{
printf("\n%s %s %s %s",arr[i].op,arr[i].op1,arr[i].op2,arr[i].res);
}
}
}
void change(int p,char *res)
{
int i;
for(i=p+1;i<n;i++)
{
if(strcmp(arr[p].res,arr[i].op1)==0)
strcpy(arr[i].op1,res);
else if(strcmp(arr[p].res,arr[i].op2)==0)
strcpy(arr[i].op2,res);
}
}

OUTPUT :
14. Implement Intermediate code generation for simple expressions

#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]==':')
{
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()
{ 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];
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+
+;
}
}

OUTPUT :
15. Implement SLR (1) Parsing algorithm

#include<stdio.h>
#include<string.h>
#include<conio.h>

int i,j,k,m,n=0,o,p,ns=0,tn=0,rr=0,ch=0;
char read[15][10],gl[15],gr[15][10],temp,templ[15],tempr[15][10],*ptr,temp2[5],dfa[15][15];

struct states
{
char lhs[15],rhs[15][10];
int n;
}I[15];

int compstruct(struct states s1,struct states s2)


{
int t; if(s1.n!
=s2.n)
return 0;
if( strcmp(s1.lhs,s2.lhs)!=0 )
return 0;
for(t=0;t<s1.n;t++)
if( strcmp(s1.rhs[t],s2.rhs[t])!=0 )
return 0;
return 1;
}

void moreprod()
{
int r,s,t,l1=0,rr1=0;
char *ptr1,read1[15][10];

for(r=0;r<I[ns].n;r++)
{
ptr1=strchr(I[ns].rhs[l1],'.');
t=ptr1-I[ns].rhs[l1];
if( t+1==strlen(I[ns].rhs[l1]) )
{
l1++;
continue;
}
temp=I[ns].rhs[l1][t+1];
l1++;
for(s=0;s<rr1;s++)
if( temp==read1[s][0] )
break;
if(s==rr1)
{
read1[rr1][0]=temp;
rr1++;
}
else
continue;

for(s=0;s<n;s++)
{
if(gl[s]==temp)
{
I[ns].rhs[I[ns].n][0]='.';
I[ns].rhs[I[ns].n][1]=NULL;
strcat(I[ns].rhs[I[ns].n],gr[s]);
I[ns].lhs[I[ns].n]=gl[s];
I[ns].lhs[I[ns].n+1]=NULL;
I[ns].n++;
}
}
}
}

void canonical(int l)
{
int t1;
char read1[15][10],rr1=0,*ptr1;
for(i=0;i<I[l].n;i++)
{
temp2[0]='.';
ptr1=strchr(I[l].rhs[i],'.');
t1=ptr1-I[l].rhs[i];
if( t1+1==strlen(I[l].rhs[i]) )
continue;

temp2[1]=I[l].rhs[i][t1+1];
temp2[2]=NULL;

for(j=0;j<rr1;j++)
if( strcmp(temp2,read1[j])==0 )
break;
if(j==rr1)
{
strcpy(read1[rr1],temp2);
read1[rr1][2]=NULL; rr1+
+;
}
else
continue;

for(j=0;j<I[0].n;j++)
{
ptr=strstr(I[l].rhs[j],temp2);
if( ptr )
{
templ[tn]=I[l].lhs[j];
templ[tn+1]=NULL;
strcpy(tempr[tn],I[l].rhs[j]); tn+
+;
}
}

for(j=0;j<tn;j++)
{
ptr=strchr(tempr[j],'.');
p=ptr-tempr[j]; tempr[j]
[p]=tempr[j][p+1];
tempr[j][p+1]='.';
I[ns].lhs[I[ns].n]=templ[j];
I[ns].lhs[I[ns].n+1]=NULL;
strcpy(I[ns].rhs[I[ns].n],tempr[j]);
I[ns].n++;
}

moreprod();
for(j=0;j<ns;j++)
{
//if ( memcmp(&I[ns],&I[j],sizeof(struct states))==1 )
if( compstruct(I[ns],I[j])==1 )
{
I[ns].lhs[0]=NULL;
for(k=0;k<I[ns].n;k++)
I[ns].rhs[k][0]=NULL;
I[ns].n=0; dfa[l]
[j]=temp2[1]; break;
}
}
if(j<ns)
{
tn=0;
for(j=0;j<15;j++)
{
templ[j]=NULL;
tempr[j][0]=NULL;
}
continue;
}

dfa[l][j]=temp2[1];
printf("\n\nI%d :",ns);
for(j=0;j<I[ns].n;j++)
printf("\n\t%c -> %s",I[ns].lhs[j],I[ns].rhs[j]);
getch();
ns++;
tn=0;
for(j=0;j<15;j++)
{
templ[j]=NULL;
tempr[j][0]=NULL;
}
}
}

int main()
{
FILE *f;
int l;

for(i=0;i<15;i++)
{
I[i].n=0;
I[i].lhs[0]=NULL;
I[i].rhs[0][0]=NULL; dfa[i]
[0]=NULL;
}

f=fopen("tab6.txt","r");
while(!feof(f))
{
fscanf(f,"%c",&gl[n]);
fscanf(f,"%s\n",gr[n]);
n++;
}

printf("THE GRAMMAR IS AS FOLLOWS\n");


for(i=0;i<n;i++)
printf("\t\t\t\t%c -> %s\n",gl[i],gr[i]);

I[0].lhs[0]='Z';
strcpy(I[0].rhs[0],".S");
I[0].n++;
l=0;
for(i=0;i<n;i++)
{
temp=I[0].rhs[l][1];
l++;
for(j=0;j<rr;j++)
if( temp==read[j][0] )
break;
if(j==rr)
{
read[rr][0]=temp;
rr++;
}
else
continue;
for(j=0;j<n;j++)
{
if(gl[j]==temp)
{
I[0].rhs[I[0].n][0]='.';
strcat(I[0].rhs[I[0].n],gr[j]);
I[0].lhs[I[0].n]=gl[j];
I[0].n++;
}
}
}
ns++;

printf("\nI%d :\n",ns-1);
for(i=0;i<I[0].n;i++)
printf("\t%c -> %s\n",I[0].lhs[i],I[0].rhs[i]);

for(l=0;l<ns;l++)
canonical(l);

printf("\n\n\t\tPRESS ANY KEY FOR DFA TABLE");


getch();

printf("\t\t\tDFA TABLE IS AS FOLLOWS\n\n\n");


for(i=0;i<ns;i++)
{
printf("I%d : ",i);
for(j=0;j<ns;j++)
if(dfa[i][j]!='\0')
printf("'%c'->I%d | ",dfa[i][j],j);
printf("\n\n\n");
}
printf("\n\n\n\t\tPRESS ANY KEY TO EXIT");
getch();
}

SAVE DATA WITH tab6.txt


S -> S+T
S -> T
T -> T*F
T -> F
F ->
(S) F -
>t

OUTPUT :
16. Design LALR bottom up parser for the given language

parser.l
%{
#include<stdio.h>
#include "parser.tab.h"
%}
%%
[0-9]+ {yylval.dval=atof(yytext);
return DIGIT;
}
\n|. return yytext[0];
%%
int yywrap()
{
return 1;
}

parser.y
%{
/*This YACC specification file generates the LALR parser for the program
considered in experiment 4.*/
#include<stdio.h>
%}
%union
{
double dval;
}
%token <dval> DIGIT
%type <dval> expr
%type <dval> term
%type <dval> factor
%%
line: expr '\n' {
printf("%g\n",$1);
}
;
expr: expr '+' term {$$=$1 + $3 ;}
| term
;
term: term '*' factor {$$=$1 * $3 ;}
| factor
;
factor: '(' expr ')' {$$=$2 ;}
| DIGIT
;
%%
int main()
{
yyparse();
}
yyerror(char *s)
{
printf("%s",s);
}

OUTPUT:

You might also like