You are on page 1of 59

Institute of

Engineering
&Technology

Approved by AICTE & Permanently Affiliated to JNTUGV, Vizianagaram


(An Autonomous Institution)

LAB RECORD
III B.TECH – II SEM – R20 REGULATION

COMPILER DESIGN Lab

DEPARTMENT OF COMPUTER SCIENCE & INFORMATION TECHNOLOGY


ACADEMIC YEAR 2022-2023

Name:

Roll No:

Branch: Computer Science and Information Technology


LENDI
INSTITUTE OF ENGINEERING & TECHNOLOGY
(Approved by A.I.C.T.E & Affiliated to JNTUGV)
JONNADA, VIZIANAGARAM DIST. -535 005

This is to certify that this is the bonafide record of the work done by

Mr. / Ms. ………………………………… bearing Regd. No…………...……...

in the Compiler Design Laboratory of III Year II Semester of B. Tech Coursein Computer
Science & Information Technology Branch during the Academic Year 2022 – 2023.

Total number of Total number of

Experiments held………………. Experiments held……………….

LAB-IN-CHARGE HEAD OF THE DEPARTMENT

INTERNAL EXAMINER EXTERNAL EXAMINER


Institute of
Engineering
&Technology

Approved by AICTE & Permanently Affiliated to JNTUGV, Vizianagaram


(Autonomous Institution)

INSTITUTE VISION

 Producing globally competent and quality technocrats with human values for the holistic needs of
industry and society.

INSTITUTE MISSION

 Creating an outstanding infrastructure and platform for enhancement of skills, knowledge and
behavior of students towards employment and higher studies.

 Providing a healthy environment for research, development and entrepreneurship, to meet the
expectations of industry and society.

 Transforming the graduates tocontribute tothe socio-economic development and welfare of the society
through value-based education.

DEPARTMENT VISION

 To excel in computing arena and to produce globally competent Computer Science and Information
Technology graduates with Ethical and Human values to serve the society.

DEPARTMENT MISSION

 To impart strong theoretical and practical background in computer science and information
technology discipline with an emphasis on software development.
 To provide an open environment to the students and faculty that promotes professional
growth.
 To inculcate the skills necessary to continue their education and research for contribution to
society.
Institute of
Engineering
&Technology

Approved by AICTE & Permanently Affiliated to JNTUGV, Vizianagaram


(An Autonomous Institution)

PROGRAM SPECIFIC OUTCOMES (PSOs)

PSO 1: Ability to solve contemporary issues utilizing skills.

PSO 2: To acquire the knowledge on latest tools and technologies to provide technical
solutions.

PSO 3 : To qualify in national and international competitive examinations for successful


higher studies and employment.

PROGRAM EDUCATIONAL OBJECTIVES (PEOs)


PEO 1: Graduates of Computer Science and Information Technology will acquire strong knowledge
to analyze, design and develop computing products and solutions for reallife problems
utilizing latest tools, techniques and technologies.

PEO 2: Graduates of Computer Science and Information Technology shall have


interdisciplinary approach, professional attitude and ethics, communication,
teamwork skills and leadership capabilities to solve social issues through their
Employment, Higher Studies and Research.

PEO 3: Graduates will engage in life-long learning and professional development to adapt to
dynamically computing environment.
Institute of
Engineering
&Technology
Approved by AICTE & Permanently Affiliated to JNTUGV, Vizianagaram
(An Autonomous Institution)

PROGRAM OUTCOMES (POs)


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 modelling 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 normsof
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.
INDEX
COMPILER DESIGN LAB MANUAL

EXP DATE Experiment Name Page Grade Sign


NO. No
Design a lexical analyzer
1 for given language and
the lexical analyzer
should ignore redundant
spaces, tabs and new
lines.
2 Simulate First and Follow
of a Grammar.
3 Develop an operator
precedence parser for a
given language.
4 Construct a recursive
descent parser for an
expression.
5 Construct a LL(1) parser
for an expression.
6 Design predictive parser
for the given language.
7 Implementation of shift
reduce parsing
algorithm.
8 Design a LALR bottom
up parser for the given
language.
9 Implement the lexical
analyzer using JLex, flex
or lex or other lexical
analyzer generating tools.
10 Write a program to
perform loop unrolling.
11 Convert the BNF rules
into YACC form and
write code to generate
abstract syntax tree.
12 Write a program for
constant propagation.
Program1:

Aim: Design a lexical analyzer for given language and the lexical analyzer should ignore redundant
spaces, tabs and new lines.

Algorithm:

Step 1: Declare the necessary variables.


Step2:Declare an array and store the keywords in that array
Step 3: Open the input file in read open
Step 4:read the string from the file till the end of file.
Step 4.1:If the first character in the strings # then print that string as header file.
Step 4.2:If the string matches with any of the keywords print That string isa keyword
Step 4.3:If the string matches with operator and special Symbols print the corresponding message
Step 4.4 : If the string is not a keyword then prints that as an identifier.

Source code: #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);
el
se 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))
{
PRAGNATHA (Asst Professor, LIET) 1|P ag e
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);

PRAGNATHA (Asst Professor, LIET) 2|P ag e


}

Expected Output:

Enter the C program a+b*c


Ctrl-D
The no’s in the program are:
The keywords and identifiers are: a is an identifier and terminal
b is an identifier and terminal c is an identifier and terminal Special characters are:
+*
Total no. of lines are: 1

Output :

Viva voice questions:

what is lexical analysis?


Ans : Input to the parser is a stream of tokens, generated by the lexical analyzer.
Type of tokens?
Ans : Token are 5 types

C tokens:
C tokens are the basic buildings blocks in C language which are constructed together to write a C program.
Each and every smallest individual units in a C program are known as C tokens. C tokens are of six types.
They are,
individual units in a C program are known as C tokens. C tokens are of six types. They are,
Keywords (eg: int, while),

PRAGNATHA (Asst Professor, LIET) 3|P ag e


Identifiers (eg: main, total),
Constants (eg: 10, 20),
Strings (eg: “total”, “hello”),
Special symbols (eg: (), {}),
Operators (eg: +, /,-,*)

C tokens example program?


Ans : int main()
{
int x, y, total; x = 10, y = 20;
total = x + y;
Printf (“Total = %d \n”, total);
}
find tokens in the above program main – identifier
{,}, (,) – delimiter int – keyword
x, y, total – identifier
main, {, }, (, ), int, x, y, total – tokens

Real time application C programs for your reference to ? Ans :


1. C program example – Real timeCalculator program
2. C program example – Real time Bank Application program
what are properties Identifiers in C language?

Each program elements in a C program are given a name called identifiers. Names given to identify
Variables, functions and arrays are examples for identifiers. eg. x is a name given to integer variable in
above program.
Rules for constructing identifier name in C?

First character should be an alphabet or underscore.


Succeeding characters might be digits or letter.
Punctuation and special characters aren’t allowed except underscore.
Identifiers should not be keywords.

