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

Implementation of Shift Reduce Parsing Algorithm: Action

The C program implements a recursive descent parser. It parses context free grammars without last recursion. The main procedures are E(), E'(), T(), T'(), and F() which recursively parse expressions, terms, and factors based on the grammar rules. The program takes an input string, calls the E() procedure, and prints the sequence of production rules used to derive the sentence.

Uploaded by

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

Implementation of Shift Reduce Parsing Algorithm: Action

The C program implements a recursive descent parser. It parses context free grammars without last recursion. The main procedures are E(), E'(), T(), T'(), and F() which recursively parse expressions, terms, and factors based on the grammar rules. The program takes an input string, calls the E() procedure, and prints the sequence of production rules used to derive the sentence.

Uploaded by

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

Ex.

No: 6
Date:

Implementation of Shift Reduce Parsing Algorithm


Aim:
To write a C program to implement the shift-reduce parsing

algorithm. Algorithm:

Grammar:
E->E+E
E->E*E
E->E/E
E->a/b
Method:
Stack Input Symbol Action

$ id1*id2$ shift
$id1 *id2 $ shift *
$* id2$ shift id2
$id2 $ shift
$ $ accept

Shift: Shifts the next input symbol onto the stack.

Reduce: Right end of the string to be reduced must be at the top of


the stack. Accept: Announce successful completion of parsing.

Error: Discovers a syntax error and call an error recovery routine.

