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

PCC Lab

The document describes an implementation of the SLR(1) parsing algorithm in C++. It includes functions to read in the grammar productions and terminals/non-terminals, find the FIRST and FOLLOW sets, and construct the parsing table. Key functions include read_tnt() to read in terminals and non-terminals, read_prod() to read productions, first_of() to calculate the FIRST set recursively, and follow_of() to calculate the FOLLOW set. The program uses arrays to store the parsing table, grammar symbols, and FIRST/FOLLOW sets.
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)
35 views

PCC Lab

The document describes an implementation of the SLR(1) parsing algorithm in C++. It includes functions to read in the grammar productions and terminals/non-terminals, find the FIRST and FOLLOW sets, and construct the parsing table. Key functions include read_tnt() to read in terminals and non-terminals, read_prod() to read productions, first_of() to calculate the FIRST set recursively, and follow_of() to calculate the FOLLOW set. The program uses arrays to store the parsing table, grammar symbols, and FIRST/FOLLOW sets.
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/ 23

Write a lex program to scan reserved words and identifiers of C language.

%{

#include<stdio.h>;

%}

%%

if|else|while|int|switch|for|char {printf(“keyword”);}

[a-z]([a-z]|[0-9])* {printf(“identifier”);}

[0-9]* {printf(“number”);}

.* {printf(“invalid”);}

%%

main()

yylex();

return 0;

int yywrap()

Sample Output -
else

keyword

humble

identifiers

9876

number
Implementation of Predictive Parsing algorithm

#include<stdio.h>