Keywords in C language?

Keywords are pre-defined words in a C compiler.


Each keyword is meant to perform a specific function in a C program.
Since keywords are referred names for compiler, they can’t be used as variable name.
Example : for,do,while,if,case and etc

PRAGNATHA (Asst Professor, LIET) 4|P ag e


Program 2:

Aim :Simulate First and Follow of a Grammar.

ALGORITHM for first:


Step 1: Start
Step 2: Declare FILE *fp
Step 3: open the file in.txt in write mode Step 4: Read the Productions
Step 5: Compute First function Step 6: stop the procuctions.
Function first:
Step1 : If X is a terminal then First(X) is just X!
Step2: If there is a Production X → ε then add ε to first(X)
Step3: If there is a Production X → Y1Y2..Yk then add first(Y1Y2..Yk) to first(X)
First(Y1Y2..Yk) is either First(Y1) (if First(Y1) doesn't contain ε)OR (if First(Y1) does contain ε) then
First (Y1Y2..Yk) is everything in First(Y1)
<except for ε > as well as everything in First(Y2..Yk) Step4 : If First(Y1) First(Y2)..First(Yk) all
contain ε then add ε to
First(Y1Y2..Yk) as well.

ALGORITHM for follow:


Step 1: Start
Step 2: Declare FILE *fp
Step 3: open the file in.txt in write mode Step 4: Read the follow Productions Step 5: Compute First
function
Step 6: stop the procuctions.

Function Follow :
Step1:First put $ (the end of input marker) in Follow(S) (S is the start symbol)
Step2:If there is a production A → aBb, (where a can be a whole string) then everything in FIRST(b)
except for ε is placed in FOLLOW(B).
Step3:If there is a production A → aB, then everything in FOLLOW(A) is in FOLLOW(B)
Step4 :If there is a production A → aBb, where FIRST(b) contains ε, then everything in FOLLOW(A) is
in FOLLOW(B)
Source code:
#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])
{

PRAGNATHA (Asst Professor, LIET) 5|P ag e


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

PRAGNATHA (Asst Professor, LIET) 6|P ag e


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--)

PRAGNATHA (Asst Professor, LIET) 7|P ag e


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();
}

PRAGNATHA (Asst Professor, LIET) 8|P ag e


Expected Output :
A->t B->Aq S->f A->w FIRST
S->#pta A->pt
B->pt S->f A->w
FOLLOW
S->$ A->ptq B-> S-> A->ptq
->$pt
Output :

Viva voice question :


Rules for First Sets?

Ans 1. If X is a terminal then First(X) is just X!


