• No results found

Compiler-Design Lab Assignment Solution

N/A
N/A
Protected

Academic year: 2021

Share "Compiler-Design Lab Assignment Solution"

Copied!
20
0
0

Loading.... (view fulltext now)

Full text

(1)

www.rishabhdua.com

DEPARTMENT OF COMPUTER SCIENCE & ENGINEERING

LIST OF EXPERIMENTS

COURSE: B.Tech SEMESTER: V

SESSION: 2009-10 BRANCH: CSE

SUBJECT CODE & NAME: TCS- 502, Compiler Design

LIST OF EXPERIMENTS 1

Write a program to check the identifier in the given source program

2

Write a program to convert an Expression form Infix to Postfix

3

Write a program to find the FIRST of the given grammar

4

Write a program FOLLOW of the given grammar

5

Write a program to implement the parser PREDICTIVE PARSER

6 Write a program to implement the parser SHIFT REDUCE PARSER 7

Implement the following expressions into quadruples a+b+c*d/e+f

8 Implement Constant Folding technique of code optimization 9

Implement Common Subexpression Elimination technique of code optimization

10

Implement Strength Reduction using Induction Variable technique of code optimization

(2)

www.rishabhdua.com

Experiment - 1

Program Name : Write a program to check the identifier in the given source program Theory Concepts :To identify identifier lexeme in the source program

Flow Chart (If Required) :

Implementation : Program to check the identifier in the given source program

#include<stdio.h> #include<conio.h> #include<string.h> void main() { char a[10],b[10]; int i,j,p,flag=0; a[]={"if","else","main","void","char","float","goto","for","includ e","int"}; clrscr(); gets(b); for(i=0;i<10;i++) { p=strcmp(b,a[i]); if(p==0) { flag=1; break; } } if(flag==1) { printf("keyword matched"); } else {

printf("keyword not matched"); }

getch();}

(3)

www.rishabhdua.com

Experiment - 2

Program Name : Write a program to convert an Expression form Infix to Postfix Theory Concepts :the infix expression is converted to postfix expression

Flow Chart (If Required) :

Implementation : Write a program to convert an Expression form Infix to Postfix

#include<conio.h> #include<stdio.h> void main() { char pre[20]; char stack1[40]; char stack2[40]; int top1=-1,top2=-1,i; clrscr();

printf("Enter the prefix expression :\n"); pre[0]='('; for(i=1;;i++) { scanf("%c",&pre[i]); if(pre[i]=='\r'||pre[i]=='\n') { pre[i]=')'; pre[++i]='\0'; break; } } for(i=0;pre[i]!='\0';i++) { up: if(pre[i]=='+'||pre[i]=='-'||pre[i]=='*'||pre[i]=='/'||pre[i]=='('||pre[i]==')') { if(pre[i]=='(') stack1[++top1]='('; if(pre[i]=='+') { if(stack1[top1]!='+'&&stack1[top1]!='*'&&stack1[top1]!='/') stack1[++top1]=pre[i];

else {stack2[++top2]=stack1[top1--];goto up;}

} if(pre[i]=='-') { if(stack1[top1]!='+'&&stack1[top1]!='-'&&stack1[top1]!='*'&&stack1[top1]!='/') stack1[++top1]=pre[i];

(4)

www.rishabhdua.com

} if(pre[i]=='*') { if(stack1[top1]!='*'&&stack1[top1]!='/') stack1[++top1]=pre[i];

else {stack2[++top2]=stack1[top1--];goto up;}

}

if(pre[i]=='/') {

if(stack1[top1]!='/') stack1[++top1]=pre[i];

else {stack2[++top2]=stack1[top1--];goto up;}

} if(pre[i]==')') { for(;;) { stack2[++top2]=stack1[top1--]; if(stack1[top1]=='(') {top1--;break;} } } } else stack2[++top2]=pre[i]; } stack2[++top2]='\0';

printf("the postfix is :%s",stack2); getch();

}

(5)

