You are on page 1of 56

VELALAR COLLEGE OF ENGINEERING AND TECHNOLOGY ERODE 12.

LAB MANUAL

COMPILER LAB

LAB MANUAL PREPARED BY .

INDEX
S.N O.
1.

DAT E

TITLE OF EXPERIMENT
IMPLEMENTATION OF TOKEN SEPARATION

PAGE NO.
4

REMARK S

2.

IMPLEMENTATION OF LEXICAL ANALYSIS IMPLEMENTATION OF LEXICAL ANALYSIS USING LEX TOOL VALIDITY OF EXPRESSION IN PREDECTIVE PARSING TABLE IMPLEMENTATION OF PREDICTIVE PARSING TABLE CONSTRUCTION IMPLEMENTATION OF SHIFT REDUCE PARSING OPERATOR PRECENDENCE PARSING IMPLEMENTATION OF LR PARSING YACC TOOL WITH SIMPLE DESK CALCULATOR

3.

4.

5.

6.

7.

8.

9.

10.

INTERMEDIATE CODE GENERATION

11.

IMPLEMENTATION OF CODE GENERATION

Expt. No.: 1.

IMPLEMENTATION OF TOKEN SEPARATION


* AIM: To write a C program to implement the separation of tokens from a source program. * ALGORITHM: 1. Start the program. 2. The lexical analysis phase of the compiler (first phase of compiler) reads the character in the source program one by one. 3. It groups them into a stream of tokens. 4. Each token represents logically cohesive sequence of characters such as an identifier, a keyword, a punctuation character, or an operator like =, +, -, *, /. 5. The keywords, operators, data types are stored in separate array and they are used for comparing the separated tokens from the source program. 6. The function sepr() is used to separate the tokens from the source program. 7. The function symsrch() is used to search the symbols in the source program. 8. The function tknsrch() is used to find the keywords and the datatypes in the source program. 9. The function consep() is for finding the constants in the source program. 10. The duplicates of all the above functions return values are eliminated using the function elimdup(). 11. Repeat the steps 5 to 10 until the end of file is encountered. 12. Stop the program.

* PROGRAM: #include<stdio.h> char str[100],token[60][60],symb[100],temp[100],op[100],ss[100], kw[60][60],dt[60][60],var[60][60],con[60][60]; char kywrd[12] [10]={"include","stdio.h","conio.h","main","getch","clrscr","void","if","printf"}; char dttyp[11] [10]={"int","char","float","double","long","short","struct","union","void"}; char oper[50]={'~','!','^','&','*','/','%','-','+','<','|','>','='}; int k=0,x=0,len,ck,cd,cv,cc; void sepr() { int i=0,j=0; while(str[i]!='\0') { if(!isalpha(str[i]) && str[i]!=' ' && str[i]!='\n' && str[i]!='.' && ! isdigit(str[i])) symb[x++]=str[i++]; else if(str[i]==' ' || str[i]=='\n') i++; else { while(isalpha(str[i]) || str[i]=='.' || isdigit(str[i])) temp[j++]=str[i++]; temp[j]='\0'; strcpy(token[k++],temp); j=0; } } len=k-1; } void symsrch() { int i,j=0,k=0,x=0,f; for(i=0;i<strlen(symb);i++) { f=0; for(j=0;j<strlen(oper);j++) { if(symb[i]==oper[j]) { op[k++]=symb[i]; f=1; 5

break; } } if(!f) ss[x++]=symb[i]; } } void tknsrch() { int i,j,fk=0,fd=0; for(i=0;i<len;i++) { for(j=0;j<12;j++) { if(strcmp(token[i],kywrd[j])==0) fk=1; if(strcmp(token[i],dttyp[j])==0) fd=1; } if(fk) { fk=0; strcpy(kw[ck++],token[i]); } else if(fd) { fd=0; strcpy(dt[cd++],token[i]); } else if(!fd && !fk) strcpy(var[cv++],token[i]); } } void elimdup() { char t; int i,j; for(i=0;i<strlen(op);i++) for(j=i+1;j<strlen(op);j++) if(op[i]==op[j]) op[j]=' '; for(i=0;i<strlen(ss);i++) for(j=i+1;j<strlen(ss);j++) if(ss[i]==ss[j]) ss[j]=' '; 6

for(i=0;i<ck;i++) for(j=i+1;j<ck;j++) if(strcmp(kw[i],kw[j])==0) strcpy(kw[j]," "); for(i=0;i<cd;i++) for(j=i+1;j<cd;j++) if(strcmp(dt[i],dt[j])==0) strcpy(dt[j]," "); for(i=0;i<cv;i++) for(j=i+1;j<cv;j++) if(strcmp(var[i],var[j])==0) strcpy(var[j]," "); } void consep() { int i; for(i=0;i<cv;i++) if(isdigit(var[i][0])) { strcpy(con[cc++],var[i]); strcpy(var[i]," "); } } void main() { int i; FILE *ip,*o; ip=fopen("ex1.c","r+"); clrscr(); while(fgets(str,100,ip)) sepr(); symsrch(); tknsrch(); elimdup(); consep(); o=fopen("out.txt","w+"); fprintf(o,"\n\nOPERATORS\n"); for(i=0;i<strlen(op);i++) { if(op[i]!=' ') fprintf(o,"%c ",op[i]); 7

} fprintf(o,"\n\nSPECIAL SYMBOLS\n"); for(i=0;i<strlen(ss);i++) { if(ss[i]!=' '&&ss[i]!='\t') fprintf(o,"%c ",ss[i]); } fprintf(o,"\n\nDATA TYPES\n"); for(i=0;i<cd;i++) { if(strcmp(dt[i]," ")!=0) fprintf(o,"%s ",dt[i]); } fprintf(o,"\n\nIDENTIFIERS\n"); for(i=0;i<cv;i++) { if(strcmp(var[i]," ")!=0) fprintf(o,"%s ",var[i]); } fprintf(o,"\n\nCONSTANTS\n"); for(i=0;i<cc;i++) { if(strcmp(con[i]," ")!=0) fprintf(o,"%s ",con[i]); } fprintf(o,"\n\nKEYWORDS\n"); for(i=0;i<ck;i++) { if(strcmp(kw[i]," ")!=0) fprintf(o,"%s ",kw[i]); } }