If there is a Production X → ε then add ε to first(X)
If there is a Production X → Y1Y2..Yk then add first(Y1Y2..Yk) to first(X) 4.First(Y1Y2..Yk) is
either
First(Y1) (if First(Y1) doesn't contain ε)
OR(if First(Y1) does contain ε) then First (Y1Y2..Yk) is everything in First(Y1) <except for ε > as well
as everything in First(Y2..Yk)
first(Y1) First(Y2)..First(Yk) all contain ε then add ε to first(Y1Y2..Yk) as well.

Rules for Follow Sets?

First put $ (the end of input marker) in Follow(S) (S is the start symbol)
If there is a production A → aBb, (where a can be a whole string) then everything in FIRST(b) except
for ε is placed in FOLLOW(B).
If there is a production A → aB, then everything in FOLLOW(A) is in FOLLOW(B)

PRAGNATHA (Asst Professor, LIET) 9|P ag e


If there is a production A → aBb, where FIRST(b) contains ε, then everything in FOLLOW(A) is in
FOLLOW(B)

Find first terms for given grammer?


E → TE'
E' → +TE'
E' → ε T → FT'
T' → *FT'
T' → ε F → (E)
F → id
Ans :

FIRST(E) = {'(',id}
FIRST(E') = {+,ε}FIRST(T) = {'(',id}
FIRSTFOLLOW(E') = {$,)}
FOLLOW(T) = {+,$,)}
FOLLOW(T') = {+,$,)}
FOLLOW(F) = {*,+,$,)}
(T') = {*,ε}
FIRST(F) = {'(',id}
Find FOLLOW(E) terms for above grammer?
Ans: FOLLOW(E) = {$,)}

PRAGNATHA (Asst Professor, LIET) 10 | P a g e


Program 3:
Aim :Develop an operator precedence parser for a given language.

Algorithm :

Step 1: Push # onto stack


Step 2: Read first input symbol and push it onto stack Step 3: Do
Obtain OP relation between the top terminal symbol on the stack and the next input symbol
If the OP relation is < or =
Pop top of the stack into handle, include non-terminalsymbol if appropriate.
Obtain the relation between the top terminal symbol on the stack and the leftmost terminal symbol in the
handle .
While the OP relation between terminal symbols is =o Do Pop top terminal symbol and associated non-
terminal symbol on stack into handle.
Obtain the OP relation between the top terminal symbol on the stack and the leftmost terminal symbol in
the handle.
Match the handle against the RHS of all productions v. Push N onto the stack
Step 4: Until end-of-file and only and N are on the stack

Source code:

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


char stack[20],stack1[20],next,s[10]; int top=-1;
char prod[9][10]={">><<<<<>>",">><<<<<>>",">>>><<<>>", ">>>><<<>>",
">>>><<<>>", ">>>>>ee>>", "<<<<<<<=e", ">>>>>ee>>", "<<<<<<" };
char G[7][6]={
"E->E+E",
" /E-E",
" /E*E",
" /E/E", " /(E)",
" /i "
};
void main()
{
char symbol,G[10][10]; int i=0,flag=0;
int j,k; clrscr();
printf("Grammar\n"); for(j=0;j<7;j++)
{
for(k=0;k<6;k++) printf("%c",G[j][k]); printf("\n");
}
printf("\n\n OPERATOR PRECEDENCE RELATIONS \n");
printf("\n \n"); printf("%c\t%c\t%c\t%c\t%c\t%c\t%c\t%c\t%c\t",'+','-','*','/','^','i','(',')','$'); printf("\n
\n"); for(j=0;j<9;j++)
{
for(k=0;k<10;k++) printf("%c\t",prod[j][k]); printf("\n");
}

PRAGNATHA (Asst Professor, LIET) 11 | P a g e


printf("Enter the string : "); gets(s);
++top; stack[top]='$'; next=s[i]; while(1)
{
if(stack[top]=='$'&& next=='$'||next=='\0') break;
else
{
symbol=prod[f(stack[top])][f(next)]; if(symbol=='<'||symbol=='=')
{
stack[++top]=symbol; stack[++top]=next;
}
else if(symbol=='>')
{
do
{
top--;
}while(stack[top]!='<'); stack[++top]=next; if(next!='$')
{
for(j=0;j<=top;j++) stack1[j]=stack[j]; stack1[j]=symbol;
}
}
else flag=1;
next=s[++i];
}
}
printf("\n STACK : "); for(j=0;j<=top;j++) printf("%c",stack1[j]);
printf("%c",'$'); if(flag==0)
printf("\n\n Accepted"); else
printf("Rejected"); getch();
}
int f(char ch)
{
switch(ch)
{
case '+':return 0;
case '-':return 1;
case '*':return 2;
case '/':return 3;
case '^':return 4;
case 'i':return 5;
case '(':return 6;
case ')':return 7;
case '$':return 8; default :
{
printf("\n ERROR "); exit(0);
}
}
}

PRAGNATHA (Asst Professor, LIET) 12 | P a g e


Expected Output:

+ - * / ^ i ( ) $
> > < < < < < > >
> > < < < < < > >
> > > > < < < > >
> > > > < < < > >
> > > > < < < > >
> > > > > e e > >
< < < < < < < = e
> > > > > e e > >
< < < < < <

Enter the string : i+i*i$ STACK : $(+(*))$


Accepted

Output:

Viva voice questions :

What is user of operator grammer?


Ans : Bottom-up parsers for a large class of context-free grammars can be easily developed using operator
grammars.
What is operator grammer?
Ans: Operator grammars have the property that no production right side is empty or has two adjacent
nonterminals.

PRAGNATHA (Asst Professor, LIET) 13 | P a g e


Precedence relation table ?
Ans:
Relation Meaning

a <· b a yields precedence to b

a =· b a has the same precedence as b

a ·>b a takes precedence over b

For example, the following operator precedence relations canbe introduced for simple expressions

id + * $

id ·> ·> ·>

+ <· ·> <· ·>

* <· ·> ·> ·>

$ <· <· <· ·>

The input string: id1 + id2 * id3after inserting precedence relations becomes?
Ans : $ <· id1 ·> + <· id2·>* <· id3 ·> $
Having precedence relations allows to identify handles as follows?
Ans : - scan the string from left until seeing ·>
scan backwards the string from right to left until seeing <·
everything between the two relations <· and ·> forms the handle
7. Operator Precedence Parsing Algorithm ?
Ans : Initialize: Set ip to point to the first symbol of w$
Repeat: Let X be the top stack symbol, and a the symbol pointed to by ip
if $ is on the top of the stack and ip points to $ then return else
Let a be the top terminal on the stack, and b the symbol pointed to by ip
ifa <· b or a =· b then
push b onto the stack
advance ip to the next input symbol
else if a ·>bthen repeat
pop the stack
until the top stack terminal is related by <· to the terminal most recently popped
else error()
end

PRAGNATHA (Asst Professor, LIET) 14 | P a g e


Program4:

Aim: Construct a recursive descent parser for an expression.

Theory:

For factoring:
Give a set of productions of the form
A-> αβ1|αβ2|…|αβn
Invent a new nonterminal Z and replace this set by the collection:A->αZ
Z-> β1|β2|…βn For substitution:
If we are given a grammar containing A Bα and if all of the productions with B on the left side are:
B-> β1|β2|…βnα

ALGORITHM:

Step 1: start.
Step 2: Declare the prototype functions E() , EP(),T(), TP(),F() Step 3: Read the string to be parsed.
Step 4: Check the productions
Step 5: Compare the terminals and Non-terminals Step 6: Read the parse string.
Step 7: stop the production

Source code: #include<stdio.h> #include<conio.h> #include<string.h> #include<stdlib.h>


#include<ctype.h>
char ip_sym[15],ip_ptr=0,op[50],tmp[50]; void e_prime();
void e();
void t_prime(); void t();
void f();
void advance(); int n=0,flag=1; void e()
{
strcpy(op,"TE'");
printf("E=%-25s",op);
printf("E->TE'\n"); t();
e_prime();
}
void e_prime()
{
int i,n=0,l; for(i=0;i<=strlen(op);i++)
if(op[i]!='e')
tmp[n++]=op[i]; strcpy(op,tmp); l=strlen(op);
for(n=0;n < l && op[n]!='E';n++); if(ip_sym[ip_ptr]=='+')
{
i=n+2;
do
{

PRAGNATHA (Asst Professor, LIET) 15 | P a g e


op[i+2]=op[i]; i++;
}while(i<=l);
op[n++]='+';
op[n++]='T';
op[n++]='E'; op[n++]=39;
printf("E=%-25s",op);
printf("E'->+TE'\n"); advance();
t();
e_prime();
}
else
{
op[n]='e';
for(i=n+1;i<=strlen(op);i++) op[i]=op[i+1];
printf("E=%-25s",op);
printf("E'->e");
}
}
void t()
{
int i,n=0,l; for(i=0;i<=strlen(op);i++) if(op[i]!='e')
tmp[n++]=op[i]; strcpy(op,tmp); l=strlen(op);
for(n=0;n < l && op[n]!='T';n++); i=n+1;
do
{
op[i+2]=op[i]; i++;
}while(i < l);
op[n++]='F';
op[n++]='T'; op[n++]=39;
printf("E=%-25s",op);
printf("T->FT'\n"); f();
t_prime();
}
void t_prime()
{
int i,n=0,l; for(i=0;i<=strlen(op);i++)
if(op[i]!='e')
tmp[n++]=op[i]; strcpy(op,tmp); l=strlen(op);
for(n=0;n < l && op[n]!='T';n++); if(ip_sym[ip_ptr]=='*')
{
i=n+2;
do
{
op[i+2]=op[i]; i++;
}
while(i < l); op[n++]='*';

PRAGNATHA (Asst Professor, LIET) 16 | P a g e


op[n++]='F';
op[n++]='T'; op[n++]=39;
printf("E=%-25s",op);
printf("T'->*FT'\n"); advance();
f();
t_prime();
}
else
{
op[n]='e'; for(i=n+1;i<=strlen(op);i++) op[i]=op[i+1];
printf("E=%-25s",op);
printf("T'->e\n");
}
}

void f()
{
int i,n=0,l; for(i=0;i<=strlen(op);i++)
if(op[i]!='e')
tmp[n++]=op[i]; strcpy(op,tmp); l=strlen(op);
for(n=0;n < l && op[n]!='F';n++); if((ip_sym[ip_ptr]=='i')||(ip_sym[ip_ptr]=='I'))
{
op[n]='i';
printf("E=%-25s",op);
printf("F->i\n"); advance();
}
else
{
if(ip_sym[ip_ptr]=='(')
{
advance(); e();
if(ip_sym[ip_ptr]==')')
{
advance(); i=n+2;
do
{
op[i+2]=op[i]; i++;
}
while(i<=l); op[n++]='(';
op[n++]='E';
op[n++]=')';
printf("E=%-25s",op);
printf("F->(E)\n");
}
}
else
{

PRAGNATHA (Asst Professor, LIET) 17 | P a g e


printf("\n\t syntax error"); flag=0; getch();
exit(1);
}
}
}
void advance()
{
ip_ptr++;
}

void main()
{
int i; clrscr();
printf("\nGrammar without left recursion"); printf("\n\t\t E->TE' \n\t\t E'->+TE'|e \n\t\t T->FT' ");
printf("\n\t\t T'->*FT'|e \n\t\t F->(E)|i");
printf("\n Enter the input expression:"); gets(ip_sym);
printf("Expressions");
printf("\t Sequence of production rules\n"); e();
for(i=0;i < strlen(ip_sym);i++)
{
if(ip_sym[i]!='+'&&ip_sym[i]!='*'&&ip_sym[i]!='('&&
ip_sym[i]!=')'&&ip_sym[i]!='i'&&ip_sym[i]!='I')
{
printf("\nSyntax error"); break;
}
for(i=0;i<=strlen(op);i++) if(op[i]!='e')
tmp[n++]=op[i]; strcpy(op,tmp); printf("\nE=%-25s",op);
}
If(flag==1) Printf(“accepted”); getch();
}

Expected output :

Grammer without left recursion E TE’


E’-> +TE’|e T-> FT’
T’->*FT’|e F->(E)|i
Enter the input expression:i+i*i
Expressions Sequence of production rules
E=TE’ E-> TE’
E=FT’E’ T-> FT’
E=iT’E’ F-> i
E=ieE’ T’->e
E=i+TE’ E’-> +TE’
E=i+FT’E’ T-> FT’
E=i+iT’E’ F-> i
E=i+i*FT’E’ T’->*FT’
E=i+i*iT’E’ F-> i
E=i+i*ieE’ T’->e
PRAGNATHA (Asst Professor, LIET) 18 | P a g e
E=i+i*ie E’->e
E=i+i*I accepted

Output :

Viva voice questions :


what type of parsing it is ?
Ans : it is topdown parser.
what is Recursive descent parser?
Ans : Recursive descent parsing associates a procedure with each nonterminal in the grammar, it may
require backtracking of the input string.
Recursive descent parsing may require backtracking of the input string?
Ans:1) try out all productions, backtrack if necessary.
E.g S->cAd, A->ab | a
input string cad
what is recursive descent parser?
Ans :Itis a kind of top-down parser built from a set of mutually recursive procedures (or a non-recursive
equivalent) where each such procedure usually implements one of the productions of the grammar.
What ate Parsing expressions by recursive descent poses two classic problems?
Ans :How to get the abstract syntax tree (or other output) to follow the precedenceand associativity of
operators.

PRAGNATHA (Asst Professor, LIET) 19 | P a g e


Program5:

Aim : Construct a LL(1) parser for an expression.

Algorithm :

Step1 : If A → α is a production choice, and there is a derivation α ⇒∗


aβ,where a is a token, then we add A → α to the table entry M[A, a].
Step 2 : If A → α is a production choice, and there are derivations α ⇒∗ε andS$ ⇒∗ βAaγ, where S is
the start symbol and a is a token (or $), then we add A → α to the table entry M[A, a]

Source code:

#include<stdio.h> #include<conio.h> void main()


{
char pro[10][10],first[10][10],follow[10][10],nt[10],ter[10],res[10][10][10],temp[10]; int
npro,noter=0,nont=0,i,j,k,flag=0,count[10][10],row,col,l,m,n,index;
clrscr(); for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
count[i][j]=NULL; for(k=0;k<10;k++){ res[i][j][k]=NULL; }
}
}
printf("Enter the no of productions:"); scanf("%d",&npro);
printf("Enter the productions:"); for(i=0;i<npro;i++)
{
scanf("%s",pro[i]);
}
for(i=0;i<npro;i++)
{
flag=0; for(j=0;j<nont;j++)
{
if(nt[j]==pro[i][0])
{
flag=1;
}
}
if(flag==0)
{
nt[nont]=pro[i][0]; nont++;
}
}
printf("\nEnter the first values:\n"); for(i=0;i<nont;i++)
{
printf("First value(%c):",nt[i]);
scanf("%s",first[i]);
PRAGNATHA (Asst Professor, LIET) 20 | P a g e
}
printf("\nEnter the follow values:\n"); for(i=0;i<nont;i++)
{
printf("Follow value(%c):",nt[i]);
scanf("%s",follow[i]);
}
for(i=0;i<nont;i++)
{
flag=0; for(j=0;j<strlen(first[i]);j++)
{
for(k=0;k<noter;k++)
{
if(ter[k]==first[i][j])
{
flag=1;
}
}
if(flag==0)
{
if(first[i][j]!='#')
{
ter[noter]=first[i][j]; noter++;
}
}
}
}
for(i=0;i<nont;i++)
{
flag=0; for(j=0;j<strlen(follow[i]);j++)
{
for(k=0;k<noter;k++)
{
if(ter[k]==follow[i][j])
{
flag=1;
}
}
if(flag==0)
{
ter[noter]=follow[i][j]; noter++;
}
}
}
for(i=0;i<nont;i++)
{
for(j=0;j<strlen(first[i]);j++)
{
flag=0; if(first[i][j]=='#')
PRAGNATHA (Asst Professor, LIET) 21 | P a g e
{
col=i; for(m=0;m<strlen(follow[col]);m++)
{
for(l=0;l<noter;l++)
{
if(ter[l]==follow[col][m])
{
row=l;
}
} temp[0]=nt[col];
temp[1]='-' ;
temp[2]='>';
temp[3]='#';
temp[4]='\0'; printf("temp %s",temp);
strcpy(res[col][row],temp); count[col][row]+=1; for(k=0;k<10;k++){ temp[k]=NULL; }
}

}
else{ for(l=0;l<noter;l++)
{
if(ter[l]==first[i][j])
{
row=l;
}
}
for(k=0;k<npro;k++){ if(nt[i]==pro[k][0])
{
col=i; if((pro[k][3]==first[i][j])&&(pro[k][0]==nt[col]))
{
strcpy(res[col][row],pro[k]); count[col][row]+=1;
}
else
{
if((isupper(pro[k][3]))&&(pro[k][0]==nt[col]))
{
flag=0; for(m=0;m<nont;m++)
{
if(nt[m]==pro[k][3]){index=m;flag=1;}
}
if(flag==1){ for(m=0;m<strlen(first[index]);m++)
{if(first[i][j]==first[index][m])
{strcpy(res[col][row],pro[k]);
count[col][row]+=1;}
}
}
}}}}}
}}
printf("LL1 Table\n\n"); flag=0; for(i=0;i<noter;i++)
PRAGNATHA (Asst Professor, LIET) 22 | P a g e
{
printf("\t%c",ter[i]);
}
for(j=0;j<nont;j++)
{
printf("\n\n%c",nt[j]); for(k=0;k<noter;k++)
{
printf("\t%s",res[j][k]);
if(count[j][k]>1){flag=1;}
}
}
if(flag==1){printf("\nThe given grammar is not LL1");} else{printf("\nThe given grammar is LL1");}
getch();
}

Expected Output:

Enter the productions :S->iEdSA S->a


A->E A-> e E-> b
Enter the first values: First values(s):a i First values(A):$ e First values(E):b

Ener the follow values: Follow values(S):$ e Follow values(A):$ e Follow values(E):t
LL1 Table
a $ b t

S S- > aA
E E->b
The given grammar is LL1

Output :

PRAGNATHA (Asst Professor, LIET) 23 | P a g e


Viva voice questions:

What is LL(1)?
Ans: The parsing table entries are single entries. So each location has not more than one entry.
This type of grammar is called LL(1) grammar.
How to element left factoring for give grammer?
Ans : Consider this following grammar: S → iEtS | iEtSeS | a
E→b
After eliminating left factoring, we have S → iEtSS’ | a
S’→ eS | ε E → b
Find first set of terminals for above grammer?
Ans: FIRST(S) = { i, a }
FIRST(S’) = {e, ε }
FIRST(E) = { b}
Find FOLLOW set of terminals of above grammer?
Ans :FOLLOW(S) = { $ ,e }
FOLLOW(S’) = { $ ,e } FOLLOW(E) = {t}
Is the parsing TABLE is given bellow either LL(1) or not?

PRAGNATHA (Asst Professor, LIET) 24 | P a g e


Ans: NO, Since there are more than one production, the grammar is not LL(1) grammar.

PRAGNATHA (Asst Professor, LIET) 25 | P a g e


Program6:

Aim : Design predictive parser for the given language.

Algorithm :

STEP 1: X symbol on top of stack,a current input symbol


STEP 2: Stack contents and remaining input called parser configuration (initially $S on stack and
complete inputstring)
If X=a=$ halt and announce success
If X=a≠$ pop X off stack advance input to next symbol 2.3.If X is a non-terminal use M[X ,a] which
contains production
STEP 3: X->rhs or error replace X on stack with rhs or call error routine, respectively.
EX: X->UVW replace X with WVU(U on top) output the production (or augment parse tree)

Source code:
#include<stdio.h>
#include<stdlib.h>
int stack[20],top=-1;
void push(int item)
{
if(top>=20)
{
printf("stack overflow");
exit(1);
}
stack[++top]=item;
}
int pop()
{
int ch;
if(top<=-1)
{
printf("stack underflow");
exit(1);
}
ch=stack[top--];
return ch;
}
char convert(int item)
{
char ch;
switch(item)
{
case 0:return'E';
case 1:return'e';
case 2:return'T';
case 3:return't';
PRAGNATHA (Asst Professor, LIET) 26 | P a g e
case 4:return'F';
case 5:return'i';
case 6:return'+';
case 7:return'*';
case 8:return'(';
case 9:return')';
case 10:return'$';
}
}
void main()
{
int m[10][10],i,j,k;
char ips[20];
int ip[10],a,b,t;
m[0][0]=m[0][3]=21;
m[1][1]=621;
m[1][4]=m[1][5]=-2;
m[2][0]=m[2][3]=43;
m[3][1]=m[3][4]=m[3][5]=-2;
m[3][2]=743;
m[4][0]=5;
m[4][3]=809;
printf("enter the input string(end with $):");
scanf("%s",ips);
for(i=0;i,i<ips[i];i++)
{
switch(ips[i])
{
case 'E':k=0;
break;
case 'e':k=1;
break;
case 'T':k=2;
break;
case 't':k=3;
break;
case 'F':k=4;
break;
case 'i':k=5;
break;
case '+':k=6;
break;
case '*':k=7;
break;
case '(':k=8;
break;
case ')':k=9;
break;
PRAGNATHA (Asst Professor, LIET) 27 | P a g e
case '$':k=10;
break;
}
ip[i]=k;
}
ip[i]=-1;
push(10);
push(0);
i=0;
printf("STACK \t INPUT \n");
while(1)
{
//printf("\t");
for(j=0;j<=top;j++)
{
printf("%c",convert(stack[j]));
}
printf("\t");
for(k=i;ip[k]!=-1;k++)
{
printf("%c",convert(ip[k]));
}
printf("\n");
if(stack[top]==ip[i])
{
if(ip[i]==10)
{
printf("\t success");
return;
}
else
{
top--;
i++;
}
}
else if(stack[top]<=4&&stack[top]>=0)
{
a=stack[top];
b=ip[i]-5;
t=m[a][b];
top--;
while(t>0)
{
push(t%10);
t=t/10;
}
}
PRAGNATHA (Asst Professor, LIET) 28 | P a g e
else
{
printf("error");
return;
}
}
}
Output 1:

Output 2:

PRAGNATHA (Asst Professor, LIET) 29 | P a g e


Viva voice questions :
what are steps require to construct predictive parser?
Ans : 1. Elimination of left recursion, left factoring and ambiguous grammar.

Construct FIRST() and FOLLOW() for all non-terminals.


Construct predictive parsing table.
Parse the given input string using stack and parsing table.

2. Step for predictive parser table ?


Ans :
For each production A → α of the grammar, do steps 2 and 3.
For each terminal a in FIRST(α), add A → α to M[A, a].
If ε is in FIRST(α), add A → α to M[A, b] for each terminal b in FOLLOW(A). If ε is in FIRST(α) and
$ is in FOLLOW(A) , add A → α to M[A, $].
Make each undefined entry of M be error.

what sre rule for FOLLOW?


Ans :
If S is a start symbol, then FOLLOW(S) contains $.
If there is a production A → αBβ, then everything in FIRST(β) except ε is placed infollow(B).
If there is a production A → αB, or a production A → αBβ where FIRST(β) contains ε, then everything
in FOLLOW(A) is in FOLLOW(B)
Rules for FIRST?
Ans :1. If X is terminal, then FIRST(X) is {X}.
If X → ε is a production, then add ε to FIRST(X).
If X is non-terminal and X → aα is a production then add a to FIRST(X).

PRAGNATHA (Asst Professor, LIET) 30 | P a g e


Program7:

Aim :Implementation of shift reduce parsing algorithm.

Algorithm :

STEP1: Initial State: the stack consists of the single state, s0; ip points to the first character in w.
STEP 2: For top-of-stack symbol, s, and next input symbol, a case action of T[s,a]
STEP 3: shift x: (x is a STATE number) push a, then x on the top of the stack and advance ip to point to
the next input symbol.
STEP 4: reduce y: (y is a PRODUCTION number) Assume that the production is of the form A ==>
beta pop 2 * |beta| symbols of the stack.
STEP 5: At this point the top of the stack should be a state number, say s’. push A, then goto of T[s’,A]
(a state number) on the top of the stack.

Source code:

#include<stdio.h> #include<stdlib.h> #include<conio.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\t\t SHIFT REDUCE PARSER\n"); printf("\n GRAMMER\n");
printf("\n E->E+E\n E->E/E"); printf("\n E->E*E\n E->a/b"); printf("\n enter the input symbol:\t");
gets(ip_sym);
printf("\n\t stack implementation table"); printf("\n stack\t\t input symbol\t\t action"); printf("\n\t\t
\t\t \n");
printf("\n $\t\t%s$\t\t\t--",ip_sym); strcpy(act,"shift "); temp[0]=ip_sym[ip_ptr]; temp[1]='\0';
strcat(act,temp); len=strlen(ip_sym); for(i=0;i<=len-1;i++)
{
stack[st_ptr]=ip_sym[ip_ptr]; stack[st_ptr+1]='\0'; ip_sym[ip_ptr]=' ';
ip_ptr++;
printf("\n $%s\t\t%s$\t\t\t%s",stack,ip_sym,act); strcpy(act,"shift ");
temp[0]=ip_sym[ip_ptr]; temp[1]='\0'; strcat(act,temp);

check(); st_ptr++;
}
st_ptr++; check();
}
void check()
{

int flag=0; temp2[0]=stack[st_ptr]; temp2[1]='\0';

PRAGNATHA (Asst Professor, LIET) 31 | P a g e


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->b",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); else
if(!strcmpi(stack,"E\E"))
printf("\n $%s\t\t %s$\t\t\tE->E\E",stack,ip_sym); else
printf("\n $%s\t\t%s$\t\t\tE->E*E",stack,ip_sym); flag=1;
}

if(!strcmpi(stack,"E")&&ip_ptr==len)
{
printf("\n $%s\t\t%s$\t\t\tACCEPT",stack,ip_sym); getch();
exit(0);
}
if(flag==0)
{
printf("\n%s\t\t\t%s\t\t reject",stack,ip_sym); exit(0);
}
return;
}