www.rishabhdua.com

Experiment - 3

Program Name : Write a program to find FIRST of NON TERNINALS of the given grammar Theory Concepts :FIRST is a function computed to develop LL and LR parser

Flow Chart (If Required) :

Implementation : Program to find first four NonTerminals

#include"stdio.h" #include<conio.h>

char array[10][20],temp[10]; int c,n;void fun(int,int[]);

int fun2(int i,int j,int p[],int key) { int k; if(!key) { for(k=0;k<n;k++) if(array[i][j]==array[k][0]) break; p[0]=i;p[1]=j+1; fun(k,p); return 0; } else { for(k=0;k<=c;k++) { if(array[i][j]==temp[k]) break; } if(k>c)return 1; else return 0; } }

void fun(int i,int p[]) { int j,k,key; for(j=2;array[i][j]!='\0';j++) { if(array[i][j-1]=='/') { if(array[i][j]>='A'&&array[i][j]<='Z') { key=0; fun2(i,j,p,key); } else {

(6)

www.rishabhdua.com

key=1;

if(fun2(i,j,p,key)) temp[++c]=array[i][j];

if(array[i][j]=='@'&&p[0]!=-1) { //taking ,@, as null symbol.

if(array[p[0]][p[1]]>='A'&&array[p[0]][p[1]]<='Z') { key=0; fun2(p[0],p[1],p,key); } else if(array[p[0]][p[1]]!='/'&&array[p[0]][p[1]]!='\0') { if(fun2(p[0],p[1],p,key)) temp[++c]=array[p[0]][p[1]]; } } } } } } void main() { int p[2],i,j; clrscr();

printf("Enter the no. of productions :"); scanf("%d",&n);

printf("Enter the productions :\n"); for(i=0;i<n;i++) scanf("%s",array[i]); for(i=0;i<n;i++) { c=-1,p[0]=-1,p[1]=-1; fun(i,p); printf("First(%c) : [ ",array[i][0]); for(j=0;j<=c;j++) printf("%c,",temp[j]); printf("\b ].\n"); getch(); } }

Output / Conclusion : Enter the no. of productions :6 Enter the productions :

S/aBDh B/cC C/bC/@ D/E/F E/g/@ F/f/@ First(S) : [ a ]. First(B) : [ c ]. First(C) : [ b,@ ]. First(D) : [ g,@,f ]. First(E) : [ g,@ ]. First(F) : [ f,@ ].

(7)

www.rishabhdua.com

Experiment - 4

Program Name : Write a program to find out FOLLOW of NONTERMINALS of given

productions

Theory Concepts : FOLLOW of nonterminals are calculated to design parsing tables Flow Chart (If Required) :

Implementation : Program to follow for NonTerminals

#include"stdio.h" #include<conio.h> #define max 10 #define MAX 15

char array[max][MAX],temp[max][MAX]; int c,n,t;void fun(int,int[]);

int fun2(int i,int j,int p[],int key) { int k; if(!key) { for(k=0;k<n;k++) if(array[i][j]==array[k][0]) break; p[0]=i;p[1]=j+1; fun(k,p); return 0; } else { for(k=0;k<=c;k++) { if(array[i][j]==temp[t][k]) break; } if(k>c)return 1; else return 0; } }

void fun(int i,int p[]) { int j,k,key; for(j=2;array[i][j]!='\0';j++) { if(array[i][j-1]=='/') { if(array[i][j]>='A'&&array[i][j]<='Z') { key=0; fun2(i,j,p,key); } else {

(8)

www.rishabhdua.com

key=1;

if(fun2(i,j,p,key))

temp[t][++c]=array[i][j];

if(array[i][j]=='@'&&p[0]!=-1) { //taking ,@, as null symbol.

if(array[p[0]][p[1]]>='A'&&array[p[0]][p[1]]<='Z') { key=0; fun2(p[0],p[1],p,key); } else if(array[p[0]][p[1]]!='/'&&array[p[0]][p[1]]!='\0') { if(fun2(p[0],p[1],p,key)) temp[t][++c]=array[p[0]][p[1]]; } } } } } } char fol[max][MAX],ff[max];int f,l,ff0; void ffun(int,int); void follow(int i) { int j,k; for(j=0;j<=ff0;j++) if(array[i][0]==ff[j]) return 0; if(j>ff0)ff[++ff0]=array[i][0]; if(i==0)fol[l][++f]='$'; for(j=0;j<n;j++) for(k=2;array[j][k]!='\0';k++) if(array[j][k]==array[i][0]) ffun(j,k); }