* OUTPUT:

* RESULT: Thus the C program for the token separation is compiled and executed successfully and the output is verified. 9

Expt. No.: 2.

IMPLEMENTATION OF LEXICAL ANALYSIS


* AIM: To write a C program to implement the lexical analysis phase of the compiler. * ALGORITHM: 1. 2. 3. 4. 5. Start the program. Get the input string from the user. Identify whether the expression is valid. If the expression is invalid then print it as invalid string and terminate. Otherwise separate the variables, operators, constants from the entered expressions. 6. The variables are then placed in the separate array. 7. The identified variables are then replaced with ID followed by the constant number to indicate the number of variables in the expressions. 8. Print the ID values in the expressions instead of the variable names. 9. Print the variable names and its corresponding ID values as symbol table. 10. Stop the program.

10

* PROGRAM: #include<stdio.h> #include<string.h> #include<conio.h> #include<stdlib.h> char oper[24][2]={"-","+","=","*","/","&","|","~","<",">","^","%","!","+=","=","*=","%=","/=","++","--","<=",">=","!=","=="}; char *op="",buf[8],tmpvar[10],tmpopr[10],varlist[10][10]={""},*mstr; int len,i=0,k,cnt,j, v=0,vl=0,fdup=0,fopr=0,b,ii,c,inval=0; int lexi(char *); int valid(); int main() { char *str,*temp; clrscr(); printf("\nEnter the Expression\n"); scanf("%s",mstr); if(valid()==0) { lexi(mstr); printf("\n\nExpression is Valid\n\n"); } else { printf("\n Invalid Expression ~ brackets"); getch(); return 0; } if(inval==0) { printf("\n%s\n",op); printf("\n\nSYMBOL TABLE\n"); for(i=0;i<vl;i++) printf("\n%s getch(); } return 0; } ID%d",varlist[i],i);

int lexi(char *str) { 11

len=strlen(str); while(i<len) { if(str[i]=='('||str[i]==')') { sprintf(buf,"%c",str[i]); strcat(op,buf); i++; } v=0; while(isalpha(str[i])||isdigit(str[i])) { tmpvar[v]=str[i]; v++; i++; } tmpvar[v]='\0'; fdup=0; if(!isdigit(tmpvar[0])) { for(cnt=0;cnt<=vl;cnt++) if(strcmp(tmpvar,varlist[cnt])==0) { sprintf(buf,"ID%d",cnt); strcat(op,buf); fdup=1; } if(fdup!=1) { strcpy(varlist[vl],tmpvar); sprintf(buf,"ID%d",vl); strcat(op,buf); vl++; } } else strcat(op,tmpvar); if(i==0||!isalpha(str[0])||(!isalpha(str[len-1])&& !isdigit(str[len-1]))&&str[len-1]!=')') { printf("\nInvalid expression \n"); inval++; getch(); return 0; } k=0; if(str[i]=='('||str[i]==')') { 12

sprintf(buf,"%c",str[i]); strcat(op,buf); i++; } while(!isalpha(str[i])&&!isdigit(str[i])&&str[i]!='('&&str[i]!=')') { tmpopr[k]=str[i]; k++; i++; } tmpopr[k]='\0'; fopr=0; for (j=0;j<24;j++) if(strcmp(tmpopr,oper[j])==0) { strcat(op,tmpopr); fopr=1; break; } if(str[len-1]!=')'&&(strcmp(tmpopr,"")!=0&&fopr==0)) { printf("\nInvalid Expression \n"); inval++; getch(); return 0; } } } int valid() { b=ii=0; while(mstr[ii++]!='\0') { if(mstr[ii]=='(') { b++; ii++; if (isalpha(mstr[ii])) continue; else { printf("\n Invalid expression ~ brackets"); inval++; 13

getch(); exit(0); } } if(mstr[ii]==')') { b--; ii++; } } return b; }

14

* OUTPUT:

* RESULT:

15

Thus the C program for the token separation is compiled and executed successfully and the output is verified. Expt. No.: 3.