Expected Output:

GRAMMAR E- > E+E


E- > E/E E->E*E E-> a/b
Enter the input symbol: a+a Stack implementation table
Stack Input symbol Action

$ a+a$ --

$a +a$ Shift a

$E +a$ E

PRAGNATHA (Asst Professor, LIET) 32 | P a g e


$E+ a$ Shift +

$E+a $ Shift a

$E+E $ E a

$E $ E E*E

$E $ ACCEPT

Output:

Viva voice questions :

What type parser it is?


Ans: It is BOTTOM-UP PARSING.
What is BOOTOM_UP PARSER?
Ans : Constructing a parse tree for an input string beginning at the leaves and going towards the root is
called bottom-up parsing.
What is SHIFT?
Ans : The shift step refers to the advancement of the input pointer to the next input symbol, which is
called the shifted symbol. This symbol is pushed onto the stack. The shifted symbol is treated as a single
node of the parse tree.
What is REDUCE?
Ans: When the parser finds a complete grammar rule (RHS) and replaces it to (LHS), it is known as
reduce-step. This occurs when the top of the stack contains a handle. To

PRAGNATHA (Asst Professor, LIET) 33 | P a g e


reduce, a POP function is performed on the stack which pops off the handle and replaces it with LHS
non-terminal symbol.
What is ACCEPT?
Ans : The parser announces succefully completion parsing.
What is error?
Ans : The parser discovers that a syntax error occur and calls error recovery routine.
What are the two types of conflicts ?
Ans : 1) shift reduce conflict 2)Reduce reduce conflict