#include<ctype.h>
#include<string.h>
#include<stdlib.h>
#define SIZE 128
#define NONE -1
#define EOS '\0'
#define NUM 257
#define KEYWORD 258
#define ID 259
#define DONE 260
#define MAX 999
char lexemes[MAX];
char buffer[SIZE];
int lastchar=-1;
int lastentry=0;
int tokenval=DONE;
int lineno=1;
int lookahead;
struct entry
{
char *lexptr;
int token;
}symtable[100];
struct entry
keywords[]={"if",KEYWORD,"else",KEYWORD,"for",KEYWORD,"int",KEYWORD,
"float",KEYWORD,"double",KEYWORD,"char",KEYWORD,"struct",KEYWORD,"ret
urn",KEYWORD,0,0};
void Error_Message(char *m)
{
fprintf(stderr,"line %d, %s \n",lineno,m);
exit(1);
}i
nt look_up(char s[ ])
{
int k;
for(k=lastentry;k>0;k--)
if(strcmp(symtable[k].lexptr,s)==0)
return k;
return 0;
}i
nt insert(char s[ ],int tok)
{
int len;
len=strlen(s);
if(lastentry+1>=MAX)
Error_Message("Symbpl table is full");
if(lastchar+len+1>=MAX)
Error_Message("Lexemes array is full");
lastentry=lastentry+1;
symtable[lastentry].token=tok;
symtable[lastentry].lexptr=&lexemes[lastchar+1];
lastchar=lastchar+len+1;
strcpy(symtable[lastentry].lexptr,s);
return lastentry;
}/
*void Initialize()
{
struct entry *ptr;
for(ptr=keywords;ptr->token;ptr+1)
insert(ptr->lexptr,ptr->token);
}*/
int lexer()
{
int t;
int val,i=0;
while(1)
{
t=getchar();
if(t==' '||t=='\t');
else if(t=='\n')
lineno=lineno+1;
else if(isdigit(t))
{
ungetc(t,stdin);
scanf("%d",&tokenval);
return NUM;
}
else if(isalpha(t))
{
while(isalnum(t))
{
buffer[i]=t;
t=getchar();
i=i+1;
if(i>=SIZE)
Error_Message("Compiler error");
}
buffer[i]=EOS;
if(t!=EOF)
ungetc(t,stdin);
val=look_up(buffer);
if(val==0)
val=insert(buffer,ID);
tokenval=val;
return symtable[val].token;
}
else if(t==EOF)
return DONE;
else
{
tokenval=NONE;
return t;
}
}
}
void Match(int t)
{
if(lookahead==t)
lookahead=lexer();
else
Error_Message("Syntax error");
}
void display(int t,int tval)
{
if(t=='+'||t=='-'||t=='*'||t=='/')
printf("\nArithmetic Operator: %c",t);
else if(t==NUM)
printf("\n Number: %d",tval);
else if(t==ID)
printf("\n Identifier: %s",symtable[tval].lexptr);
else
printf("\n Token %d tokenval %d",t,tokenval);
}
void F()
{
//void E();
switch(lookahead)
{
case '(' : Match('(');
E();
Match(')');
break;
case NUM : display(NUM,tokenval);
Match(NUM);
break;
case ID : display(ID,tokenval);
Match(ID);
break;
default : Error_Message("Syntax error");
}
}
void T()
{
int t;
F();
while(1)
{
switch(lookahead)
{
case '*' : t=lookahead;
Match(lookahead);
F();
display(t,NONE);
continue;
case '/' : t=lookahead;
Match(lookahead);
display(t,NONE);
continue;
default : return;
}
}
}
void E()
{
int t;
T();
while(1)
{
switch(lookahead)
{
case '+' : t=lookahead;
Match(lookahead);
T();
display(t,NONE);
continue;
case '-' : t=lookahead;
Match(lookahead);
T();
display(t,NONE);
continue;
default : return;
}
}
}
void parser()
{
lookahead=lexer();
while(lookahead!=DONE)
{
E();
Match(';');
}
}
main()
{
char ans[10];
printf("\n Program for recursive decent parsing ");
printf("\n Enter the expression ");
printf("And place ; at the end\n");
printf("Press Ctrl-Z to terminate\n");
parser();
}
Output:
Program for recursive decent parsing

Enter the expression And place ; at the end


Press Ctrl-Z to terminate
a+b*c;
Identifier: a
Identifier: b
Identifier: c
Arithmetic Operator: *
Arithmetic Operator: +
2*3;
Number: 2
Number: 3
Arithmetic Operator: *
+3;
line 5,Syntax error
Ctrl-Z
Write a C program to generate Three address code

#include<stdio.h>
#include<string.h>
void pm();
void plus();
void div();
int i,ch,j,l,addr=100;
char ex[10], exp[10] ,exp1[10],exp2[10],id1[5],op[5],id2[5];
void main()
{
clrscr();
while(1)
{
printf("\n1.assignment\n2.arithmetic\n3.relational\n4.Exit\nEnter the choice:");
scanf("%d",&ch);
switch(ch)
{
case 1:
printf("\nEnter the expression with assignment operator:");
scanf("%s",exp);
l=strlen(exp);
exp2[0]='\0';
i=0;
while(exp[i]!='=')
{
i++;
}
strncat(exp2,exp,i);
strrev(exp);
exp1[0]='\0';
strncat(exp1,exp,l-(i+1));
strrev(exp1);
printf("Three address code:\ntemp=%s\n%s=temp\n",exp1,exp2);
break;

case 2:
printf("\nEnter the expression with arithmetic operator:");
scanf("%s",ex);
strcpy(exp,ex);
l=strlen(exp);
exp1[0]='\0';

for(i=0;i<l;i++)
{
if(exp[i]=='+'||exp[i]=='-')
{
if(exp[i+2]=='/'||exp[i+2]=='*')
{
pm();
break;
}
else
{
plus();
break;
}
}
else if(exp[i]=='/'||exp[i]=='*')
{
div();
break;
}
}
break;

case 3:
printf("Enter the expression with relational operator");
scanf("%s%s%s",&id1,&op,&id2);
if(((strcmp(op,"<")==0)||(strcmp(op,">")==0)||(strcmp(op,"<=")==0)||(strcmp(op,">=")==0)||(strcmp(o
p,"==")==0)||(strcmp(op,"!=")==0))==0)
printf("Expression is error");
else
{
printf("\n%d\tif %s%s%s goto %d",addr,id1,op,id2,addr+3);
addr++;
printf("\n%d\t T:=0",addr);
addr++;
printf("\n%d\t goto %d",addr,addr+2);
addr++;
printf("\n%d\t T:=1",addr);
}
break;
case 4:
exit(0);
}
}
}
void pm()
{
strrev(exp);
j=l-i-1;
strncat(exp1,exp,j);
strrev(exp1);
printf("Three address code:\ntemp=%s\ntemp1=%c%ctemp\n",exp1,exp[j+1],exp[j]);
}
void div()
{
strncat(exp1,exp,i+2);
printf("Three address code:\ntemp=%s\ntemp1=temp%c%c\n",exp1,exp[i+2],exp[i+3]);
}
void plus()
{
strncat(exp1,exp,i+2);
printf("Three address code:\ntemp=%s\ntemp1=temp%c%c\n",exp1,exp[i+2],exp[i+3]);
}

Example Generation of Three Address Project Output Result

1. assignment
2. arithmetic
3. relational
4. Exit
Enter the choice:1
Enter the expression with assignment operator:
a=b
Three address code:
temp=b
a=temp

1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:2
Enter the expression with arithmetic operator:
a+b-c
Three address code:
temp=a+b
temp1=temp-c

1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:2
Enter the expression with arithmetic operator:
a-b/c
Three address code:
temp=b/c
temp1=a-temp

1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:2
Enter the expression with arithmetic operator:
a*b-c
Three address code:
temp=a*b
temp1=temp-c

1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:2
Enter the expression with arithmetic operator:a/b*c
Three address code:
temp=a/b
temp1=temp*c
1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:3
Enter the expression with relational operator
a
<=
b

100 if a<=b goto 103


101 T:=0
102 goto 104
103 T:=1

1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:4
Implementation Of SLR(1) Parser algorithm:-
Code:-
#include<stdio.h>
#include<ctype.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream.h>
#define epsilon '^'
char prod[20][20],T[20],NT[20],c[10][10],foll[10][10],fir[10][10];
int tt,tnt,tp,a;
int follow[20][20],first[20][20];
void first_of(char);
int count(int j);
void rhs(int j);
void read_tnt();
int rhs(int j);
void read_tnt()
{ cout<<"For SLR parser: ";
cout<<"\nEnter number of terminals: ";
cin>>tt;
cout<<"\nEnter terminals: ";
for(int i=0;i<tt;i++)
T[i]=getche();
getch();
cout<<"\nEnter number of Non-terminals: ";
cin>>tnt;
cout<<"\nEnter Non-terminals: ";
for(i=0;i<tnt;i++)
NT[i]=getche();
getch(); }
void read_prod()
{ int j;
char x=0;
cout<<"\n\nEnter number of productions: ";
cin>>tp;
cout<<"\n Enter productions: ";
for(int i=0;i<tp;i++)
{ j=x=0;
while(x!='\r')
{ prod[i][j]=x=getche();
j++; }
cout<<"\n"; }
getch(); }
return(i);
if(t=='$')
return(tt);
return(-1); }
int terminal(char x)
{ for(int i=0;i<tt;i++)
if(T[i]==x)
return(1);
return(0); }
int nonterminal(char x)
{ for(int i=0;i<tnt;i++)
if(NT[i]==x)
return(1);
return(0); }
int in_rhs(char *s,char x)
{ for(int i=0;i<=strlen(s);i++)
if(*(s+i)==x)
return(i);
return(-1); }
void find_first()
{ for(int i=0;i<tnt;i++)
first_of(NT[i]); }
void first_of(char n)
{ int t1,t2,p1,cnt=0,i,j;
char x;
static int over[20];
p1=t_no(epsilon);
if(terminal(n))
return;
t1=nt_no(n);
if(over[t1])
return;
over[t1]=1;
for(i=0;i<tp;i++)
{ t1=nt_no(prod[i][0]);
if(prod[i][0]==n)
{ int k=0;
cnt=count(1);
rhs(i);
while(k<cnt)
{ x=c[i][k];
if(terminal(x))
{ t2=t_no(x);
first[t1][t2]=1;
break; }
else
{ t2=nt_no(x);
first_of(x);
for(int j=0;j<tt;j++)
first[t1][p1]=1; } } }
void follow_of(char n)
{ int f,t1,t2,p1,t,cnt=0;
char x,beta;
static int over[20];
p1=t_no(epsilon);
t1=nt_no(n);
if(over[t1])
return;
over[t1]=1;
if(NT[0]==n)
follow[nt_no(NT[0])][tt]=1;
for(int i=0;i<tp;i++)
{ rhs(i);
cnt=count(i);
t=in_rhs(c[i],n);
int bno;
for(int j=0;j<tt;j++)
{
bno=nt_no(beta);
if((first[bno][j]) && (j!=p1))
follow[t1][j]=1; }
if((p1!=-1) && (first[bno][p1]==1))
continue;
else if((t==(cnt-1)||(k>=cnt)))
{ follow_of(prod[i][0]);
t1=nt_no(prod[i][0]);
for(int l=0;l<=tt+1;l++)
if(follow[t][l])
follow[t1][l]=1; } } }
}

int count(int j)
{ int c1=0;
for(int q=3;prod[j][q]!='\r';q++)
c1++;
return(c1); }
void show_follow()
{ int b=0;
a=0;
cout<<"\n\n Follow Table For Grammar: \n";
for(int i=0;i<tnt;i++)
{
b=0;
cout<<"\n FOLLOW ("<<NT[i]<<" )= { ";
for(int j=0;j<tt+1;j++)
if(follow[i][j] && j!=tt)
{ foll[a][b]=T[j];
b++;
cout<<T[j]<<" "; }
else
if(j==tt)
{ foll[a][b]='$';
b++;
cout<<'$'; }
a++;
cout<<" } "; }
getch(); }
void show_first()
{ int b=0;
a=0;
cout<<"\n\n First Table For Grammar: \n";
for(int i=0;i<tnt;i++)
{ b=0;
cout<<"\n FIRST ("<<NT[i]<<" )= { ";
for(int j=0;j<tt+1;j++)
if(first[i][j] && j!=tt)
{ fir[a][b]=T[j];
b++;
cout<<T[j]<<" "; }
a++;
cout<<" } "; }
getch()}}}}