IMPLEMENTATION OF LEXICAL ANALYSIS USING LEX TOOL


* AIM: To write a C program to implement lexical analysis using LEX tool. * ALGORITHM: 1. Start the program. 2. Lex program consists of three parts. a. Declaration %% b. Translation rules %% c. Auxilary procedure. 3. The declaration section includes declaration of variables, maintest, constants and regular definitions. 4. Translation rule of lex program are statements of the form a. P1 {action} b. P2 {action} c. d. e. Pn {action} 5. Write a program in the vi editor and save it with .l extension. 6. Compile the lex program with lex compiler to produce output file as lex.yy.c. eg $ lex filename.l $ cc lex.yy.c -ll 7. Compile that file with C compiler and verify the output.

16

* PROGRAM: %{ #include<stdio.h> %} digit[0-9]+ identifier[a-zA-z][a-zA-z0-9]* %% #.* printf("%s is a preprocessor directive",yytext); int | float | double | if | char | goto printf("%s is a keyword\n",yytext); {identifier}\( printf("%s is a funtion\n",yytext); \{ printf("%s block begin \n",yytext); \} printf("%s block end \n",yytext); {identifier}(\[[0-9]*\])? printf("%s is identifier\n",yytext); \".*\" printf("%s is string\n",yytext); -{digit} printf("%s is negative number",yytext); "+"?{digit} printf("%s is a positive number",yytext); \; | \( | \) printf("%s is a special operator",yytext); \= printf("%s is assignment operator",yytext); \< | \> | \<= | \>= printf("%s is a relational operator\n",yytext); %% int main(int argc,char *argv[]) { if(argc>1) { FILE *fp; fp=fopen(argv[1],"r"); if(!fp) { printf("can't open"); exit(0); } yyin=fp; 17

yylex(); } return(0); } * OUTPUT:

* RESULT: 18

Thus the above program is compiled and executed successfully using the LEX tool and the sample output is verified. Expt. No.: 4.

VALIDITY OF EXPRESSION IN PREDECTIVE PARSING TABLE


* AIM: To write a C program to implement the predictive parsing algorithm. * ALGORITHM: 1. Input: A string w and a parsing table M for grammar G. 2. Output: If w is in L(G), a leftmost derivation of w; otherwise, an error indication. 3. Method: Initially, the parser is in a configuration in which it has $S on the stack with S, the start symbol of G on the top, and w$ in the input buffer. The program that utilizes the predictive parsing table M to produce a parse for the input. set ip to point to the first symbol of w$; repeat let X be the top stack symbol and a the symbol pointed to by ip; if X is a terminal or $ then if X=a then pop X from the stack and advance ip else error() else /* X is a nonterminal */ if M[X,a] = XY1Y2.....Yk then begin pop X from the stack; push Yk, Yk-1, ..Y1 onto the stack, with Y1 on top; output the production XY1Y2.....Yk end else errror() until X = $ /* stack is empty */

19

* PROGRAM: # include<stdio.h> # include<conio.h> # include<string.h> # include<stdlib.h> char t[6][5]={"x","+","*","(",")","$"}; char nt[5][6]={"E","e","T","t","F"}; char tv[5][6][6] = {"Te","0","0","Te","0","0","0","+Te","0","0", "a","a","Ft","0","0","Ft","0","0","0", "a","*Ft","0","a","a","x","0","0","(E)","0","0"}; struct stack { char item[50][25]; int top; }st; void push(char*); void pop(); void disp(); char* search(char*,char*); int check_ter(char*); char expr[6][10],tbv[25]; static char prod[10]; void main() { char item[25]; int k,j; static int i=0; clrscr(); printf("Enter the terminals:\n"); for(k=0;k<6;k++) printf("%s\n",t[k]); printf("Enter the non terminals:\n"); for(k=0;k<5;k++) printf("%s\n",nt[k]); printf("Enter the Table Values:\n"); for(k=0;k<5;k++) for(j=0;j<6;j++) printf("%s\n",tv[k][j]);

20

printf("Enter the expression:\t"); for(k=0;k<6;k++) scanf("%s",expr[k]); strcpy(st.item[st.top],"$"); st.top++; strcpy(st.item[st.top],"E"); disp(); while(strcmp(st.item[st.top],"$")!=0) { if(check_ter(st.item[st.top])==1) { strcpy(tbv,search(st.item[st.top],expr[i])); strcpy(prod,st.item[st.top]); if(strcmp(tbv,"")!=0 && strcmp(tbv,"a")!=0) { pop(); strcpy(item,strrev(tbv)); push(item); } else if(strcmp(tbv,"a")==0) pop(); else { printf("NOT VALID\n"); break; } } else if(check_ter(st.item[st.top])==0) { if(strcmp(st.item[st.top],expr[i])==0) { pop(); strcpy(expr[i],"\0"); i++; } else { printf("NOT VALID\n"); break; } } disp(); } } void pop() { strcpy(st.item[st.top],"\0"); 21

st.top=st.top-1; } void push(char *item) { int j; char str[5]; for(j=0;j<strlen(item);j++) { st.top++; str[0]=item[j]; str[1]='\0'; strcpy(st.item[st.top],str); } } char* search(char *r,char *s) { int k=0,j=0,x=0,y=0; char str[10]; while(k<5) if(strcmp(nt[k],r)!=0) k++; else { x=k; break; } while(j<6) if(strcmp(t[j],s)!=0) j++; else { y=j; break; } strcpy(str,tv[x][y]); return str; } int check_ter(char *r) { int x; for(x=0;x<6;x++) if(strcmp(t[x],r)==0) return 0; else if(strcmp(nt[x],r)==0) return 1;

22

} void disp() { int k; for(k=0;k<=st.top;k++) printf("%s",st.item[k]); printf("\t"); for(k=0;strcmp(expr[k],"$")!=0;k++) printf("%s",expr[k]); printf(expr[k]); printf("\t"); printf("%s-> %s",prod,strrev(tbv)); printf("\n"); }