PRAGNATHA (Asst Professor, LIET) 34 | P a g e


Program 8:

Aim :Design a LALR bottom up parser for the given language.

Algorithm :

STEP 1: Represent Ii by its CLOSURE, those items that are either the initial item[S’->.S; eof] or do not
have the . at the left end of the rhs.
STEP 2 : Compute shift, reduce, and goto actions for the state derived from Ii directly from
CLOSURE(Ii)
Source code:
#include<stdio.h> #include<conio.h> #include<stdlib.h> #include<string.h>
void push(char *,int *,char); char stacktop(char *);
void isproduct(char,char); int ister(char);
int isnter(char); int isstate(char); void error();
void isreduce(char,char); char pop(char *,int *);
void printt(char *,int *,char [],int); void rep(char [],int);
struct action
{
char row[6][5];
};
const struct action A[12]={
{"sf","emp","emp","se","emp","emp"},
{"emp","sg","emp","emp","emp","acc"},
{"emp","rc","sh","emp","rc","rc"},
{"emp","re","re","emp","re","re"},
{"sf","emp","emp","se","emp","emp"},
{emp","rg","rg","emp","rg","rg"},
{"sf","emp","emp","se","emp","emp"},
{"sf","emp","emp","se","emp","emp"},
{"emp","sg","emp","emp","sl","emp"},
{"emp","rb","sh","emp","rb","rb"},
{"emp","rb","rd","emp","rd","rd"},
{"emp","rf","rf","emp","rf","rf"}
};
struct gotol
{
char r[3][4];
};

const struct gotol G[12]={


{"b","c","d"},
{"emp","emp","emp"},
{"emp","emp","emp"},
{"emp","emp","emp"},
{"i","c","d"},
{"emp","emp","emp"},
{"emp","j","d"},
PRAGNATHA (Asst Professor, LIET) 35 | P a g e
{"emp","emp","k"},
{"emp","emp","emp"},
{"emp","emp","emp"},
};
char ter[6]={'i','+','*',')','(','$'};
char nter[3]={'E','T','F'};
char states[12]={'a','b','c','d','e','f','g','h','m','j','k','l'}; char stack[100];
int top=-1; char temp[10]; struct grammar
{
char left; char right[5];
};
const struct grammar rl[6]={
{'E',"e+T"},
{'E',"T"},
{'T',"T*F"},
{'T',"F"},
{'F',"(E)"},
{'F',"i"},
};
void main()
{
char inp[80],x,p,dl[80],y,bl='a'; int i=0,j,k,l,n,m,c,len;
clrscr();
printf(" Enter the input :"); scanf("%s",inp); len=strlen(inp); inp[len]='$';
inp[len+1]='\0'; push(stack,&top,bl); printf("\n stack\t\t\t input"); printt(stack,&top,inp,i);
do
{
x=inp[i]; p=stacktop(stack); isproduct(x,p); if(strcmp(temp,"emp")==0) error();
if(strcmp(temp,"acc")==0) break;
else
{
if(temp[0]=='s')
{
push(stack,&top,inp[i]); push(stack,&top,temp[1]); i++;
}
else
{
if(temp[0]=='r')
{
j=isstate(temp[1]); strcpy(temp,rl[j
-
2].right); dl[0]=rl[j-2].left;
dl[1]='\0';
n=strlen(temp); for(k=0;k<2*n;k++) pop(stack,&top); for(m=0;dl[m]!='\0';m++)
push(stack,&top,dl[m]); l=top;
y=stack[l-1]; isreduce(y,dl[0]); for(m=0;temp[m]!='\0';m++) push(stack,&top,temp[m]);
}
}
PRAGNATHA (Asst Professor, LIET) 36 | P a g e
}
printt(stack,&top,inp,i);
}while(inp[i]!='\0'); if(strcmp(temp,"acc")==0) printf("\n accept the input "); else
printf("\n do not accept the input "); getch();
}
void push(char *s,int *sp,char item)
{
if(*sp==100)
printf(" stack is full "); else
{
*sp=*sp+1; s[*sp]=item;
}
}
char stacktop(char *s)
{
char i; i=s[top]; return i;
}
void isproduct(char x,char p)
{
int k,l; k=ister(x); l=isstate(p);
strcpy(temp,A[l-1].row[k-1]);
}
int ister(char x)
{
int i; for(i=0;i<6;i++) if(x==ter[i]) return
i+1;
return 0;
}
int isnter(char x)
{
int i; for(i=0;i<3;i++) if(x==nter[i]) return i+1; return 0;
}
int isstate(char p)
{
int i; for(i=0;i<12;i++) if(p==states[i]) return i+1; return 0;
}
void error()
{
printf(" error in the input "); exit(0);
}
void isreduce(char x,char p)
{
int k,l; k=isstate(x); l=isnter(p);
strcpy(temp,G[k-1].r[l-1]);
}
char pop(char *s,int *sp)
{
char item; if(*sp==-1)
PRAGNATHA (Asst Professor, LIET) 37 | P a g e
printf(" stack is empty "); else
{
item=s[*sp];
*sp=*sp-1;
}
return item;
}
void printt(char *t,int *p,char inp[],int i)
{
int r; printf("\n");
for(r=0;r<=*p;r++) rep(t,r); printf("\t\t\t"); for(r=i;inp[r]!='\0';r++)
printf("%c",inp[r]);
}
void rep(char t[],int r)
{
char c; c=t[r]; switch(c)
{

case 'a':printf("0"); break;


case 'b':printf("1"); break;
case 'c':printf("2"); break;
case 'd':printf("3"); break;
case 'e':printf("4"); break;
case 'f':printf("5"); break;
case 'g':printf("6"); break;
case 'h':printf("7"); break;
case 'm':printf("8"); break;
case 'j':printf("9"); break;
case 'k':printf("10"); break;
case 'l':printf("11"); break;

default
:printf("%c",t[r]); break;
}
}

Expected Output: Enter the input : i+i


Stack input
0 i+i$
0i5 +i$
0F3 +i$
0T2 +i$
0E1 +i$
0E1+6 i$
0E1+6i5 $

PRAGNATHA (Asst Professor, LIET) 38 | P a g e


0E1+6F3 $
0E1+6T9 $
0E1 $

accept the input _


Output

Viva voice questions


What is full form LALR?
Ans: look ahead LR parsre
What is CLOSURE?
Ans :CLOSURE(I) – set of items built from I ◦ (1) initially add every item I to closure(I) ◦
(2) if A->α•Bβ is in CLOSURE(I) and B->γ then add B- >•γ to CLOSURE(I) if not already there
what are two functions used in LALR? Ans: 1. CLOSURE() 2. GOTO()
What are Kernel Items?
Ans : 1)S’->•S
2) all items whose dots are not at the left end
5)what are Non-kernel Items?
Ans : 1)all items with their dots at the left end ◦ 2)Except S’->•S 6)what is an augmented grammar ?
Ans :G - grammar with starting symbol S. G’ – augmented grammar for G, S’- >S

