PCC Lab

Download as pdf or txt
Download as pdf or txt
You are on page 1of 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