23

* OUTPUT:

* RESULT: Thus the above program is compiled and executed successfully and output is verified. 24

Expt. No.: 5.

IMPLEMENTATION OF PREDICTIVE PARSING TABLE CONSTRUCTION


* AIM: To write a C program to implement the predictive parsing table construcion. * ALGORITHM: Input: Grammar G. Output: Parsing Table M. Method: 1. For each production A of the grammar, do steps 2 and 3. 2. For each terminal a in FIRST (), add A to M [A, a]. 3. If is in FIRST (), add A to M [A, b] for each terminal b in FOLLOW (A). If is in FIRST () and $ is in FOLLOW (A), add A to M [A, $]. 4. Make each undefined entry of M be error.

25

* PROGRAM: # include<stdio.h> # include<conio.h> # include<string.h> # include<stdlib.h> char t[7][5]={"x","+","*","(",")","a","$"}; char nt[5][6]={"E","e","T","t","F"}; char prod[8][10]={"E->Te","e->+Te","e->a","T->Ft","t->*Ft","t->a","F->(E)","F>x"}; char first[5][5]; char fol[5][5]; char tab[5][7][10]; int check_ter(char); int check(char); void main() { int i=0,x=0,y=0,l=0,j=0; int m=0,n=0; char s,z; int k=0; clrscr(); printf("\nEnter the terminals:\n"); for(i=0;i<7;i++) printf("%s",t[i]); printf("\nEnter the non terminals:\n"); for(i=0;i<5;i++) printf("%s",nt[i]); printf("\nEnter the productions:\n"); for(i=0;i<8;i++) printf("%s",prod[i]); /*FIRST*/ for(i=7;i>=0;i--) { s=prod[i][0]; x=check(s); if(check_ter(prod[i][3])==0) { k=0; while(first[x][k]!='\0') 26

k++; first[x][k]=prod[i][3]; } else if (check_ter(prod[i][3])==1) { y=check(prod[i][3]); strcpy(first[x],first[y]); } } /*FOLLOW*/ fol[0][0]='$'; fol[0][1]=prod[6][5]; for(i=0;i<8;i++) if(prod[i][3]!='a') { x=check(prod[i][3]); y=check(prod[i][4]); if(check_ter(prod[i][3])==1) { here:if(first[y][l]!='a') { k=0; while(fol[x][k]!='\0') k++; fol[x][k]=first[y][l]; } else { l++; goto here; } } } for(i=0;i<6;i++) if(prod[i][3]!='a') { x=check(prod[i][0]); y=check(prod[i][4]); strcat(fol[y],fol[x]); } printf("FIRST:\n"); for(i=0;i<5;i++) { printf("%s:\t",nt[i]); printf("%s\n",first[i]); } 27

printf("FOLLOW:\n"); for(i=0;i<5;i++) { printf("%s:\t",nt[i]); printf("%s\n",fol[i]); } /*TABLE CREATION*/ for(m=0;m<8;m++) { y=check(prod[m][0]); if(check_ter(prod[m][3])==1) { k=0; while(first[y][k]!='\0') { n=check(first[y][k]); strcpy(tab[y][n],prod[m]); k++; } } else if(prod[m][3]!='a'&& check_ter(prod[m][3])==0) { n=check(prod[m][3]); strcpy(tab[y][n],prod[m]); } else if(prod[m][3]=='a') { k=0; while(fol[y][k]!='\0') { n=check(fol[y][k]); strcpy(tab[y][n],prod[m]); k++; } } } printf("\t"); for(i=0;i<7;i++) if(strcmp(t[i],"a")!=0) printf("%s\t",t[i]); printf("\n"); for(i=0;i<5;i++) { printf("%s\t",nt[i]); for(j=0;j<7;j++) printf("%s\t",tab[i][j]); printf("\n\n\n"); 28

} } int check_ter(char z) { int x; char r[2]; r[0]=z; r[1]='\0'; for(x=0;x<6;x++) if(strcmp(t[x],r)==0) return 0; else if(strcmp(nt[x],r)==0) return 1; } int check(char s) { int i=0; char x[2]; x[0]=s; x[1]='\0'; while(i<5) if(strcmp(x,nt[i])==0) return i; else i++; i=0; while(i<8) if(strcmp(x,t[i])==0) return i; else i++; }

