CD Lab Manual PDF
CD Lab Manual PDF
For
COMPILER DESIGN
Prepared by
DEPARTMENT OF
CERTIFICATE
Department : CSE
Program : B.TECH
Year : III
Semester :I
IQAC Members:
Name(s):
Signature(s):
HOD
INDEX
PROGRAM Page
SNO DESCRIPTION
NO. No.
1 LAB OBJECTIVE
2 UNIVERSITY / JNTU Syllabus
3 List of Programs
4 SCHEDULE/CYCLE CHART
Design a lexical analyzer for given language and
5 1 the lexical analyzer should ignore redundant 1
spaces, tabs and new lines.
6 2 Simulate First and Follow of a Grammar. 6
Develop an operator precedence parser for a
7 3 13
given language.
Construct a recursive descent parser for an
8 4 18
expression.
9 5 Construct a LL(1) parser for an expression. 25
10 6 Design predictive parser for the given language. 32
Implementation of shift reduce parsing
11 7 41
algorithm.
Design a LALR bottom up parser for the given
12 8 45
language.
Implement the lexical analyzer using JLex, flex
13 9 47
or lex or other lexical analyzer generating tools.
14 10 Write a program to perform loop unrolling. 51
Convert the BNF rules into YACC form and
15 11 54
write code to generate abstract syntax tree.
16 12 Write a program for constant propagation. 60
Additional Programs
Write a program to check whether a string
17 13 62
belongs to a grammar or not
Write a program to find out whether given
18 14 66
string is identifier or not
19 APPENDIX
20 REFERENCE
Lab Objective
Co to po mapping:
Aim: Design a lexical analyzer for given language and the lexical analyzer should
ignore redundant spaces, tabs and new lines.
Algorithm:
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);
else
printf("\n%s is an identifier",str);
}
main()
{
FILE *f1,*f2,*f3;
char c,str[10],st1[10];
int num[100],lineno=0,tokenvalue=0,i=0,j=0,k=0;
printf("\nEnter the c program");/*gets(st1);*/
f1=fopen("input","w");
1|Page
while((c=getchar())!=EOF)
putc(c,f1);
fclose(f1);
f1=fopen("input","r");
f2=fopen("identifier","w");
f3=fopen("specialchar","w");
while((c=getc(f1))!=EOF)
{
if(isdigit(c))
{
tokenvalue=c-'0';
c=getc(f1);
while(isdigit(c))
{
tokenvalue*=10+c-'0';
c=getc(f1);
}
num[i++]=tokenvalue;
ungetc(c,f1);
}
else
if(isalpha(c))
{
putc(c,f2);
c=getc(f1);
while(isdigit(c)||isalpha(c)||c=='_'||c=='$')
{
putc(c,f2);
c=getc(f1);
}
putc(' ',f2);
ungetc(c,f1);
}
else
if(c==' '||c=='\t')
printf(" ");
else
if(c=='\n')
lineno++;
else
putc(c,f3);
}
fclose(f2);
2|Page
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);
}
Expected Output:
3|Page
Output :
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,
1. Keywords (eg: int, while),
2. Identifiers (eg: main, total),
3. Constants (eg: 10, 20),
4. Strings (eg: total, hello),
5. Special symbols (eg: (), {}),
6. Operators (eg: +, /,-,*)
4|Page
3.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
7.Keywords in C language?
5|Page
Program2:
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>
6|Page
#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 )
{
7|Page
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)
8|Page
{
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--)
9|Page
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++)
10 | P a g e
{
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();
}
Expected Output :
At
B Aq
S f
Aw
FIRST
S #pta
A pt
B pt
Sf
Aw
FOLLOW
S$
Aptq
B
S
Aptq
$pt
11 | P a g e
Output :
1. First put $ (the end of input marker) in Follow(S) (S is the start symbol)
2. 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).
12 | P a g e
3. If there is a production A aB, then everything in FOLLOW(A) is in
FOLLOW(B)
4. If there is a production A aBb, where FIRST(b) contains , then everything in
FOLLOW(A) is in FOLLOW(B)
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}
4. Find FOLLOW(E) terms for above grammer?
Ans: FOLLOW(E) = {$,)}
13 | P a g e
Program3:
Aim :Develop an operator precedence parser for a given language.
Algorithm :
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",
14 | P a g 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");
}
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=='=')
{
15 | P a g e
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;
16 | P a g e
case ')':return 7;
case '$':return 8;
default :
{
printf("\n ERROR ");
exit(0);
}
}
}
Expected Output:
+ - * / ^ i ( ) $
> > < < < < < > >
> > < < < < < > >
> > > > < < < > >
> > > > < < < > >
> > > > < < < > >
> > > > > e e > >
< < < < < < < = e
> > > > > e e > >
< < < < < <
Output:
17 | P a g e
Viva voice questions :
Ans: Operator grammars have the property that no production right side is empty or
has two adjacent nonterminals.
Ans:
Relation Meaning
For example, the following operator precedence relations canbe introduced for
simple expressions
id + * $
4. The input string: id1 + id2 * id3after inserting precedence relations becomes?
18 | P a g e
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
19 | P a g e
Program4:
Theory:
For factoring:
Give a set of productions of the form
A1|2||n
Invent a new nonterminal Z and replace this set by the collection:
AZ
Z1|2|n
For substitution:
If we are given a grammar containing AB and if all of the productions with B on the
left side are:
B1|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();
20 | P a g 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
{
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';
21 | P a g 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
{
22 | P a g e
op[i+2]=op[i];
i++;
}
while(i < l);
op[n++]='*';
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]=='(')
23 | P a g e
{
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
{
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");
24 | P a g e
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 :
25 | P a g e
Output :
Ans : Recursive descent parsing associates a procedure with each nonterminal in the
grammar, it may require backtracking of the input string.
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.
5. What ate Parsing expressions by recursive descent poses two classic problems?
26 | P a g e
Ans :How to get the abstract syntax tree (or other output) to follow the
precedenceand associativity of operators.
Program5:
Algorithm :
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]);
}
27 | P a g e
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]);
}
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]!='#')
28 | P a g e
{
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]=='#')
{
col=i;
for(m=0;m<strlen(follow[col]);m++)
{
for(l=0;l<noter;l++)
{
if(ter[l]==follow[col][m])
{
row=l;
}
}
29 | P a g e
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]);
30 | P a g e
count[col][row]+=1;}
}
}
}}}}}
}}
printf("LL1 Table\n\n");
flag=0;
for(i=0;i<noter;i++)
{
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:
31 | P a g e
S Sa
A
E Eb
The given grammar is LL1
Output :
1. 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.
2. How to element left factoring for give grammer?
Ans : Consider this following grammar:
S iEtS | iEtSeS | a
Eb
After eliminating left factoring, we have
S iEtSS | a
S eS |
Eb
3. Find first set of terminals for above grammer?
Ans: FIRST(S) = { i, a }
FIRST(S) = {e, }
32 | P a g e
FIRST(E) = { b}
4. Find FOLLOW set of terminals of above grammer?
Ans :FOLLOW(S) = { $ ,e }
FOLLOW(S) = { $ ,e }
FOLLOW(E) = {t}
5. Is the parsing TABLE is given bellow either LL(1) or not?
Ans: NO, Since there are more than one production, the grammar is not LL(1)
grammar.
33 | P a g e
Program6:
Algorithm :
Source code:
#include<stdio.h>
#include<string.h>
# define SIZE 30
char st[100];
int top=-1;
int s1(char),ip(char);
int n1,n2;
char nt[SIZE],t[SIZE];
/*Function to return variable index*/
int s1(char c)
{
int i;
for(i=0;i<n1;i++)
{
if(c==nt[i])
return i;
}
34 | P a g e
}
/*Function to return terminal index*/
int ip(char c)
{
int i;
for(i=0;i<n2;i++)
{
if(c==t[i])
return i;
}
}
void push(char c)
{
top++;
st[top]=c;
return;
}
void pop()
{
top--;
return;
}
main()
{
char table[SIZE][SIZE][10],input[SIZE];
int x,f,s,i,j,u;
printf("Enter the number of variables:");
scanf("%d",&n1);
printf("\nUse single capital letters for variables\n");
for(i=0;i<n1;i++)
{
printf("Enter the %d nonterminal:",i+1);
scanf("%c",&nt[i]);
}
printf("Enter the number of terminals:");
scanf("%d",&n2);
printf("\nUse single small letters for terminals\n");
for(i=0;i<n2;i++)
{
printf("Enter the %d terminal:",i+1);
scanf("%c",&t[i]);
35 | P a g e
}
/*Reading the parsing table*/
printf("Please enter only right sides of productions\n");
printf("Use symbol n to denote no entry and e to epsilon\n");
for(i=0;i<n1;i++)
{
for(j=0;j<n2;j++)
{
printf("\nEnter the entry for %c under %c:",nt[i],t[j]);
scanf("%s",table[i][j]);
}
}
/*Printing the parsing taable*/
for(i=0;i<n2;i++)
printf("\t%c",t[i]);
printf("\n---------------------------------------------------------\n");
for(i=0;i<n1;i++)
{
printf("\n%c|\t",nt[i]);
for(j=0;j<n2;j++)
{
if(!strcmp(table[i][j],"n"))
printf("\t");
else
printf("%s\t",Table[i][j]);
}
printf("\n");
}
printf("Enter the input:");
scanf("%s",input);
/*Initialising the stack*/
top++;
st[top]='$';
top++;
st[top]=nt[0];
printf("STACK content INPUT content PRODUCTION used\n");
printf("--------------------------------------------------------------\n");
i=0;
printf("$%c\t\t\t%s\n\n",st[top],input);
while(st[top]!='$')
{
x=0;
f=s1(st[top]);
36 | P a g e
s=ip(input[i]);
if(!strcmp(table[f][s],"n"))
{
printf("'String not accepted");
}
else
if(!strcmp(table[f][s],"e"))
{
pop();
}
else
if(st[top]==input[i])
{
x=1;
pop();
i++;
}
else
{
pop();
for(j=strlen(table[f][s])-1;j>0;j--)
{
{
push(table[f][s][j]);
}
}
for(u=0;u<=top;u++)
printf("%c",st[u]);
printf("\t\t\t");
for(u=i;input[u]!='\0';u++)
printf("%c",input[u]);
printf("\t\t\t");
if(x==0)
printf("%c->%s\n\n",nt[f],table[f][s]);
printf("'\n\n");
}
printf("\n\nThus string is accepted");
}
}
Expected Output:
38 | P a g e
Enter the entry for F under ): n
Enter the entry for F under i: i
Enter the entry for F under $: n
+ * ( ) i $
-----------------------------------------------------------------------------
E| TA TA
A| +TA e e
T| FB FB
B| e *FB e e
F| (E) i
Enter the input: i+i*i$
39 | P a g e
Output:
40 | P a g e
Viva voice questions :
1. what are steps require to construct predictive parser?
Ans : 1. Elimination of left recursion, left factoring and ambiguous grammar.
41 | P a g e
2. Construct FIRST() and FOLLOW() for all non-terminals.
3. Construct predictive parsing table.
4. Parse the given input string using stack and parsing table.
42 | P a g e
Program7:
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");
43 | P a g e
printf("\n $\t\t%s$\t\t\t--",ip_sym);
strcpy(act,"shift ");
temp[0]=ip_sym[ip_ptr];
temp[1]='\0';
strcat(act,temp);
len=strlen(ip_sym);
for(i=0;i<=len-1;i++)
{
stack[st_ptr]=ip_sym[ip_ptr];
stack[st_ptr+1]='\0';
ip_sym[ip_ptr]=' ';
ip_ptr++;
printf("\n $%s\t\t%s$\t\t\t%s",stack,ip_sym,act);
strcpy(act,"shift ");
temp[0]=ip_sym[ip_ptr];
temp[1]='\0';
strcat(act,temp);
check();
st_ptr++;
}
st_ptr++;
check();
}
void check()
{
int flag=0;
temp2[0]=stack[st_ptr];
temp2[1]='\0';
if((!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")))
{
44 | P a g 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
EE+E
EE/E
EE*E
Ea/b
Enter the input symbol: a+a
Stack implementation table
Stack Input symbol Action
$ a+a$ --
$a +a$ Shift a
$E +a$ Ea
45 | P a g e
$E+ a$ Shift +
$E+a $ Shift a
$E+E $ Ea
$E $ EE*E
$E $ ACCEPT
Output:
46 | 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.
5. What is ACCEPT?
Ans : The parser announces succefully completion parsing.
6. What is error?
Ans : The parser discovers that a syntax error occur and calls error recovery routine.
7. What are the two types of conflicts ?
Ans : 1) shift reduce conflict
2)Reduce reduce conflict
Program 8:
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"},
47 | P a g e
{"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"},
{"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();
48 | P a g e
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]);
}
}
}
49 | 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;
}
50 | P a g e
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)
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)
{
51 | P a g e
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 $
0E1+6F3 $
0E1+6T9 $
0E1 $
accept the input _
52 | P a g e
Output:
53 | P a g e
Program9:
Aim :Implement the lexical analyzer using JLex, flex or lex or other lexical
analyzer generating tools.
Algorithm :
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:
54 | P a g e
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);}
%%
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);
}
55 | P a g e
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
Output:
57 | P a g e
Program10:
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();
}
58 | P a g e
}
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;
}
Expected Output:
Enter a value:5
Loop rolling output:2
Loop unrolling output:2
Output:
59 | P a g e
Viva voice questions :
1.define loop unrolling?
Ans : Loop overhead can be reduced by reducing the number of terations
and replicating the body of the loop.
2.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];
}
60 | P a g e
Program11 :
Aim :Convert the BNF rules into YACC form and write code to generate abstract
Syntax tree.
Algorithm :
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);
61 | P a g e
return NUM;}
\< |
\> |
\>= |
\<= |
== {strcpy(yylval.var,yytext);
Compiler design Lab programs
12
return RELOP;}
[ \t] ;
\n LineNo++;
. return yytext[0];
%%
<int.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 ';'
19
62 | P a g e
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,$$);}
| '-' 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{
63 | P a g e
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;
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");
64 | P a g e
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
65 | 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:
66 | 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
67 | P a g e
Program12:
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
dont 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()
68 | P a g e
{
int a = 30;
int b = 3;
int c;
c = b * 4;
if (c > 10) {
c = c - 10;
}
return c * 2;
}
Expected Output:
Output:
69 | 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
Program13 :
Algorithm :
Step1: Start.
Step2: Declare two character arrays str[],token[] and initialize integer
variables a=0,b=0,c,d. Input the string from the user.
Step3: Repeat steps 5 to 12 till str[a] =\0.
If str[a] =='(' or str[a] =='{' then token[b] =4, b++.
If str[a] ==')' or str[a] =='} then token[b] =5, b++.
Step4: Check if isdigit(str[a]) then repeat steps 8 till isdigit(str[a]) a++.
Step5: a--, token[b] =6, b++.
Step6:If(str[a]=='+) then token[b]='2',b++.
Step7:If(str[a]=='*') then token[b]=3,b++.
a++
token[b]='\0';
then print the token generated for the string .
Step8: b=0.
Repeat step 22 to 31 till token[b]!='\0'
Step9: c=0.
Repeat step 24 to 30 till (token[b]=='6' and token[b+1]=='2' and
70 | P a g e
token[b+2]=='6') or (token[b]=='6' and token[b+1]=='3'and
token[b+2]=='6') or (token[b]=='4' and token[b+1]=='6' and
token[b+2]=='5') or (token[c]!='\0').
token[c]='6';
c++;
step10:Repeat step 27 to 28 till token[c]!='\0'.
token[c]=token[c+2].c++.
Step11:token[c-2]=\0. print token. b++.
Source code :
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<string.h>
void main()
{
int a=0,b=0,c;
char str[20],tok[11]; clrscr();
printf("Input the expression = ");
gets(str);
while(str[a]!='\0')
{
if((str[a]=='(')||(str[a]=='{'))
{
tok[b]='4';
b++;
}
if((str[a]==')')||(str[a]=='}'))
{
tok[b]='5';
b++;
71 | P a g e
}
if(isdigit(str[a]))
{
while(isdigit(str[a]))
{
a++;
}
a--; tok[b]='6';
b++;
}
if(str[a]=='+')
{
tok[b]='2';
b++;
}
if(str[a]=='*')
{
tok[b]='3';
b++;
}
a++;
}
tok[b]='\0';
puts(tok);
b=0;
while(tok[b]!='\0')
{
if(((tok[b]=='6')&&(tok[b+1]=='2')&&(tok[b+2]=='6'))||((tok[b]=='6')&&(tok[b+1
]=='3')&&(tok[b+2]=='6'))||((tok[b]=='4')&&(tok[b+1]=='6')&&(tok[b+2]=='5'))/*||((to
k[b
]!=6)&&(tok[b+1]!='\0'))*/)
{
tok[b]='6';
c=b+1;
while(tok[c]!='\0')
{
tok[c]=tok[c+2];
c++;
}
72 | P a g e
tok[c]='\0';
puts(tok);
b=0;
}
else
{
b++;
puts(tok);
}
}
int d;
d=strcmp(tok,"6");
if(d==0)
{
printf("It is in the grammar.");
}
else
{
printf("It is not in the grammar.");
}
getch();
}
Expected Output:
OUTPUT :
73 | P a g e
Viva voice questions
74 | P a g e
have to choose the option between x86 and x64. So if the program is compiled in x86 and msi
file has been created on x64 will it run on both X64 and x86 or any one of ?
Ans Syntax refers to the structure of a language, tracing its etymology to how things are out
together.
For example you mgiht require the code to be put together by declaring a type then a name and
then a semicolon, to be syntactically correct.
Type token;
On the other hand, the semantics is about meaning. A compiler or interpreter could complain
about syntax errors. Your co-workers will complain about semantics.
Program14:
Aim: Write a program to find out whether given string is identifier or not
Algorithm :
Step1: Start
Step2: Check if the first char is a letter goto step 3 with rest of the string
else goto 5.
Step3: Check if the first character of the given string is a letter or a digit
repeat step 3 with rest of the string else goto step 5.
Step4: print The given string is an identifier and goto step 6.
Step5: Print The given string is not an identifier.
Step6: Exit
Source Code:
75 | P a g e
#include<stdio.h>
#include<conio.h>
int isiden(char*); int
second(char*); int
third();
void main()
{
{
++i;
str[i] = getch(); if(str[i]!=10 &&
str[i]!=13)
printf("%c",str[i]);
if(str[i] == '\b')
{
--i;
printf(" \b");
}
}while(str[i] != 10 && str[i] != 13);
if(isident(str))
else
printf("\n\n\t\tThe given string is not an identifier");
getch();
76 | P a g e
int isident(char *str)
{
}
else
return 0;
second stage
}
else
{
if(str[0] == 10 || str[0] == 13)
{
return(third(str));
}
else
{
return 0;
}
}
}
77 | P a g e
//This function acts as third stage of dfa
int third()
{
return 1; //Being final stage reaching it mean the string is identified
}
EXPECTED OUTPUT:
Enter the desired String: a123
OUTPUT:
78 | P a g e
1)What is an identifier?
Ans : An identifier is used for any variable, function, data definition, etc. In the programming
language C, an identifier is a combination of alphanumeric characters, the first being a letter of
the alphabet or an underline, and the remaining being any letter of the alphabet, any numeric
digit, or the underline
2)What are the rules followed for constructing an identifier?
Rules for constructing identifiers
1. The first character in an identifier must be an alphabet or an underscore and can be followed
only by any number alphabets, or digits or underscores.
2. They must not begin with a digit.
3. Uppercase and lowercase letters are distinct. That is, identifiers are case sensitive.
4. Commas or blank spaces are not allowed within an identifier.
5. Keywords cannot be used as an identifier.
6. Identifiers should not be of length more than 31 characters.
7. Identifiers must be meaningful, short, quickly and easily typed and easily read.
Ans The char keyword can only hold 1 character value at a time. By creating an array of
characters, you can store string values in it. Example: char MyName[50]; declares a string
variable named MyName that can hold a maximum of 50 characters.
Ans No. if command can only be used to compare numerical values and single character
values. For comparing string values, there is another function called strcmp() that deals
specifically with strings.
79 | P a g e