COMPILER CONSTRUCTIONS LAB RECORD INDEXS.NO LIST OF PROGRAMS PAGE NO.
1 Program to implement a standalone scanner.
2 Write a program in lex to check if a no is octal, Hexadecimal
3 Program in lex to capitalize all comments in a c program
4 Program to implement a lex scanner
5 Write a program to find first and follow elements
6 Write a Program to find canonical LR(0) collections. i.e. a). closure
7 Write a Program to construct SLR parsing table using program 6
8 Write a program to implement a calculator using yacc. a). using lex b). without using lex
9 Program to generate code
10 Program to optimize the code
1. Program to implement a standalone scanner.
Scanner.c#include <stdio.h>#include <string.h>#include <ctype.h>
main(){
FILE *in,*out;char str1[20],str2[20];char ch;int k,flag;char key_word[32][32]={"do","if","while","include","main","define","for","char","int","float","long","double","switch","exit","break","continue","case","default","return","else","goto","printf","scanf","void","struct","union","enum","FILE"};
in=fopen("in.txt","r");out=fopen("out1.txt","w");
while(!feof(in)){
ch=fgetc(in);int i=0,j=0;flag=0;
if((ch=='+')||(ch=='-')||(ch=='*')||(ch=='/')||(ch=='<')||(ch=='>')||(ch=='=')||(ch=='%')||(ch=='?')) fprintf(out,"\n %c is operator \n",ch);
else if((ch=='#')||(ch=='~')||(ch==';')||(ch=='^')||(ch=='$')||(ch=='(')||(ch=='-')||(ch==')')||(ch=='{')||(ch=='}')||(ch=='[')||(ch==']')||(ch=='_')||(ch=='|')||(ch=='`')||(ch=='"')||(ch==':')||(ch=='.')||(ch==','))
fprintf(out,"\n %c specialsymbol \n",ch);
else if(isdigit(ch)){
str2[j]=ch;j++;ch=fgetc(in);while(isdigit(ch)){
str2[j]=ch;j++;ch=fgetc(in);
}str2[j]='\0';fprintf(out,"\n %s is Number\n",str2);//str2[j]='\0';
}else if(isalpha(ch)){
str1[i]=ch; i++; ch=fgetc(in);
while(isalnum(ch)){
str1[i]=ch; i++; ch=fgetc(in);
}str1[i]='\0';for( k=0;k<32;k++)if(strcmp(key_word[k],str1)==0)
flag=1;if(flag==1)
fprintf(out,"\n %s keyword\n",str1);else
fprintf(out,"\n %s identifier\n",str1);}
}fclose(in);fclose(out);
}
Execution:Cc scanner.c./a.out
In.txtvoid main(){int a = 10 , b = 20 , c ;c = a + b;printf("the sum is %d",c);}Out1.txtvoid keywordmain keyword) specialsymbol { specialsymbol int keyworda identifier= is operator 10 is Number, specialsymbol b identifier
= is operator 20 is Number, specialsymbol c identifier; specialsymbol c identifier= is operator a identifier+ is operator b identifierprintf keyword" specialsymbol the identifiersum identifieris identifier% is operator d identifier, specialsymbol c identifier; specialsymbol } specialsymbol
2. Write a program in lex to check if a no is octal, Hexadecimal etc.
Octal.l
%%[0][0-7]+ printf("%s\tIt is octal\n",yytext);[0][Xx][0-9A-Fa-f]+ printf("%s\tIt ishexadecimel\n",yytext);%%
Execution:
Lex octal.lCc lex.yy.c –ll./a.out
Output:0xA10xA1 It ishexadecimel
03210321 It is octal
3. Program in lex to capitalize all comments in a c program.
Capitalize.l
%{int c=0;%}comment [//]%%{comment} {c=1;}[A-Za-z] {if(c==1)printf("%s",caps(yytext));}
%%main(){yylex();}caps(char *str){int i=0;for(i=0;str[i]!='\0';i++)printf("%c",toupper(str[i]));}Execution: Output:lex cap1.l //mjcollegecc lex.yy.c –ll MJCOLLEGE./a.out
4. Program to implement a lex scanner.
Lscan.l
%{
#include <stdio.h>#include <string.h>void fn(int,int);int ln=1,n;
%}
d [0-9]n {d}+signo ([+/-]?{n})letter [A-Za-z]key "int"|"main"|"include"|"stdio.h"sc [;| |(|)|{|}|,|#|"|&|<|>]
%%
[\n] {ln++;}{key} {fn(ln,1);}[+|-|*|=] {fn(ln,2);}{letter} {fn(ln,3);}{sc} {fn(ln,4);}
%%
main(){
yyin=fopen("in.txt","r");yyout=fopen("out.txt","w");yylex();
}
void fn(int l,int n){
switch(n){
case 1: fprintf(yyout,"\n%d %s keyword",l,yytext); break;
case 2: fprintf(yyout,"\n%d %s operator",l,yytext);
break;
case 3: fprintf(yyout,"\n%d %s identifier",l,yytext); break;
default: fprintf(yyout,"\n%d %s special symbol",l,yytext); break;
}
}In.txt
#include<stdio.h>int main(){int a,b,c;c=a+b;}Out.txt1 # special symbol1 include keyword1 < special symbol1 stdio.h keyword1 > special symbol3 int keyword3 special symbol3 main keyword3 ( special symbol3 ) special symbol4 { special symbol5 int keyword5 special symbol5 a identifier5 , special symbol5 b identifier5 , special symbol5 c identifier5 ; special symbol6 c identifier6 = operator6 a identifier6 + operator6 b identifier6 ; special symbol7 } special symbol
5. Write a program to find first and follow elements.
First.c
#include<stdio.h>#include<ctype.h>
int main(){
int i,n,j,k; char str[10][10],f; printf("Enter the number of productions\n"); scanf("%d",&n); printf("Enter grammar\n"); for(i=0;i<n;i++) scanf("%s",&str[i]); for(i=0;i<n;i++) {
f= str[i][0]; int temp=i;
if(isupper(str[i][3])) {
repeat: for(k=0;k<n;k++) { if(str[k][0]==str[i][3]) { if(isupper(str[k][3])) { i=k; goto repeat; } else { printf("First(%c)=%c\n",f,str[k][3]); } } } } else { printf("First(%c)=%c\n",f,str[i][3]); }
i=temp; }
}
Output:
vi first.ccc first.c./a.out
Enter the number of productions5
Enter grammarS->ABA->abcB->(D)D->jklE->S
First(S)=aFirst(A)=aFirst(B)=(First(D)=jFirst(E)=a
Follow.c
#include<stdio.h>main(){
int np,i,j,k;char prods[10][10],follow[10][10],Imad[10][10];printf("enter no. of productions\n");scanf("%d",&np);printf("enter grammar\n");for(i=0;i<np;i++){
scanf("%s",&prods[i]);}
for(i=0; i<np; i++){
if(i==0) {
printf("Follow(%c) = $\n",prods[0][0]);//Rule1 }for(j=3;prods[i][j]!='\0';j++){
int temp2=j; //Rule-2: production A->xBb then everything in first(b) is in follow(B) if(prods[i][j] >= 'A' && prods[i][j] <= 'Z') {
if((strlen(prods[i])-1)==j) { printf("Follow(%c)=Follow(%c)\n",prods[i][j],prods[i][0]); } int temp=i; char f=prods[i][j]; if(!isupper(prods[i][j+1])&&(prods[i][j+1]!='\0')) printf("Follow(%c)=%c\n",f,prods[i][j+1]); if(isupper(prods[i][j+1])) {
repeat: for(k=0;k<np;k++) { if(prods[k][0]==prods[i][j+1]) { if(!isupper(prods[k][3])) { printf("Follow(%c)=%c\n",f,prods[k][3]); } else { i=k; j=2; goto repeat; } }
}}i=temp;
}j=temp2;
}}
}
Output :
vi follow.ccc follow.c./a.out
enter no. of productions4
Enter GrammarS->AB(C)B->DED->abcE->jkl
Follow(S) = $Follow(A)=aFollow(B)=(Follow(C)=)Follow(D)=jFollow(E)=Follow(B)
6. Write a Program to find canonical LR(0) collections. i.e. a). closure
closure.c
#include<stdio.h>#include<string.h>main(){ char A[10][10],items[20][20]={},closure[10][10]={},I[20][20],inputs[20][20]; int i,j,k,l=0,m=0,p=3,n=0,ilen[10],numi; int B[10][10]; char c,ch; int flag=0,numprods,temp,temp1,q;
printf("enter the number of productions\n"); scanf("%d",&numprods);
printf("Enter productions:\n");
for(i=0;i<=numprods;i++) { gets(A[i]); }
//finding items:
for(i=0;i<=numprods;i++) {
n = strlen(A[i]); for(j=0;j<(n-2);j++) { for(k=0;k<=(strlen(A[i]));k++) { if(p==k) { items[l][m] = '.'; m++; items[l][m] = A[i][k]; m++; } else { items[l][m++] = A[i][k]; }
}//k loop l++; p++; m = 0;
}//j loop p = 3;
}//i loop i = 0;
printf("Items are:\n");
while(l!=i) {
printf("%d)",i); puts(items[i]); printf("\n"); i++; }
printf("\n");
//Finding Closure:
strcpy(closure[0],items[0]); m=1;
j=0; do { if(closure[j][4]>='A' && closure[j][4] <= 'Z') { for(i=0;i<l;i++)// l gives the number of items { if((closure[j][4]==items[i][0])&&(items[i][4]=='.')) { strcpy(closure[++j],items[i-1]); m++; } } } else flag=1; }
while(flag==0); printf("Closure is:\n"); for(j=0;j<m;j++) puts(closure[j]); printf("\n");}
Output:
enter the number of productions2
Enter productions:A->CC->bItems are:0)A->.C
1)A->C.
2)C->.b
3)C->b.
Closure is:A->.CC->.b
7. Write a Program to construct SLR parsing table using program 6.
Slr.c
#include<stdio.h>#include<string.h>
char a[8][5],b[7][5];int c[12][5];int w=0,e=0,x=0,y=0;int st2[12][2],st3[12];char sta[12],ch;
void v1(char,int);void v2(char,int,int,int);
int main() { int i,j,k,l=0,m=0,p=1,f=0,g,v=0,jj[12]; printf("\n\n\t*******Enter the Grammar Rules (max=3)*******\n\t"); for(i=0;i<3;i++) {
gets(a[i]);printf("\t");
} for(i=0;i<3;i++) {
for(j=0;j<strlen(a[i]);j++) {
for(k=0;k<strlen(a[i]);k++) {
if(p==k){
b[l][m]='.'; m+=1;
b[l][m]=a[i][k]; m+=1;
}else{
b[l][m]=a[i][k]; m++; }
}p++;l++;m=0;
} p=1;
} i=0; p=0; while(l!=i) { for(j=0;j<strlen(b[i]);j++) { if(b[i][j]=='.')
{ p++; }
} if(p==0) {
b[i][strlen(b[i])]='.';}
i++; p=0; } i=0; sleep(10);
printf("\n\t*******Your States will be*******\n\t"); while(l!=i) { printf("%d--> ",i); puts(b[i]); i++; printf("\t"); } printf("\n"); v1('A',l);
p=c[0][0]; m=0; while(m!=6) { for(i=0;i<st3[m];i++) { for(j=0;j<strlen(b[p]);j++) { if(b[p][j]=='.' && ((b[p][j+1]>=65 && b[p][j+1]<=90)||(b[p][j+1]>=97&&b[p][j+1]<=122)))
{ st2[x][0]=m; sta[x]=b[p][j+1]; v2(b[p][j+1],j,l,f); x++;
}else
{ if(b[p][j]=='.') {
st2[x][0]=m;sta[x]='S';st2[x][1]=m;x++;
}
}}
p=c[m][i+1]; } m++; p=c[m][0]; } g=0; p=0; m=0;
x=0;while(p!=11)
{ for(i=0;i<st3[p];i++) {
for(k=0;k<p;k++){
for(j=0;j<3;j++) { if(c[k][j]==c[p][j])
{ m++;
} }
if(m==3) { m=0; goto ac; } m=0;
} if(m!=3) { if(v==0) {
printf("\tI%d=",g); v++; jj[g]=p;
} printf("%d",c[p][i]);
}
}printf("\n");
g++; ac: p++; v=0; } sleep(10); printf("\t*******Your DFA will be *******");
for(i=0;i<9;i++) { printf("\n\t%d",st2[i][0]); printf("-->%c",sta[i]); }
getchar(); }
void v1(char ai,int kk){
int i,j; for(i=0;i<kk;i++) {
if(b[i][2]==ai&&b[i][1]=='.') { c[w][e]=i; e++; if(b[i][2]>=65 && b[i][2]<=90)
{ for(j=0;j<kk;j++) { if(b[j][0]==ai && b[j][1]=='.')
{ c[w][e]=j; e++; }
} }
}}st3[w]=e;w++;e=0;
}void v2(char ai,int ii,int kk,int tt)
{ int i,j,k; for(i=0;i<kk;i++)
{
if(b[i][ii]=='.'&& b[i][ii+1]==ai) { for(j=0;j<kk;j++)
{ if(b[j][ii+1]=='.' && b[j][ii]==ai) {
c[w][e]=j;e++;st2[tt][1]=j;if(b[j][ii+2]>=65 && b[j][ii+1]<=90)
{ for(k=0;k<kk;k++) { if(b[k][0]==b[j][ii+2] && b[k][1]=='.')
{ c[w][e]=k; e++; }
} }
} } if((b[i][ii+1]>=65 && b[i][ii+1]<=90) && tt==1) {
for(k=0;k<kk;k++) { if(b[k][0]==ai && b[k][1]=='.') {
c[w][e]=k; e++;
}}
}}
} st3[w]=e; w++; e=0; }
8. Write a program to implement a calculator using yacc. a). using lex b). without using lex
a)yacclex.l%{ #include "y.tab.h" extern int yylval;%}%%[0-9]+ {yylval=atoi(yytext); return NUM;}[\t]\n return 0;. return yytext[0];%%
yacclex.y:%{#include<stdio.h>#include<ctype.h>%}%token DIG%%cmd: E '\n' {printf("%d\n",$1);}
E:E'+'T {$$=$1+$3;} |T {$$=$1;} ;T:T'*'F {$$=$1*$3;} |F {$$=$1;} ;F:'('E')' {$$=$2;} |DIG {$$=$1;} ;%%yylex(){ int c; c=getchar(); if(isdigit(c)) { yylval=c-'0'; return DIG; } elsereturn c;}
Execution:lex lp6.l yacc lp6.y yacc -dyacc.y
(usage: yacc [-dlrtv] [-b file_prefix] [-o output_filename] [-p symbol_prefix] filename)
cc y.tab.c lex.yy.c -ly -ll ./a.out
output:5*420
b. yacc.y
%{ #include<stdio.h>%}%token DIG
%%cmd: E '\n' { printf("%d", $1);} ;E : E '+' T {$$=$1+$3;} | T {$$=$1;} ;
T : T '-' B {$$=$1-$3;} |B {$$=$1;} ;
B : B '/' Q{$$=$1/$3;} |Q {$$=$1;} ;
Q : Q '*' F {$$=$1*$3;} | F {$$=$1;} ;
F : '(' E ')' {$$=$2;} |DIG {$$=$1;} ;%%yylex(){int c;c=getchar();if(isdigit(c))
{
yylval=c-'0';return DIG;}
return c;}Execution:yacc yacc.ycc y.tab.c -ly./a.out
Output:5*315
9. Program to generate code.9.Gencode.c
#include<stdio.h>char stk[100],stktop=-1,cnt=0;
void push(char pchar){
stk[++stktop]=pchar;}
char pop(){
return stk[stktop--];}
char checkoperation(char char1){
char oper;if(char1=='+')
oper='A';else if(char1=='-')
oper='S';else if(char1== '*')
oper='M';else if(char1=='/')
oper='D';
return oper;}
int checknstore(char check){
int ret;if(check!='+' && check!='-' && check!='*' && check!='/' && check!='@'){
push(++cnt);if(stktop>0)printf("ST $%d\n",cnt);ret=1;
}
elseret=0;
return ret;}
void main()
{char msg[100],op1,op2,operation;int i,val;while(scanf("%s",msg)!=EOF){
cnt=0;stktop=-1;for(i=0;msg[i]!='\0';i++){
if((msg[i]>='A' && msg[i]<='Z')|| (msg[i]>='a' && msg[i]<='z'))push(msg[i]);
else{
op1=pop();op2=pop();printf("L %c\n",op2);operation= checkoperation(msg[i]);printf("%c %c\n",operation,op1);val=checknstore(msg[i+1]);while(val==0){
op1=pop();cnt--;operation=checkoperation(msg[++i]);if(operation=='S'&&stktop>=-1){printf("N\n");operation='A';}printf("%c %s\n", operation,op1);val=checknstore(msg[i+1]);
}}
}}
}
Output:AB+C*D+L AA BL ?M CL ? A D
10. Program to optimize the code.
Codeopti.c
/* Code Optimization prog*/
#include<stdio.h>#include<string.h>
main(){
char str[25][50], forLoopParam[90], rightHandParam[10][40], leftHandParam[90];int j=0,k=0,i=0,m=0,n=0,q=0,s=0;int flag[10]={0},count[10]={0};printf("\n Input the loop to be optimized:\n");
/* PROCESSING FIRST LINE -- FOR DECLARATION*/
gets(str[0]);while(str[k][i++]!=';');while(str[k][i++]!=';');
while(str[k][i]!=')'){
if(isalpha(str[k][i])) forLoopParam[j++]=str[k][i];
i++;}i=0;
/* J IS INDEX TO CHANGEARRAY*/
/* PROCESSING SECOND LINE --{*/
puts(str[0]);gets(str[0]);
while(str[0][i++]!='{');puts(str[0]);k=0;while(gets(str[k]) && str[k][0]!='}'){
while(str[k][i++]!='=');leftHandParam[n++]=str[k][i-2];k++;i=0;
}
/*N IS INDEX TO TEMPCHANGE ARRAY*//* TEMPCHANGE ARRAY STORES LEFT SIDE PARAMETERS OF ASSIGNMENT OPERATIONS */
for(m=0,i=0;m<k;m++){
while(str[m][i++]!='=');while(str[m][i]!=';'){
if(isalpha(str[m][i]))rightHandParam[m][count[m]++]=str[m][i];i++;
} i=0;}
/* Q IS INDEX TO TEMP2*//* TEMP2 STORES RIGHT HAND SIDE PARAMETERS OF STATEMENTS*//*COMPARING LEFT-HAND PARAMETERS WITH RIGHT-HAND PARAMETERS*/
for(m=0;m<k;m++) for(s=0;s<count[m];s++) for(i=0;i<n;i++)
{ if(rightHandParam[m][s]==leftHandParam[i])
flag[m]=1;}
//COMPARING LEFT-HAND SIDE PARAMETERS WITH FOR-LOOP PARAMETERS
for(i=0;i<k;i++) for(q=0;q<j;q++) {
if(leftHandParam[i]==forLoopParam[q])flag[i]=1;
}
//COMPARING RIGHT-HAND PARAMETERS WITH FOR-LOOP PARAMETERS
for(m=1;m<k;m++) for(s=0;s<count[m];s++) for(i=0;i<j;i++)
{ if(rightHandParam[m][s]==forLoopParam[i])
flag[m]=1;}
//DISPLAYING STATEMENTS OF FOR LOOP WHICH CANT BE OPTIMIZED IN THE FOR LOOP
for(i=0;i<k;i++) if(flag[i]==1) puts(str[i]);
//DISPLAYING STATEMENTS OF FOR LOOP WHICH CANT BE OPTIMIZED OUTSIDE FOR LOOP
puts(str[k]); //DISPLAYING THE END-FLOWER BRACE
for(i=0;i<k;i++) if(flag[i]==0)
printf("\t\t %s \t\t",str[i]);}
Execution:Cc codeopti.c./a.out
Output:Input the loop to be optimized:for(i=0;i<9;i++)for(i=0;i<9;i++){{c=n+m;i=i+j;}i=i+j;} c=n+m;
11.Program to implement recursive descent parser
rec1parse.c
#include<stdio.h>#include<stdlib.h>char token;int exp(void);int term(void);int fac(void);void match(char etoken)
{ if (token==etoken) token=getchar(); else
{printf("ERROR\n");exit(1);} } main() { token=getchar(); exp(); if (token=='\n') printf("SUCCESS\n"); else printf("ERROR\n"); } int exp(void) {term(); while((token=='+') ||(token=='-')) switch(token) { case '+': match('+'); term(); break;
case '-': match('-'); term(); break; } } int term(void) {fac(); while(token=='*') { match('*'); fac(); } } int fac(void) { if (token=='(') { match('('); exp(); match(')'); } else if(isdigit(token)) { match(token); } else {printf("ERROR\n");exit(1);} }
Output :1+9+8
vi rec1parse.c SUCCESS cc rec1parse.c 8+7*./a.out ERROR