29

* OUTPUT:

* RESULT: Thus the above program is compiled and executed successfully and output is verified. 30

Expt. No.: 6.

IMPLEMENTATION OF SHIFT REDUCE PARSING


* AIM: To write a C program to implement the shift reduce parsing. * ALGORITHM: 1. 2. 3. 4. 5. 6. 7. 8. Start the program. Get the input string from the user. Push $ onto top of the stack. Set ip to point to the first input symbol. If there is any production which can be used to reduce the input symbol reduce the string otherwise push it to the top of the stack. Set ip to point to next input symbol. Repeat the above steps until the top of the stack contains the $ and the starting symbol. If so, then the string is valid, otherwise the string is invalid, return an error message. Stop the program.

31

* PROGRAM: #include<stdio.h> #include<conio.h> void pus(char); void reduce(); char inp1[5][10]={"E+E","E*E","(E)","a"},stk[50],inpt1[10],stk1[50]; int ct=0; void main() { int k,len; char inpt[10]; clrscr(); printf("Enter The Input String\n\n"); gets(inpt); printf("\n\n"); len=strlen(inpt); inpt[len++]='$'; inpt[len]='\0'; strcpy(inpt1,inpt); len=strlen(inpt); inpt[len++]='$'; inpt[len++]='\0'; pus('$'); pus(inpt[0]); for(k=1;k<len-1;k++) { if(!isupper(inpt[k-1])) { reduce(); if(inpt[k]!='$') pus(inpt[k]); } } if(stk[0]=='$' && stk[1]=='E' && stk[2]=='0' && inpt1[0]=='$') printf("\n\n\n\t\tString Accepted"); else printf("\n\n\n\t\tNot Accepted"); getch(); } void pus(char inpt) { int i,n; n=strlen(inpt1); if(ct>0) { for(i=0;i<n;i++) inpt1[i-1]=inpt1[i]; inpt1[n-1]='\0'; 32

} stk[ct++]=inpt; i=0; while(stk[i]!='0' && stk[i]!='\0') printf("%c",stk[i++]); printf("\t%s\tShift\n",inpt1); } void reduce() { int j=0,ct1,i,ct2,t,ct3,true=0; char temp[10],tmp; strcpy(stk1,stk); for(i=0;i<5;i++) { if(stk[ct-1]==inp1[i][0]) { if(stk[ct-1]!='('&&stk[ct-1]!=')') stk[ct-1]='E'; i=0; while(stk[i]!='0' && stk[i]!='\0') printf("%c",stk[i++]); printf("\t%s\tReduce\n",inpt1); true=1; } } for(i=0;i<4 ;i++) { j=0; ct1=ct-strlen(inp1[i]); ct2=ct1; ct3=0; while(ct1<ct && ct1>0 && stk[ct1]!=0) temp[j++]=stk[ct1++]; temp[j]='\0'; if(strcmp(temp,inp1[i])==0) { stk[ct2]='E'; t=ct2; while(ct2<=ct) stk[++ct2]='0'; ct=t; ct++; true=0; } } i=0; while(stk[i]!='0' && stk[i]!='\0' && true==0) printf("%c",stk[i++]); if(true==0) printf("\t%s\tReduce\n",inpt1); 33

34

* OUTPUT:

* RESULT: Thus the above program is compiled and executed successfully and output is verified. 35

Expt. No.: 7.

IMPLEMENTATION OF OPERATOR PRECENDENCE PARSING


* AIM: To write a C program to implement operator precedence parsing algorithm. * ALGORITHM: Input: An input string w and a table of precedence relations. Output: If w is well formed, a skeletal parse tree, with a placeholder nonterminal E labeling all interior nodes; otherwise, an error indication. Method: Initially, the stack contains $ and the input buffer the string w$. set ip to point to the first symbol of w$; repeat forever if $ is on top of the stack and ip points to $ then return else begin let a be the topmost terminal symbol on the stack and let b be the symbol pointed to by ip; if a < b or a = b then begin push b onto the stack; advance ip to the next input symbol; end; else if a> b then repeat pop the stack until the top stack terminal is related by < to the terminal most recently popped else error() end

36

* PROGRAM: #include<stdio.h> #include<conio.h> #define msize 40 struct stack { int top; char item[msize]; }s; void main() { int i,j,re; char *in; char c1,c2; s.top=-1; clrscr(); printf("Enter the input language\n"); scanf("%s",in); printf("\nStack elements\t\tInput\t\tActions\n\n"); push(&s,'$'); printf("$\t\t\t"); for(i=0;in[i];i++) printf("%c",in[i]); printf("$\tInitial\n"); for(i=0;in[i];i++) { re=check(s.item[s.top],in[i]); if(re==1) { push(&s,in[i]); for(j=0;j<=s.top;j++) printf("%c",s.item[j]); printf("\t\t\t"); for(j=i+1;in[j];j++) printf("%c",in[j]); printf("$\t\t"); printf("push(%c<%c)\n",s.item[s.top-1],in[i]); } else { pop(&s); for(j=0;j<=s.top;j++) printf("%c",s.item[j]); printf("\t\t\t"); for(j=i;in[j];j++) printf("%c",in[j]); printf("$\t\t"); 37

printf("pop(%c>%c)\n",s.item[s.top+1],in[i]); while(re==0) { c1=s.item[s.top]; c2=s.item[s.top+1]; re=check(c1,c2); if(re==1) { re=check(s.item[s.top],in[i]); if(re==1) { push(&s,in[i]); for(j=0;j<=s.top;j++) printf("%c",s.item[j]); printf("\t\t\t"); for(j=i+1;in[j];j++) printf("%c",in[j]); printf("$\t\t"); printf("push(%c<%c)\n",s.item[s.top-1],in[i]); break; } else { pop(&s); for(j=0;j<=s.top;j++) printf("%c",s.item[j]); printf("\t\t\t"); for(j=i;in[j];j++) printf("%c",in[j]); printf("$\t\t"); printf("pop(%c>%c)\n",s.item[s.top+1],in[i]); } } } } if(in[i+1]==NULL) while(s.item[s.top]!='$') { re=check(s.item[s.top],'$'); if(re==0) pop(&s); for(j=0;j<=s.top;j++) printf("%c",s.item[j]); printf("\t\t\t"); printf("$"); printf("\t\tpop(%c>$)\n",s.item[s.top+1]); } } if(s.top==0) 38