void ffun(int j,int k) { int ii,null=0,tt,cc; if(array[j][k+1]=='/'||array[j][k+1]=='\0') null=1; for(ii=k+1;array[j][ii]!='/'&&array[j][ii]!='\0';ii++) { if(array[j][ii]<='Z'&&array[j][ii]>='A') { for(tt=0;tt<n;tt++) if(temp[tt][0]==array[j][ii])break; for(cc=1;temp[tt][cc]!='\0';cc++) { if(temp[tt][cc]=='@')null=1; else fol[l][++f]=temp[tt][cc]; } } else fol[l][++f]=array[j][ii]; } if(null)follow(j); }

(9)

www.rishabhdua.com

void main()

{

int p[2],i,j;

clrscr();

printf("Enter the no. of productions :"); scanf("%d",&n);

printf("Enter the productions :\n"); for(i=0;i<n;i++) scanf("%s",array[i]); for(i=0,t=0;i<n;i++,t++) { c=0,p[0]=-1,p[1]=-1; temp[t][0]=array[i][0]; fun(i,p); temp[t][++c]='\0'; printf("First(%c) : [ ",temp[t][0]); for(j=1;j<c;j++) printf("%c,",temp[t][j]); printf("\b ].\n"); getch(); } /* Follow Finding */ for(i=0,l=0;i<n;i++,l++) { f=-1;ff0=-1; fol[l][++f]=array[i][0]; follow(i); fol[l][++f]='\0'; } for(i=0;i<n;i++) { printf("\nFollow[%c] : [ ",fol[i][0]); for(j=1;fol[i][j]!='\0';j++) printf("%c,",fol[i][j]); printf("\b ]"); getch(); } }

(10)

www.rishabhdua.com

Output / Conclusion : Enter the no. of productions :6 Enter the productions :

S/aBDh B/cC C/bC/@ D/E/F E/g/@ F/f/@ First(S) : [ a ]. First(B) : [ c ]. First(C) : [ b,@ ]. First(D) : [ g,@,f ]. First(E) : [ g,@ ]. First(F) : [ f,@ ]. Follow[S] : [ $ ] Follow[B] : [ g,f,h,$ ] Follow[C] : [ g,f,h,$ ] Follow[D] : [ h ] Follow[E] : [ h ] Follow[F] : [ h ]

(11)

www.rishabhdua.com

Experiment - 5

Program Name : Write a program to implement predictive parser Theory Concepts :predictive decent parser implements LL(1) grammar Flow Chart (If Required) :

Implementation : PROGRAM TO IMPLEMENT PREDICTIVE PARSER

#include<stdio.h> #include<conio.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;/*value of token attribute */

int lineno=1; int lookahead; struct entry{ char *lexptr; int token; }symtable[100];

/* stores the list of keywords */ struct entry keywords[]=

{

"if",KEYWORD,"else",KEYWORD,"for",KEYWORD,"int",KEYWORD,"floa t",KEYWORD,"double",

KEYWORD,"char",KEYWORD,"struct",KEYWORD,"return",KEYWORD,0,0 }

/* issues a compiler error */ void Error_Message(char *m) {

fprintf(stderr,"line %d: %s \n",lineno,m); /* line number where error is occured */

exit(1); }

int look_up(char s[]) {

(12)

www.rishabhdua.com

for(k=lastentry;k>0;k=k-1) if(strcmp(symtable[k].lexptr,s)==0) return k; return 0; }