PRAGNATHA (Asst Professor, LIET) 39 | P a g e


Program9:

Aim :Implement the lexical analyzer using JLex, flex or lex or other lexical analyzer generating tools.

Algorithm :

STEP1 : WHILE there is more input

InputChar := GetChar State := Table[0, InputChar]


STEP2 : WHILE State != Blank
InputChar := GetChar
State := Table[State, InputChar] STEP 3: ENDWHILE
STEP 4: Retract STEP 5 : Accept
STEP 6: Return token = (Class, Value) STEP7 :ENDWHILE
Source code:

/* program name is lexp.l */


%{
/* program to recognize a c program */ 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 |
do |
if | break |
continue | void | switch | case | long | struct | const | typedef | return | else |
goto {printf("\n\t%s is a KEYWORD",yytext);} "/*" {COMMENT = 1;}
/*{printf("\n\n\t%s is a COMMENT\n",yytext);}*/ "*/" {COMMENT = 0;}
/* printf("\n\n\t%s is a COMMENT\n",yytext);}*/
{identifier}\( {if(!COMMENT)printf("\n\nFUNCTION\n\t%s",yytext);}
\{ {if(!COMMENT) printf("\n BLOCK BEGINS");}
\} {if(!COMMENT) printf("\n 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\t%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);}
%%

PRAGNATHA (Asst Professor, LIET) 40 | P a g e


int main(int argc,char **argv)
{
if (argc > 1)
{
FILE *file;
file = fopen(argv[1],"r"); if(!file)
{
printf("could not open %s \n",argv[1]); exit(0);
}
yyin = file;
}
yylex(); printf("\n\n"); return 0;
} int yywrap()
{
return 0;
}

Expected Output:

$lex lex.l
$cc lex.yy.c
$./a.out var.c
#include<stdio.h> is a PREPROCESSOR DIRECTIVE FUNCTION
main (
)
BLOCK BEGINS
int is a KEYWORD a IDENTIFIER
b IDENTIFIER BLOCK ENDS

PRAGNATHA (Asst Professor, LIET) 41 | P a g e


Output:

Viva voice questions :

1.what is A lexical analyzer?


Ans: A lexical analyzer breaks an input stream of characters into tokens. Writing lexical analyzers by
hand can be a tedious process, so software tools have been developed to ease this task.

Lex is a lexical analyzer generator for what ?


Ans : the UNIX operating system, targeted to the C programming language.

how many sections a JLex input file is organized? Ans : A JLex input file is organized into three
sections
what are the sections in Jlex?
Ans : 1)user code 2)JLex directives 3)regular expression rules

Define User code?


Ans :User code precedes the first double-percent directive (``%%'). This code is copied verbatim into
the lexical analyzer source file that JLex outputs, at the top of the file. Therefore, if the lexer source file
needs to begin with a package declaration or with the importation of an external class, the user code
section should begin with the corresponding declaration. This declaration will then be copied onto the
top of the generated source file.

Define Jlex directive?


Ans :The JLex directive section begins after the first ``%%'' and continues until the second
``%%'' delimiter. Each JLex directive should be contained on a single line and should begin that line.

PRAGNATHA (Asst Professor, LIET) 42 | P a g e


Program10:

Aim :Write a program to perform loop unrolling.


THEORY:
Loop unrolling transforms a loop into a sequence of statements. It is a parallelizing and optimizing
compiler technique where loop unrolling us used to eliminate loop overhead to test loop control flow
such as loop index values and termination conditions technique was also used to expose instruction-
level parallelism. Syntax tree.

Algorithm :

Step1: start Step2: declare n


Step3: enter n value
Step4: loop rolling display countbit1 or move to next step 5 Step5: loop unrolling display countbit2
Step6:end

Source code:

#include<stdio.h> #include<conio.h> void main()


{ int n;
printf("Enter n value:"); scanf("%d",&n);
printf("loop rolling output:%d\n",countbit1(n)); printf("loop unrolling output:%d\n",countbit2(n));
getch();
}

int countbit1(unsigned int n)


{
int bits = 0; while (n != 0)
{
if (n & 1) bits++; n >>= 1;
}
return bits;
}
int countbit2(unsigned int n)
{
int bits = 0; while (n != 0)
{
if (n & 1) bits++; if (n & 2) bits++; if (n & 4) bits++; if (n & 8) bits++; n >>= 4;
}
return bits;
}

PRAGNATHA (Asst Professor, LIET) 43 | P a g e


Expected Output:

Enter a value:5
Loop rolling output:2 Loop unrolling output:2

Output:

Viva voice questions :


define loop unrolling?
Ans : Loop overhead can be reduced by reducing the number of terations and replicating the body of the
loop.
example of loop unrolling?
Ans 1)an array sum loop 2) a dot product loop3)a row operation loop
3)An Array Sum Loop
Ans :The following C code will compute the sum of the entries in a 100-entry vector A.
double arraySum = 0;
for (int i = 0; i < 100; i++) { arraySum += A[i];
}