printf("\nSUCCESS"); else printf("\nERROR"); getch(); } int check(char st,char ip) { char id[8]={'+','-','*','i','$','/','(',')'}; char pre[8][8]={{'=','>','<','<','>','<','<','>'}, {'>','=','<','<','>','<','<','>'}, {'>','>','=','<','>','>','<','>'}, {'>','>','>','=','>','>','0','>'}, {'<','<','<','<','=','<','<','0'}, {'>','>','>','<','>','=','<','>'}, {'<','<','<','<','0','<','<','>'}, {'>','>','>','0','>','>','0','>'}}; int i,t1,t2; for(i=0;i<8;i++) { if(st==id[i]) t1=i; if(ip==id[i]) t2=i; } if(pre[t1][t2]=='>') return 0; else return 1; } push(ps,x) struct stack *ps; char x; { ps->item[++(ps->top)]=x; return; } pop(ps) struct stack *ps; { ps->item[--(ps->top)]; return; }

39

* OUTPUT:

* RESULT: Thus the above program is compiled and executed successfully and output is verified. 40

Expt. No.: 8.

IMPLEMENTATION OF LR PARSING
* AIM: To write a C program to implement simple ing algorithm. * ALGORITHM: Input: An input string w and an LR parsing table with functions action and goto for a grammar G. Output: If w is in L(G), a bottom up parse for w; otherwise an error indication. Method: Initially, the parser has s0 on its stack, s0 is the initial state, and w$ in the input buffer. The parser then executes the program until accept or error action is encountered. set ip to point to the first symbol of w$; repeat forever begin let s be the state on the top of the stack and a the symbol pointed to by ip; if action [s, a] = shift s then begin push a then s on the top of the stack; advance ip to the next input symbol end else if action [s, a] = reduce A then begin pop 2*|| symbols off the stack; let s be the state now on top of the stack; push A then goto [s, A] on top of the stack; output the production A end else if action [s, a] = accept then return else error() end

41