28
Program:
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char ip_sym[15],stack[15];
int ip_ptr=0,st_ptr=0,len,i;
char temp[2],temp2[2];
char act[15];
void check();
void main()
{
clrscr();
printf("\n\n\t Shift Reduce Parser\n");
printf("\n\t***** ****** ******");
printf("\n Grammar\n\n");
printf("E->E+E\nE->E/E\n");
printf("E->E*E\nE->a/b");
printf("\n Enter the Input
Symbol:\t"); gets(ip_sym);
printf("\n\n\t Stack Implementation Table");
printf("\n Stack\t\t Input Symbol\t\t Action");
printf("\n $\t\t %s$\t\t\t --",ip_sym);
strcpy(act,"shift");
temp[0]=ip_sym[ip_ptr];
temp[1]='\0';
strcat(act,temp);
len=strlen(ip_sym);
for(i=0;i<=len-1;i++)
{
stack[st_ptr]=ip_sym[ip_ptr];
stack[st_ptr+1]='\0';
ip_sym[ip_ptr]=' ';
ip_ptr++;
printf("\n$%s\t\t%s$\t\t\t%s",stack,ip_sym,act);
strcpy(act,"shift");
temp[0]=ip_sym[ip_ptr];
temp[1]='\0';
strcat(act,temp); check();

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

}
if(!strcmpi(stack,"E")&&ip_ptr==len)
{
printf("\n$%s\t\t%s$\t\t\tAccept",ip_sym);
getch();
exit(0);
}
if(flag==0)
{
printf("\n %s \t\t\t %s \t\t Reject",stack,ip_sym);
}
return;
}
30
Sample Input & Output:
Shift Reduce Parser
***** ****** *****
Grammar

E->E+E
E->E/E
E->E*E
E->a/b

Enter the input symbol: if(a*b)

Stack Implementation Table

Stack Input Symbol Action


$ if(a*b)$ --
$i f(a*b)$ shift i
$if (a*b)$ shift f
$if( a*b)$ shift (
$if(a *b)$ shift a
$if(E *b)$ E->a
$if(E* b)$ shift *
if(E* b) reject

Press any key to continue...

Result:
The above C program was successfully executed and verified.
31
Ex.No: 7
Date:

Implementation of Operator Precedence Parser

Aim:
To write a C program to implement Operator Precedence Parser.

Algorithm:
Input: String of terminals from the operator grammar
Output: Sequence of shift reduce step1

Method:
1- Let the input string to be initially the stack contains, when the reduce
action takes place we have to reach create parent child relationship.

2- See IP to pointer to the first symbol of input string and repeat forever if only
$ is on the input accept and break else begin.

3- Let 'd’ be the top most terminal on the stack and 'b' be current input IF(a<b)
or a=b then Begin push 'b' onto the stack.

4- Advance Input to the stack to the next Input symbol


end;
else if(a>b)
5- Repeat pop the stack until the top most terminal is related by < to the
terminal most recently popped else error value routine
end;

Program:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
char q[9][9]={
{'>','>','<','<','<','<','>','<','>' },
{'>','>','<','<','<','<','>','<','>' },
{'>','>','>','>','<','<','>','<','>' },
{'>','>','>','>','<','<','>','<','>' },
{'>','>','<','<','<','<','>','<','>' },
32
{'<','<','<','<','<','<','=','<','E' },
{'>','>','>','>','>','E','>','E','>' },
{'>','>','>','>','>','E','>','E','>' },
{'<','<','<','<','<','<','E','<','A' }
};
char s[30],st[30],qs[30];
int top=-1,r=-1,p=0; void
push(char a)
{
top++;
st[top]=a;
}
char pop()
{
char a;
a=st[top];
top--;
return a;
}
int find(char a)
{
switch(a)
{
case '+':return 0;
case '-':return 1;
case '*':return 2;
case '/':return 3;
case '^':return 4;
case '(':return 5;
case ')':return 6;
case 'a':return 7;
case '$':return 8;
default :return -1;
}
}
void display(char a)
{
printf("\n Shift %c",a);
}
void display1(char a)
{
if(isalpha(a))
printf("\n Reduce E->%c",a);
else if((a=='+')||(a=='-')||(a=='*')||(a=='/')||(a=='^'))
printf("\n Reduce E->E%cE",a);
else if(a==')')
printf("\n Reduce E->(E)");
33
}
intrel(char a,char b,char d)
{
if(isalpha(a)!=0)
a='a';
if(isalpha(b)!=0)
b='a';
if(q[find(a)][find(b)]==d)
return 1;
else
return 0;
}
void main()
{
char s[100];
int i=-1;
clrscr();
printf("\n\t Operator Preceding Parser\n");
printf("\n Enter the Arithmetic Expression End with $..");
gets(s);
push('$');
while(i)
{
if((s[p]=='$')&&(st[top]=='$'))
{
printf("\n\nAccepted");
break;
}
else if(rel(st[top],s[p],'<')||rel(st[top],s[p],'='))
{
display(s[p]);
push(s[p]);
p++;
}
else if(rel(st[top],s[p],'>'))
{
do
{
r++;
qs[r]=pop();
display1(qs[r]);
}
while(!rel(st[top],qs[r],'<'));
}
}
getch();
}

34
Sample Input & Output:

Enter the Arithmetic Expression End with $: a-(b*c)^d$

Shift a
Reduce E->a
Shift -
Shift (
Shift b
Reduce E->b
Shift *
Shift c
Reduce E->c
Reduce E->E*E
Shift )
Reduce E->(E)
Shift ^
Shift d
Reduce E->d
Reduce E->E^E
Reduce E->E-E
Accepted
Result:
The above C program was successfully executed and verified.

35
Ex.No: 8
Date:

Implementation of Recursive Descent Parser


Aim:
To write a C program to implement Recursive Descent Parser.

Algorithm:
Input: Context Free Grammar without last recursion and an input string
from the grammar.
Output: Sequence of productions rules used to derive the sentence.

Method:
Consider the grammar
E->TE
E'->+TE'/e
T->FT
T->*FT/e
F->(E)/Id

To recursive decent parser for the above grammar is given below

Procedure:
Begin
T()
E_prime();
print E-> TE'
end

procedureeprime():
ifip_sym+='+' then
begin
advance();
T();
eprime();
prime E'-
>TE' end
else
print E'->e
procedure T();
begin
e();

36
Tprime();
print T-
>FT'; end;

procedureTprime();
ifip_sym='*' then
begin
advance();
F();
Tprime()
print T'-
>T*FT' end
else print T'->e

procedure F()
ifip_sym =id
then begin
advance();
print->id
end
else
Error();
end;
else
Error();

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

37
if(ip_sym[ip_ptr]=='+')
{
printf("\n\t\tE'-------
>+TE'"); advance();
t();
e_prime();
}
else printf("\n\t\tE'-----
>e'");
}
void t()
{
printf("\n\t\tT'------->FT'");
f(); t_prime();
}
void t_prime()
{
if(ip_sym[ip_ptr]=='*')
{
printf("\n\t\tT------>*FT'"); advance();
f();
t_prime();
}
else
{
printf("\n\t\tT'----->e");
}
}
void f()
{
if((ip_sym[ip_ptr]=='i')||(ip_sym[ip_ptr]=='j'))
{
printf("\n\t\tF------>i"); advance();
}
else
{
if(ip_sym[ip_ptr]=='(')
{
advance();
e();
if(ip_sym[ip_ptr]==')')
{
advance(); printf("\n\t\tF-
---->(E)");
}

38
else
{
printf("\n\t\tSyntax
Error"); getch();
exit(1);
}
}
}
}
void advance()
{
ip_ptr++;
}
void main()
{
int i;
clrscr();
printf("\n\t\tGRAMMER WITHOUT RECURSION");
printf("\n\t\tE------>TE'\n\t\tE'/e\r\t\tT----->FT");
printf("\n\t\tT------>*FT/e\n\t\tF------>(E)/id");
printf("\n\t\tEnter the Input Symbol: ");
gets(ip_sym);
printf("\n\t\tSequence of Production
Rules"); e();
getch();
}
39
Sample Input & Output:

GRAMMER WITHOUT RECURSION


E------>TE'
T----->FT
T------>*FT/e
F------>(E)/id

Enter the Input Symbol: T

Sequence of Production Rules


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

Result:
The above C program was successfully executed and verified.
40
Ex.No: 9
Date:

Implementation of Code Optimization Techniques

Aim:
To write a C program to implement Code Optimization Techniques.

Algorithm:
Input: Set of ‘L’ values with corresponding ‘R’ values.
Output: Intermediate code & Optimized code after eliminating common
expressions. Program:
#include<stdio.h>
#include<conio.h>
#include<string.h>
struct op
{
char l;
char r[20];
}
op[10],pr[10];
void main()
{
int a,i,k,j,n,z=0,m,q;
char *p,*l;
char temp,t;
char *tem;
clrscr();
printf("Enter the Number of
Values:"); scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("left: ");
op[i].l=getche();
printf("\tright: ");
scanf("%s",op[i].r);
}
printf("Intermediate Code\n")
; for(i=0;i<n;i++)
{
printf("%c=",op[i].l);
printf("%s\n",op[i].r);
}
41
for(i=0;i<n-1;i++)
{
temp=op[i].l;
for(j=0;j<n;j++)
{
p=strchr(op[j].r,temp);
if(p)
{
pr[z].l=op[i].l;
strcpy(pr[z].r,op[i].r);
z++;
}
}
}
pr[z].l=op[n-1].l;
strcpy(pr[z].r,op[n-1].r);
z++;
printf("\nAfter Dead Code
Elimination\n"); for(k=0;k<z;k++)
{
printf("%c\t=",pr[k].l);
printf("%s\n",pr[k].r);
}
for(m=0;m<z;m++)
{
tem=pr[m].r;
for(j=m+1;j<z;j++)
{
p=strstr(tem,pr[j].r);
if(p)
{
t=pr[j].l;
pr[j].l=pr[m].l;
for(i=0;i<z;i++)
{
l=strchr(pr[i].r,t)
; if(l)
{
a=l-pr[i].r;
printf("pos: %d",a);
pr[i].r[a]=pr[m].l;
}
}
}
}
}
42
printf("Eliminate Common Expression\n");
for(i=0;i<z;i++)
{
printf("%c\t=",pr[i].l);
printf("%s\n",pr[i].r);
}
for(i=0;i<z;i++)
{
for(j=i+1;j<z;j++)
{
q=strcmp(pr[i].r,pr[j].r);
if((pr[i].l==pr[j].l)&&!q)
{
pr[i].l='\0';
strcpy(pr[i].r,'\0');
}
}
}
printf("Optimized
Code\n"); for(i=0;i<z;i++)
{
if(pr[i].l!='\0')
{
printf("%c=",pr[i].l);
printf("%s\n",pr[i].r);
}
}
getch();
}
43
Sample Input & Output:
Enter the Number of Values: 5
Left: a right: 9
Left: b right: c+d
Left: e right: c+d
Left: f right: b+e
Left: r right: f

Intermediate Code
a=9
b=c+d
e=c+d
f=b+e
r=:f

After Dead Code Elimination


b =c+d
e =c+d
f =b+e
r =:f

Eliminate Common Expression


b =c+d
b =c+d
f =b+b
r =:f

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

Result:
The above C program was successfully executed and verified.
44
Ex.No: 10
Date:

Implementation of Code Generator


Aim:
To write a C program to implement Simple Code Generator.

Algorithm:
Input: Set of three address code sequence.
Output: Assembly code sequence for three address codes (opd1=opd2, op, opd3).

Method:
1- Start
2- Get address code sequence.
3- Determine current location of 3 using address (for 1st operand).
4- If current location not already exist generate move (B,O).
5- Update address of A(for 2nd operand).
6- If current value of B and () is null,exist.
7- If they generate operator () A,3 ADPR.
8- Store the move instruction in memory 9-
Stop.

Program:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
#include<graphics.h>
typedef struct
{
char var[10];
int alive;
}
regist;
regist preg[10];
void substring(char exp[],int st,int end)
{
int i,j=0;
char dup[10]="";
for(i=st;i<end;i++)
dup[j++]=exp[i];
dup[j]='0';
45
strcpy(exp,dup);
}
int getregister(char var[])
{
int i;
for(i=0;i<10;i++)
{
if(preg[i].alive==0)
{
strcpy(preg[i].var,var);
break;
}
}
return(i);
}
void getvar(char exp[],char v[])
{
int i,j=0;
char var[10]="";
for(i=0;exp[i]!='\0';i++)
if(isalpha(exp[i]))
var[j++]=exp[i];
else
break;
strcpy(v,var);
}
void main()
{
char basic[10][10],var[10][10],fstr[10],op;
int i,j,k,reg,vc,flag=0;
clrscr();
printf("\nEnter the Three Address
Code:\n"); for(i=0;;i++)
{
gets(basic[i]);
if(strcmp(basic[i],"exit")==0)
break;
}
printf("\nThe Equivalent Assembly Code is:\n");
for(j=0;j<i;j++)
{
getvar(basic[j],var[vc++]);
strcpy(fstr,var[vc-1]);
substring(basic[j],strlen(var[vc-
1])+1,strlen(basic[j])); getvar(basic[j],var[vc++]);
reg=getregister(var[vc-1]);
46
if(preg[reg].alive==0)
{
printf("\nMov R%d,%s",reg,var[vc
1]); preg[reg].alive=1;
}
op=basic[j][strlen(var[vc-1])];
substring(basic[j],strlen(var[vc
1])+1,strlen(basic[j])); getvar(basic[j],var[vc++]);
switch(op)
{
case '+': printf("\nAdd"); break;
case '-': printf("\nSub"); break;
case '*': printf("\nMul"); break;
case '/': printf("\nDiv"); break;
}
flag=1;
for(k=0;k<=reg;k++)
{
if(strcmp(preg[k].var,var[vc-1])==0)
{
printf("R%d, R%d",k,reg);
preg[k].alive=0;
flag=0;
break;
}
}
if(flag)
{
printf(" %s,R%d",var[vc-1],reg);
printf("\nMov %s,R%d",fstr,reg);
}
strcpy(preg[reg].var,var[vc
3]); getch();
}
}
47
Sample Input & Output:

Enter the Three Address Code:


a=b+c
c=a*c
exit

The Equivalent Assembly Code is:

Mov R0,b
Add c,R0
Mov a,R0
Mov R1,a
Mul c,R1
Mov c,R1

Result:
The above C program was successfully executed and verified.
48

You might also like