To construct parse table:

#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#include<iostream.h>
#include"c:\tc\bin\SLR.h"

int S=0,i=0,j=0,state[20];
char TNT[15];
struct node
{ int pno,dpos; };
struct t
{ char s;
int n; };
struct t1
{ struct t lr[10];
int gr[5]; };
struct t1 action[15];
struct node closure[10][10];
int g[15][10];
int l;
void sclosure(int,int);
int added(int);
int t_into(char);
void print_table(int);
void parser(void);
void find_closure(int,int);
void SLR(void);
void main()
{ clrscr();
mainf();
getch();
for(int i=0;i<tnt;i++)
TNT[i]=NT[i];
for(int j=0;j<tt;j++)
{ TNT[i]=T[j];
i++; }
strcat(T,"$");
i=j=0;
SLR();
print_table(S);
getch(); }
void SLR()
{ int clno,no=0,x,y,z,len,cnt=-1,d=0;
closure[i][j].pno=0;
closure[i][j++].dpos=3;
find_closure(no,3);
sclosure(i,j);
state[i]=j;
S=0;
do
{ cnt++;
z=state[cnt];
for(int k=0;k<tnt+tt;k++)
{ i++;
j=0;d=0;
for(int l=0;l<z;l++)
{ x=closure[cnt][1].pno;
y=closure[cnt][1].dpos;
if(prod[x][y]==TNT[k])
{ d=1;
closure[i][j].pno=x;
closure[i][j++].dpos=++y;
if((y<strlen(prod[x])) && (isupper(prod[x][y])))
find_closure(x,y); } }
if(d==0)
{ i--;
continue; }
sclosure(i,j);
else
{ action[cnt].lr[k-tnt].s='S';
action[cnt].lr[k-tnt].n=clno;
}
if(added(i-1)!=-1)
i--;
else
{ S++;
for(l=0;l<state[i];l++)
{ if(closure[i][1].pno==0)
{ action[i].lr[tt].s='A';
continue; }
len=(strlen(prod[closure[i][l].pno])-1);
if(len==closure[i][l].dpos)
{ char v=prod[closure[i][l].pno][0];
int u=nt_no(v);
for(x=0;x<strlen(foll[u]);x++)
{ int w=t_ino(foll[u][x]);
action[i].lr[w].s='R';
action[i].lr[w].n=closure[i][l].pno;}}}}}}
while(cnt!=S); }
void print_table(int states)
{ int lin=5;
cout<<"\n\n Parser Table: \n";
for(int i=0;i<tt;i++)
cout<<"\t"<<T[i];
cout<<"\t$";
for(i=0;i<tnt;i++)
cout<<"\t"<<NT[i];
cout<<"\n______________________________________________________________\n";
for(i=0;i<=states;i++)
{ gotoxy(l,lin);
cout<<"I"<<i<<"\t";
for(int j=0;j<=tt;j++)
{ if(action[i].lr[j].s!='\x0')
{ if(action[i].lr[j].s=='A')
{ cout<<"Acc";
continue; }
else
cout<<"\t"; }
for(j=0;j<tnt;j++)
if(action[i].gr[j])
{ cout<<action[i].gr[j];
cout<<"\t"; }
else
cout<<"\t";
lin++;
cout<<"\n"; }
cout<<"\n______________________________________________________"; }
void sclosure(int clno,int prodno)
{ struct node temp;
for(int i=0;i<prodno-1;i++)
{ for(int j=i+1;j<prodno;j++)
{ if(closure[clno][i].pno>closure[clno][j].pno)
{ temp=closure[clno][i];
closure[clno][i]=closure[clno][j];
closure[clno][j]=temp; }}}
for(i=0;i<prodno-1;i++)
{for(j=i+1;j<prodno;j++)
{if((closure[clno][i].dpos>closure[clno][j].dpos) &&
(closure[clno][i].pno==closure[clno][j].pno))
{ temp=closure[clno][i];
closure[clno][i]=closure[clno][j];
closure[clno][j]=temp;}}}}
int added(int n)
{ int d=1;
for(int k=0;k<=n;k++)
{if(state[k]==state[n+1])
{ d=0;
return(k); } }
return(-1); }
void find_closure(int no,int dp)
{ int k;
char temp[5];
if(isupper(prod[no][dp]))
{for(k=0;k<tp;k++)
{if(prod[k][0]==prod[no][dp])
{ int t_ino(char t)
{ for(int i=0;i<=tt;i++)
if(T[i]==t)
return(i);
return(-1); }
char pops2;
struct node1
{ char s2;int s1; };
struct node1 stack[10];
int pops1,top=0;
void parser(void)
{ int r,c;
struct t lr[10];
char t,acc='f',str[10];
cout<<"Enter I/p String To Parse: ";
cin>>str;
strcat(str,"$");
stack[0].s1=0;
stack[0].s2='\n';
cout<<"\n\n STACK";
cout<<"\t\t INPUT";
cout<<"\t\t ACTION";
for(int j=0;j<strlen(str);j++)
cout<<str[j];
do
{r=stack[top].s1;
c=find_index(str[i]);
if(c==-1)
cout<<"\n Error! Invalid String!";
return; }
while(top!=0);
switch(action[r],lr[c].s)
{case 'S': { push(str[i],action[r].lr[c].n);
i++;
cout<<"\t\t\t Shift";
break; }
case 'R': { t=prod[action[r].lr[c].n][3];
do { pop(); }
while(pops2!=t);
t=prod[action[r].lr[c].n][0];
r=stack[top].s1;
c=find_index(t);
push(t,action[r].gr[c-tt-1]);
cout<<"\t\t\t Reduce";
break;}
case 'A':{ cout<<"\t\t\t Accept";
cout<<"\n\n\n String accepted";
acc='t';
getch();
return; }
default: { cout<<"\n\n\n Error! String not accepted!";
getch();
exit(0);}}
for(j=0;j<=top;j++)
cout<<stack[j].s2<<stack[j].s1;
if(top<4)
cout<<"\t\t\t";
else
cout<<"\t\t";
for(j=i;j<strlen(str);j++)
cout<<str[j];
if(acc=='t')
return; }
int find_index(char temp)
{for(int i=0;i<=tt+tnt;i++)
{if(i<=tt)
{ if(T[i]==temp)
return(i);}
else
if(NT[i-tt-1]==temp)
return(i); }
return(-1); }
void push(char t2,int t1)
{++top;
stack[top].s1=t1;
stack[top].s2=t2;
return; }
void pop(void)
{pops1=stack[top].s1;
pops2=stack[top].s2;
--top; getch(); }

Output:-

Enter number of terminals: 5


Enter terminals:+*()i
Enter number of non-terminals:3
Enter non-terminals:ETF
Enter number of productions:6
Enter productions:
E->E+T
E->T
T->T*F
T->F
F->(E)
F->i

Follow table:
FOLLOW(E)={+ ) $}
FOLLOW(F)={+ * ) $}
FOLLOW(T)={ + * ) $}

First Table :
FIRST(E)={ ( i }
FIRST(E)={ ( i }
FIRST(E)={ ( i }
Expected parse table:

+ * ( ) i $ E T F

I0 S4 S5
1 2 3
I1 S6
ACC
I2 R1 S7 R1 R1
I3 R3 R3 R3 R3
I4 S4 S5 ACC
8 2 3
I5 R5 R5 R5 R5

I6
ACC
I7 S4 S5
9
I8 S10 S11 ACC

I9 R2 R2 R2 R2
I10
ACC
I11 R4 R4 R4 R4

Enter i/p string: i+i*i

STACK INPUT
ACTION
Design LALR Bottom up Parser for the given language
<parser.l>

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

<parser.y>

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

Output:
$lex parser.l
$yacc –d parser.y
$cc lex.yy.c y.tab.c –ll –lm
$./a.out
2+3

5.0000

You might also like