* PROGRAM: char stk[10],inp[10],pat[20][20][20],prod[10][10],ipsymb[10]; int sp,ip,tp; char c,v; int i,k,t; void gettable() { int i,j,k,n; char c; strcpy(pat[0][0],"s5");strcpy(pat[0][3],"s4");strcpy(pat[0][6],"1"); strcpy(pat[0][7],"2");strcpy(pat[0][8],"3"); strcpy(pat[1][5],"A"); strcpy(pat[1][1],"s6"); strcpy(pat[2][1],"r2");strcpy(pat[2][2],"s7");strcpy(pat[2][4],"r2"); strcpy(pat[2][5],"r2"); strcpy(pat[3][1],"r4");strcpy(pat[3][2],"r4");strcpy(pat[3][4],"r4"); strcpy(pat[3][5],"r4"); strcpy(pat[4][0],"s5");strcpy(pat[4][3],"s4");strcpy(pat[4][6],"8"); strcpy(pat[4][7],"2");strcpy(pat[4][8],"3"); strcpy(pat[5][2],"r6");strcpy(pat[5][1],"r6");strcpy(pat[5][4],"r6"); strcpy(pat[5][5],"r6"); strcpy(pat[6][0],"s5");strcpy(pat[6][3],"s4");strcpy(pat[6][7],"9"); strcpy(pat[6][8],"3"); strcpy(pat[7][0],"s5");strcpy(pat[7][3],"s4");strcpy(pat[7][8],"a"); strcpy(pat[8][1],"s6");strcpy(pat[8][4],"sb"); strcpy(pat[9][1],"r1");strcpy(pat[9][2],"s7");strcpy(pat[9][4],"r1"); strcpy(pat[9][5],"r1"); strcpy(pat[10][1],"r3");strcpy(pat[10][2],"r3");strcpy(pat[10][4],"r3"); strcpy(pat[10][5],"r3"); strcpy(pat[11][1],"r5");strcpy(pat[11][2],"r5");strcpy(pat[11][4],"r5"); strcpy(pat[11][5],"r5"); ipsymb[0]='i';ipsymb[1]='+';ipsymb[2]='*';ipsymb[3]='(';ipsymb[4]=')'; ipsymb[5]='$';ipsymb[6]='E';ipsymb[7]='T';ipsymb[8]='F'; strcpy(prod[0],"E'->E");strcpy(prod[1],"E->E+T");strcpy(prod[2],"E->T"); strcpy(prod[3],"T->T*F");strcpy(prod[4],"T->F"); strcpy(prod[5],"F->(E)");strcpy(prod[6],"F->i"); } int ipnum(char c) { int i; for(i=0;i<strlen(ipsymb);i++) { if(ipsymb[i]==c) break; } return i; 42

} int stknum(char c) { char t[10]; int i; if(c<='9') { t[0]=c;t[1]='\0'; return atoi(t); } else { return(c-97+10); } } void shift() { char t; t=pat[i][k][1]; stk[++sp]=inp[ip++]; stk[++sp]=t; } void reduce() { int b,prev,z; char t,pr[10],subs[10]; t=pat[i][k][1]; strcpy(pr,prod[t-48]); b=2*(strlen(pr)-3); sp=sp-b; t=stk[sp]; prev=stknum(t); stk[++sp]=pr[0]; z=ipnum(pr[0]); stk[++sp]=pat[prev][z][0]; stk[sp+1]='\0'; } void main() { int q; clrscr(); printf("ENTER THE INPUT..."); scanf("%s",inp); t=strlen(inp); inp[t]='$'; inp[t+1]='\0'; stk[0]='0'; gettable(); printf("\n\n\nSTACK\t\tINPUT\t\tOPERATION\n"); 43

while(1) { c=inp[ip]; v=stk[sp]; k=ipnum(c); i=stknum(v); if(pat[i][k][0]=='s') shift(); else if(pat[i][k][0]=='r') reduce(); else if(pat[i][k][0]=='A') { printf("\n\nVALID..."); getch(); exit(0); } else { printf("\n\nINVALID..."); getch(); exit(0); } printf("%s\t\t",stk); q=ip; while(inp[q]!='\0') printf("%c",inp[q++]); if(pat[i][k][0]=='s') printf("\t\tShift\n"); else if(pat[i][k][0]=='r') printf("\t\tReduced by %s\n",prod[pat[i][k][1]-48]); } }

44

* OUTPUT:

* RESULT: Thus the above program is compiled and executed successfully and output is verified.

45

Expt. No.: 9.

YACC TOOL WITH SIMPLE DESK CALCULATOR


* AIM: To implement simple desk calculator using yacc tool. * ALGORITHM: Start the program. Yacc program consists of three parts namely o Declarations %% o Transition Rule %% o Supporting C routines. Declaration part consists of two sections, first section contains only include statements and the second statements contains declaration of the grammar tokens. Each rule in set of transition rules consists of grammar production and semantic action. The set of productions are of the form o <left side>: <alt 1> {semantic action 1} | <alt 2> {semantic action 2} .. | <alt n> {semantic action n} ; In the third part, error recovery routines are added. The program is typed using vi editor, and saved with .y extension. It is first compiled with the yacc compiler to produce the C code for C compiler (yacc samp.y). After that compile that program with C compiler (cc y.tab.c ly standard output file of yacc compiler). See the output using ./a.out. Stop the program.

46