PRAGNATHA (Asst Professor, LIET) 44 | P a g e


Program11 :

Aim :Convert the BNF rules into YACC form and write code to generate abstract Syntax tree.

Algorithm :

Step1: To specify the syntax of a language : CFG and BNF Step2: ex: if-else statement in C has the
form of statement →if (
expression )
statement else statement
Step3: An alphabet of a language is a set of symbols.
step4: ex:{0,1} for a binary number system(language)={0,1,100,101,...} Step 5:{a,b,c} for
language={a,b,c, ac,abcc..}
Step6: {if,(,),else ...} for a if statements={if(a==1)goto10, if--}
Step7: A string over an alphabet
is a sequence of zero or more symbols from the alphabet.
Step8: Ex: 0,1,10,00,11,111,0202 ... strings for a alphabet {0,1}
Step9: Null string is a string which does not have any symbol of alphabetLanguage.
o Is a subset of all the strings over a given alphabet.
Step10: Alphabets Ai Languages Li for Ai A0={0,1} L0={0,1,100,101,...}
A1={a,b,c} L1={a,b,c, ac, abcc..}
A2={all of C tokens} L2= {all sentences of C program }

Source code:
<int.l>
%{
#include"y.tab.h"
#include<stdio.h> #include<string.h> int LineNo=1; %} identifier [a-zA-Z][_a-zA-Z0-9]* number [0-
9]+|([0-9]*\.[0-9]+)
%%
main\(\) return MAIN; if return IF; else return ELSE; while return WHILE;
int |
char | float return TYPE; {identifier} {strcpy(yylval.var,yytext); return VAR;} {number}
{strcpy(yylval.var,yytext);
return NUM;}
\< |
\> |
\>= |
\<= |
== {strcpy(yylval.var,yytext); Compiler design Lab programs 12
return RELOP;} [ \t] ;
\n LineNo++;
. return yytext[0];
%%
<int.y>
%{

PRAGNATHA (Asst Professor, LIET) 45 | P a g e


#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 ';' 19
CD LAB PROGRAMS
| 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,$$);}