int insert(char s[],int tok) {

int len;

len=strlen(s);

if(lastentry+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 Initialise() { struct entry *ptr; for(ptr=keywords;ptr->token;ptr++) 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)

(13)

www.rishabhdua.com

val=insert(buffer,ID); tokenval=val; return symtable[val].token; } else if(t==EOF) return DONE; else { tokenval=NONE; 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("\n Arithematic 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();

(14)

www.rishabhdua.com

while(1) switch(lookahead) { case '*':t=loookahead; Match(lookahead); F(); display(t,NONE); continue; case '/':t=lookahead; Match(lookahead); F(); 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(';'); }} void main(){ char ans; clrscr();

printf("program for recursive descent parsing \n"); Initialize();

printf("enter the expression"); printf("and place; at the end"); printf("press ctrl to terminate"); parser();

}

(15)

www.rishabhdua.com

Experiment - 6

Program Name : Write a program to simulate SHIFT REDUCE PARSER Theory Concepts :SHIFT REDUCE parser is simplest form of LR grammar Implementation : PROGRAM TO SIMULATE REDUCE PARSER

#include<stdio.h> #include<conio.h> void push(char,char[],int); void pop(int); void main() { char a[4][10]={ {'E','=','E','+','E'}, {'E','=','E','*','E'}, {'E','=','(','E',')'}, {'E','=','id'}}; char st[20],item; int top=0; st[top]='$'; char str[10]={'id','+','(','id','*','id',')'}; clrscr(); for(int j=0;j<=7;j++) { push(str[j],st,top); if(st[top]==a[3][2]) { pop(top); push('E',st,top); } else { for(int i=0;i<4;i++) { if(st[top]==a[i][2]) { if(st[top--]==a[i][3]) if(st[top--]==a[i][4]) { pop(top); push(a[i][1],st,top); } } }} } if(st[top]=='$') printf("accept"); getch(); }

void push(char item,char st[],int top) {

top=top+1; st[top]=item;

(16)

www.rishabhdua.com

}

void pop(int top) { top=top-1; }

(17)

www.rishabhdua.com

Experiment - 7

Program Name : Implement the following expressions into quadruples

Theory Concepts : Every compiler has intermediate code representation phase from which code is optimized in code optimization phase

Flow Chart (If Required) :

Implementation : Implement the following expressions into quadruples

a+b+c*d/e+f

op arg1 arg2 result

(0) + f T1 (1) / d e T2 (2) * c T2 T3 (3) + T3 T1 T4 (4) + b T4 T5 (5) + a T5 T6 Output / Conclusion :

(18)

www.rishabhdua.com

Experiment - 8

Program Name : Implement Constant Folding technique of code optimization

Theory Concepts : Constant folding is the simplest code optimization to understand. Let us

suppose that you write the statement x = 45 * 88; in your C program. A non-optimizing compiler will generate code to multiply 45 by 88 and store the value in x. An optimizing compiler will detect that both 45 and 88 are constants, so their product will also be a constant. Hence it will find 45 * 88 = 3960 and generate code that simply copies 3960 into x. This is constant folding, and means the calculation is done just once, at compile time, rather than every time the program is run. To illustrate this, create the file test2.c as shown below.

Flow Chart (If Required) : Implementation :

/* Demonstration of constant folding */ #include <stdio.h> int main() { int x, y, z; x = 10; y = x + 45; z = y + 4; printf("The value of z = %d", z); return 0; }

Output / Conclusion : constant folding, the compiler evaluates the various expressions in the

program only once and plugs the final value into the generated code. One more interesting thing to observe is that after constant folding, there is no need of the variables x, y and z. Therefore no space for them is allocated on the stack, thus reducing the memory requirement of the program. This brings out the fact that one optimization may lead to another one. In the above case constant folding lead to a decrease in run time (since all the computations are done at compile time) and also to a decrease in the space requirements. Optimization is done.

(19)

www.rishabhdua.com

Experiment - 9

Program Name : Implement Common Subexpression Elimination technique of code

optimization

Theory Concepts : Many a times, it happens that the same expression is evaluated at different

places in the same program and the values of the operands in the expression do not change in between the two evaluations of that expression. For example, the program may evaluate say a * b at the beginning and at the end. If the values of a and b do not change in between these two evaluations of a * b, then instead of evaluating a * b again at the end, we can save the result of the evaluation of a * b at the beginning in some temporary variable and use it at the end. This will help eliminate redundant computations in the program. This optimization is called as common subexpression elimination. Consider the following program that demonstrates it.

Flow Chart (If Required) : Implementation :

/* common subexpression elimination */ #include <stdio.h>

int main() {

int a, b; int x, y, z;

scanf("%d %d", &a, &b); x = a * b; if(b >= 4) { y = a * b; z = 0; } else { z = a * b * 4; y = 0; } printf("x = %d, y = %d, z = %d\n", x, y, z); return 0; }

Output / Conclusion : This program has an example of a common subexpression. The

expression a * b is evaluated the first time, and then again later. The last two evaluations of a * b are redundant since the value of neither a nor b changes after the first evaluation. Thus these two evaluations are common subexpressions that can be eliminated. The first thing to notice is that now only variables a and b are stored on the stack, hence a stack of just 8 bytes is required as opposed to a 20 byte stack for the unoptimized version. You may wonder what's so special about variables a and b. The specialty is that the address of variables a and b is used in the program (for scanf()) and variables that reside in the registers cannot have a memory address.

(20)

www.rishabhdua.com

Experiment - 10

Program Name : Implement Strength Reduction using Induction Variable technique of

code optimization

Theory Concepts : One type of code optimization is strength reduction in which a "costly"

operation is replaced by a less expensive one. For example, the evaluation of x2 is much more efficient if we multiply x by x rather than call the exponentiation routine. One place where this optimization can be applied is in loops. Many times in a loop, one variable changes in synchronization with the loop variable. Such a variable is called as induction variable. Induction variables give the compiler a chance to apply strength reduction, as can be seen from the following program.

Flow Chart (If Required) : Implementation :

/* demonstration of induction variable elimination */ int main() { int i, j; for(i = 0; i < 10; i++) { j = i * 7; printf("i = %d, j = %d", i, j); } return 0; }

Output / Conclusion : Here i is the loop variable whereas j is the induction variable as j always

changes in lock step with I . Here, the compiler has adjusted the order of the statements in the loop so as to enable it to use strength reduction. After analyzing the program, the compiler sees that inside the loop, the value of i is always going to increase by 1 and since j is an induction variable, its value is always going to increase by 7. Therefore, instead of multiplying i by 7 (which is costly), it adds 7 to the old value of j before going on to the next

iteration. Thus a costly operation of multiplication has been replaced by addition which is cheaper (in terms of time).

References

Related documents

As was the case above, when we were assuming that negative externalities exist, so-called unwanted fertility is likely to persist unless there are changes in the situation

• Assist with property management activities including site monitoring and developing work scopes • Design, layout and produce visual displays such as mounted aerial photos and

Employment System Performance rankings. Four of the 10 higher-performing states, Maryland,.. 6 South Dakota, Colorado, and Delaware, were in the top 10 in terms of VR

In particular, it is shown that by using a channel decoder, the probability of two users establishing a secret key is close to one, while the probability of an adversary gen-

The results indicate that for an increase in forest area of 50 million acres, annual government expenditures with optimal contracts are about $4 billion lower compared than under

This system bonds composite not only to dentin but to most dental related surfaces like enamel, casting alloys, amalgam, porcelain and composite.. Fifth generation The most

Background and objectives: This study compared the rates of acute respiratory failure, rein- tubation, length of intensive care stay and mortality in patients in whom the

Institute: Health Study programme: Dental Techniques Level of course unit: first cycle degree. Course unit title Course