* PROGRAM: %{ #include<ctype.h> #include<stdio.h> #define YYSTYPE double %} %token NUMBER %left '+' '-' %left '*' '/' %right '^' %right UMINUS %% lines : lines expr '\n' {printf("%lf",$2);} | lines '\n' | ; expr : expr '+' expr {$$=$1+$3;} | expr '-' expr {$$=$1-$3;} | expr '*' expr {$$=$1*$3;} | expr '/' expr {if($3!=0) {$$=$1/$3;} else yyerror("divident should be a positive no.\n"); } | expr '^' expr { int i,sum=1; for(i=1;i<=$3;i++) {sum *= $1;} $$=sum; } | '(' expr ')' {$$=$2;} | '-' expr %prec UMINUS {$$= $2;} | NUMBER ; %% yylex() { int c; while((c=getchar())==' '); if((c=='.')||(isdigit(c))) { ungetc(c,stdin); scanf("%lf",&yylval); return NUMBER; } return c; }

47

* OUTPUT:

* RESULT: Thus the above program is compiled and executed successfully and output is verified.

48

Expt. No.: 10.

IMPLEMENTATION OF INTERMEDIATE CODE GENERATION


* AIM: To write a C program to implement the intermediate code for the given set of input expressions. * ALGORITHM: 1. 2. 3. 4. 5. Start the program. Get the input expression from the user. Check the expressions for its validation. If it is invalid return the error message. Otherwise, for each computation store the result in the three address statement (store it in temporary variable say t1, t2, etc.,) . 6. Assign the final temporary value to the variable in which the result has to be stored. 7. Stop the program.

49

* PROGRAM: #include<stdio.h> #include<ctype.h> #include<stdlib.h> #include<conio.h> #include<string.h> void small(); void dove(int ); int p[5]={0,1,2,3,4},c=1,i,k,l,m,pi; char sw[5]={'=','-','+','/','*'},j[20],a[5],b[5],ch[2]; void main() { clrscr(); printf("Enter the expression:"); scanf("%s",j); printf("\n\n\tThe Intermediate code is:\n"); small(); } void dove(int i) { a[0]='\0';b[0]='\0'; I f(!isdigit(j[i+2]) && !isdigit(j[i-2])) { a[0]=j[i-1]; b[0]=j[i+1]; } if(isdigit(j[i+2])) { a[0]=j[i-1]; b[0]='t'; b[1]=j[i+2]; } if(isdigit(j[i-2])) { b[0]=j[i+1]; a[0]='t'; a[1]=j[i-2]; b[1]='\0'; } if(isdigit(j[i+2]) && isdigit(j[i-2])) { a[0]='t'; b[0]='t'; a[1]=j[i-2]; b[1]=j[i+2]; itoa(c,ch,10); j[i+2]=j[i-2]=ch[0]; } 50

if(j[i]=='*') printf("\tt%d=%s*%s\n",c,a,b); if(j[i]=='/') printf("\tt%d=%s/%s\n",c,a,b); if(j[i]=='+') printf("\tt%d=%s+%s\n",c,a,b); if(j[i]=='-') printf("\tt%d=%s-%s\n",c,a,b); if(j[i]=='=') printf("\t%c=t%d",j[i-1],--c); itoa(c,ch,10); j[i]=ch[0]; c++; small(); } void small() { pi=0;l=0; for(i=0;i<strlen(j);i++) { for(m=0;m<5;m++) if(j[i]==sw[m]) if(pi<=p[m]) { pi=p[m]; l=1; k=i; } } if(l==1) dove(k); else { getch(); exit (0); } }

51

* OUTPUT:

* RESULT: Thus the above program is compiled and executed successfully and output is verified. 52

Expt. No.: 11.

IMPLEMENTATION OF CODE GENERATION


* AIM: To write a C program to implement the code generation algorithm. * ALGORITHM: The code generation algorithm takes as input a sequence of three address statements constituting a basic block. For each three address statement of the form x := y op z we perform the following actions: 1. Invoke a function getreg to determine the location L where the result of the computation y op z should be stored. L will usually be a register, but it could also be a memory location. We shall describe getreg shortly. 2. Consult the address descriptor for y to determine y , (one of) the current location(s) of y. prefer the register for y if the value of y is currently both in memory and a register. If the value of y is not already in L, generate the instruction MOV y , L to place a copy of y in L. 3. Generate the instruction OP z, L where z is a current location of z. Again, prefer a register to a memory location if z is in both. Update the address descriptor of x to indicate that x is in location L. If L is a register, update its descriptor to indicate that it contains the value of x, and remove x from all other register descriptors. 4. If the current values of y and/or z have no next users, are not live on exit from the block, and are in register descriptor to indicate that, after execution of x := y op z, those registers no longer will contain y and/or z, respectively.

53

* PROGRAM: #include<stdio.h> #include<conio.h> #include<string.h> char exp[10][10],*ope; int i,j,n,s[10],flag2,flag3,r1,r2; void check(); void oper(); void main() { clrscr(); printf("\nEnter the No. of Expressions:\n"); scanf("%d",&n); printf("\nEnter The Expression (In Three Address Code):\n"); for(i=0;i<n;i++) { scanf("%s",exp[i]); s[i]=i; } printf("\n\nGenerated Code Is:\n\n"); oper(); getch(); } void oper() { for(i=0;i<n;i++) { flag2=0; flag3=0; if(exp[i][3]=='*') ope="MUL"; if(exp[i][3]=='/') ope="DIV"; if(exp[i][3]=='+') ope="ADD"; if(exp[i][3]=='-') ope="SUB"; check(); printf("MOV R%d,%c\t(Result Moved To %c)\n",s[i],exp[i][0],exp[i] [0]); } } 54

void check() { for(j=0;j<i;j++) { if(exp[i][2]==exp[j][0]) { flag2=1; r1=s[j]; } if(exp[i][4]==exp[j][0]) { flag3=1; r2=s[j]; } } if(flag2==1&&flag3==1) { s[i]=0; printf("%s R%d,R%d\t(Result In R%d)\n",ope,r2,r1,r1); } else if(flag2==1&&flag3!=1) { s[i]=r1; printf("%s %c,R%d\t(Result In R%d)\n",ope,exp[i][4],r1,r1); } else if(flag2!=1&&flag3==1) { s[i]=r2; printf("%s %c,R%d\t(Result In R%d)\n",ope,exp[i][2],r2,r2); } else { printf("MOV %c,R%d\t(%c Moved To R%d)\n",exp[i][2],s[i],exp[i] [2],s[i]); printf("%s %c,R%d\t(Result In R%d)\n",ope,exp[i][4],s[i],s[i]); } }

55

* OUTPUT:

* RESULT: Thus the above program is compiled and executed successfully and output is verified. 56

You might also like