PRAGNATHA (Asst Professor, LIET) 46 | P a g e


| '-' 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,""); Compiler design Lab
programs
14
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++;
}
;
%%
Compiler design Lab programs 15
extern FILE *yyin;
PRAGNATHA (Asst Professor, LIET) 47 | P a g e
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++)
{
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--]; Compiler design Lab programs 16
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);
}
Input: $vi 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;
}
}

Expected Output:
$lex int.l
$yacc –d int.y
$gcc lex.yy.c y.tab.c –ll –lm
$./a.out test.c

PRAGNATHA (Asst Professor, LIET) 48 | P a g e


Pos Operator Arg 1 Arg 2 Result
0 < a b t0
1 == t0 FALSE 5
2 + a b t1
3 = t1 a
4 GOTO 5
5 < a b t2
6 == t2 FALSE 10
7 + a b t3
8 = t3 a
9 GOTO 5
10 <= a b t4
11 == t4 FALSE 15
12 - a b t5
13 = t5 c
14 GOTO 17
15 + a b t3
16 = t6 c

Output:

PRAGNATHA (Asst Professor, LIET) 49 | P a g e


Viva voice questions:
What is the full form of BNF?
Ans:BNF stands for either Backus-Naur Form or Backus Normal Form
What is struture for BNF?
Ans: the Every rule in Backus-Naur form has the following structure:
$\mathit{name}$ ::= $\mathit{expansion}$
Example of BNF Grammar?
<expr> ::= <term> "+" <expr>
| <term>
<term> ::= <factor> "*" <term>
| <factor>
<factor> ::= "(" <expr> ")"
| <const>
<const> ::= integer
What is the BNF Converter?
The BNF Converter is a compiler construction tool generating a compiler front-end from a Labelled
BNF grammar
What is full form of YACC?
Ans : Yacc: Yet Another Compiler-Compiler

PRAGNATHA (Asst Professor, LIET) 50 | P a g e


Program12:

Aim:Write a program for constant propagation.

THEORY:

The algorithm we shall present basically tries to find for every statement in the program a mapping
between variables, and values of N T 𝖴⊥ { , } . If a variable is mapped to a constant number, that
number is the variables value in that statement on every execution. If a variable is mapped to T (top), its
value in the statement is not known to be constant, and in the variable is mapped to ⊥ (bottom), its value
is not initialized on every execution, or the statement is unreachable. The algorithm for assigning the
mappings to the statements is an iterative algorithm, that traverses the control flow graph of the
algorithm, and updates each mapping according to the mapping of the previous statement, and the
functionality of the statement. The traversal is iterative, because non-trivial programs have circles in
their control flow graphs, and it ends when a “fixed-point” is reached – i.e., further iterations don’t
change the mappings.
ALGORITHM:
Step1: start
Step2: declare a=30,b=3,c
Step3: display result of propagation Step4:end
Source code:

#include<stdio.h> #include<conio.h> void main()


{
printf("result of constant propagation is %d",constantpropagation()); getch();
}

int constantpropagation()

{
int a = 30; int b = 3; int c;

c = b * 4; if (c > 10) {
c = c - 10;
}
return c * 2;
}

Expected Output:

Result of constant propagation is 4

Output:

PRAGNATHA (Asst Professor, LIET) 51 | P a g e


Viva voice questions
What is a compiler?
Ans : a program that translates an executable program in one language into an executable program in
another language
we expect the program produced by the compiler to be better, in some way, than the original.

What is an interpreter?
a program that reads an executable program and produces the results of running that program
usually, this involves executing the source program in some fashion

PRAGNATHA (Asst Professor, LIET) 52 | P a g e


PRAGNATHA (Asst Professor, LIET) 53 | P a g e

You might also like