LIST OF EXPERIMENTS 1 2 3 4 5 Write a program to check the identifier in the given source program Write a program to convert an Expression form Infix to Postfix Write a program to find the FIRST of the given grammar Write a program FOLLOW of the given grammar Write a program to implement the parser PREDICTIVE PARSER Write a program to implement the parser SHIFT REDUCE PARSER Implement the following expressions into quadruples 7 a+b+c*d/e+f Implement Constant Folding technique of code optimization Implement Common Subexpression Elimination technique of code optimization Implement Strength Reduction using Induction Variable technique of code optimization



9 10


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();} Output / Conclusion : keyword matched


if(pre[i]=='\r'||pre[i]=='\n') { pre[i]=')'. pre[0]='('.} } if(pre[i]=='-') { if(stack1[top1]!='+'&&stack1[top1]!=''&&stack1[top1]!='*'&&stack1[top1]!='/') stack1[++top1]=pre[i]. } } for(i=0. break. for(i=1..i++) { scanf("%c".com . else {stack2[++top2]=stack1[top1--]. char stack2[40].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. int top1=-1.www.i.com Experiment .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].top2=-1. char stack1[40]. clrscr().} www.h> void main() { char pre[20]. else {stack2[++top2]=stack1[top1--]. pre[++i]='\0'.rishabhdua.goto up. printf("Enter the prefix expression :\n").pre[i]!='\0'.&pre[i]).goto up.rishabhdua.

} Output / Conclusion : a+b is converted to ab+ www.www. getch().break.. if(stack1[top1]=='(') {top1--.} } if(pre[i]=='/') { if(stack1[top1]!='/') stack1[++top1]=pre[i]. printf("the postfix is :%s". else {stack2[++top2]=stack1[top1--]. } stack2[++top2]='\0'.} } } } else stack2[++top2]=pre[i].goto up. else {stack2[++top2]=stack1[top1--].goto up.) { stack2[++top2]=stack1[top1--].com .} } if(pre[i]==')') { for(.rishabhdua.stack2).rishabhdua.com } if(pre[i]=='*') { if(stack1[top1]!='*'&&stack1[top1]!='/') stack1[++top1]=pre[i].

com .key.k.int j. return 0.n. } if(k>c)return 1.int[]).int p[]) { int j. int fun2(int i.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.j++) { if(array[i][j-1]=='/') { if(array[i][j]>='A'&&array[i][j]<='Z') { key=0. else return 0.rishabhdua.k++) if(array[i][j]==array[k][0]) break.k<n.k<=c.temp[10]. if(!key) { for(k=0.h> char array[10][20].p[1]=j+1.j.h" #include<conio. } } void fun(int i. p[0]=i.p).k++) { if(array[i][j]==temp[k]) break.com Experiment . fun2(i.www.int key) { int k. } else { www.int p[].p.key).void fun(int.rishabhdua. } else { for(k=0. fun(k. for(j=2. int c.array[i][j]!='\0'.

fun(i.key)) temp[++c]=array[p[0]][p[1]]. printf("First(%c) : [ ". for(i=0. } } } } } } void main() { int p[2].j<=c.i. fun2(p[0].i++) scanf("%s". First(E) : [ g. printf("Enter the productions :\n").\n"). } } Output / Conclusion : Enter the no.p[1]=-1.i<n.p.key)) temp[++c]=array[i][j].@.j++) printf("%c.@ ].p). scanf("%d". of productions :").j.rishabhdua.f ]. if(array[i][j]=='@'&&p[0]!=-1) { //taking . clrscr().com key=1.array[i]). First(C) : [ b.j.www.@ ].p[1].temp[j]).p[1]. if(fun2(i. First(F) : [ f. getch(). First(B) : [ c ]. of productions :6 Enter the productions : S/aBDh B/cC C/bC/@ D/E/F E/g/@ F/f/@ First(S) : [ a ].i++) { c=-1.rishabhdua. as null symbol. for(j=0.array[i][0]).i<n. First(D) : [ g. if(array[p[0]][p[1]]>='A'&&array[p[0]][p[1]]<='Z') { key=0. } else if(array[p[0]][p[1]]!='/'&&array[p[0]][p[1]]!='\0') { if(fun2(p[0]. for(i=0.com .p. printf("Enter the no.&n).p. printf("\b ]. www.@ ].key).@.p[0]=-1.".

rishabhdua.int key) { int k.com . } else { www.k<n. p[0]=i.rishabhdua.j.t.p).p.k++) { if(array[i][j]==temp[t][k]) break. if(!key) { for(k=0.void fun(int.n.k++) if(array[i][j]==array[k][0]) break.int p[].p[1]=j+1.www.int[]).k.k<=c.int p[]) { int j. fun2(i.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. else return 0. } if(k>c)return 1.h> #define max 10 #define MAX 15 char array[max][MAX].h" #include<conio. return 0.key. for(j=2. int c.int j. fun(k. } } void fun(int i.j++) { if(array[i][j-1]=='/') { if(array[i][j]>='A'&&array[i][j]<='Z') { key=0. int fun2(int i.array[i][j]!='\0'. } else { for(k=0.com Experiment .key).temp[max][MAX].

k).p.j<n.ff0. fun2(p[0]. else fol[l][++f]=temp[tt][cc]. if(fun2(i.int). } } else fol[l][++f]=array[j][ii]. if(j>ff0)ff[++ff0]=array[i][0].tt.k++) if(array[j][k]==array[i][0]) ffun(j.p[1].cc.@.p.ff[max].key).key)) temp[t][++c]=array[p[0]][p[1]]. if(array[j][k+1]=='/'||array[j][k+1]=='\0') null=1.p[1]. } else if(array[p[0]][p[1]]!='/'&&array[p[0]][p[1]]!='\0') { if(fun2(p[0]. } if(null)follow(j).com .ii++) { if(array[j][ii]<='Z'&&array[j][ii]>='A') { for(tt=0.tt++) if(temp[tt][0]==array[j][ii])break.j++) for(k=2. void ffun(int. for(j=0.p. if(array[i][j]=='@'&&p[0]!=-1) { //taking . } void ffun(int j. as null symbol.int f.key)) temp[t][++c]=array[i][j].null=0. if(array[p[0]][p[1]]>='A'&&array[p[0]][p[1]]<='Z') { key=0.j<=ff0.array[j][ii]!='/'&&array[j][ii]!='\0'.rishabhdua.temp[tt][cc]!='\0'.array[j][k]!='\0'.com key=1. } www.l. void follow(int i) { int j.k.www. for(ii=k+1.j++) if(array[i][0]==ff[j]) return 0.int k) { int ii.cc++) { if(temp[tt][cc]=='@')null=1.tt<n. for(cc=1. for(j=0. } } } } } } char fol[max][MAX].rishabhdua. if(i==0)fol[l][++f]='$'.j.

i.i++.fol[i][j]!='\0'.j++) printf("%c. getch().j.temp[t][j]). printf("Enter the productions :\n").i<n.". clrscr().temp[t][0]). for(i=0.j++) printf("%c.i<n.p[1]=-1. temp[t][0]=array[i][0]. printf("\b ]").com . printf("First(%c) : [ ".rishabhdua.fol[i][0]).j<c.p[0]=-1.". getch().t=0. fun(i.i++) scanf("%s".\n").l=0. temp[t][++c]='\0'. fol[l][++f]='\0'. } /* Follow Finding */ for(i=0.rishabhdua.www.p).i<n.i<n. fol[l][++f]=array[i][0]. for(j=1. printf("Enter the no. of productions :"). for(i=0.i++.i++) { printf("\nFollow[%c] : [ ". } } www.com void main() { int p[2].l++) { f=-1. for(j=1.array[i]).&n).ff0=-1. scanf("%d".t++) { c=0.fol[i][j]). printf("\b ]. follow(i). } for(i=0.

www.rishabhdua.h.@ ]. First(C) : [ b.com Output / Conclusion : Enter the no.@ ]. Follow[S] : [ $ ] Follow[B] : [ g. First(B) : [ c ]. First(F) : [ f.f ].@. of productions :6 Enter the productions : S/aBDh B/cC C/bC/@ D/E/F E/g/@ F/f/@ First(S) : [ a ].$ ] Follow[D] : [ h ] Follow[E] : [ h ] Follow[F] : [ h ] www.h.$ ] Follow[C] : [ g. First(D) : [ g.rishabhdua.@ ].com . First(E) : [ g.f.f.

/*value of token attribute */ int lineno=1.KEYWORD."double". /* line number where error is occured */ exit(1).KEYWORD.h> #include<ctype. www.rishabhdua.0.www."floa t".KEYWORD.com . KEYWORD. /* stores the list of keywords */ struct entry keywords[]= { "if".com Experiment .h> #include<stdlib.KEYWORD.0 } /* issues a compiler error */ void Error_Message(char *m) { fprintf(stderr."return"."char". struct entry{ char *lexptr."else".KEYWORD.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.KEYWORD."for". int tokenval=DONE. } int look_up(char s[]) { int k.lineno.h> #include<conio. char buffer [SIZE]. int lastchar=-1.KEYWORD."line %d: %s \n".m)."struct".KEYWORD.rishabhdua.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]. int lastentry=0. int lookahead. int token. }symtable[100].h> #include<string."int".

lexptr. symtable[lastentry]. strcpy(symtable[lastentry]. if(t!=EOF) ungetc(t. len=strlen(s). } int insert(char s[]. int val.i=0. if(val==0) www. return NUM.com for(k=lastentry.lexptr. else if(isdigit(t)) { ungetc(t.ptr->token.lexptr=&lexemes[lastchar+1]. while(1) { t=getchar(). } void Initialise() { struct entry *ptr.www. } else if(isalpha(t)) { while(isalnum(t)) { buffer[i]=t. if(i>=SIZE) Error_Message("compiler error").s)==0) return k. lastchar=lastchar+len+1.com .stdin). for(ptr=keywords.token=tok.int tok) { int len. lastentry=lastentry+1. scanf("%d". } buffer[i]=EOS.k>0.k=k-1) if(strcmp(symtable[k]. if(t== ' ' || t=='\t') else if(t=='\n') lineno=lineno+1.rishabhdua.ptr++) insert(ptr->lexptr. return lastentry. t=getchar().&tokenval).rishabhdua.ptr->token).stdin). i=i+1. if(lastentry+1 >=MAX) Error_Message("lexemes array is full"). val=look_up(buffer). symtable[lastentry].s). } int lexer() { int t. return 0.

else if(t==NUM) printf("\n NUMBER:%d". return symtable[val]. switch(lookahead) { case '(':Match ('(').rishabhdua. E().rishabhdua. } }} void Match(int t) { if(lookahead==t) lookahead=lexer(). } else if(t==EOF) return DONE. break.tokenval). else Error_Message("Syntax error").tokenval). www.symtable[tval]. } void F() { void E().com . return t. else if(t==ID) printf("\n identifier:%s". else printf("\n token %d tokenval %d".ID). break.token. return symtable[val]. F(). Match(NUM). } else if(t==EOF) return DONE.tokenval). break. }} void T() { int T.tval).www. } void display(int t.token. Match (')').int tval) { if(t=='+'||t=='-'||t=='*'||t=='\') printf("\n Arithematic operator:%c".com val=insert(buffer. Match(ID). else { tokenval=NONE. else { tokenval=NONE.lexptr). tokenval=val.t). case ID:display(ID.t. case NUM:display(NUM. default:Error_Message("Syntax Error").

Match(lookahead). printf("press ctrl to terminate").rishabhdua. default:return. Initialize(). printf("program for recursive descent parsing \n"). }} void main(){ char ans. display(T.'). display(T. continue. Match(lookahead). } Output / Conclusion :parsers the given expression www. display(t.NONE).NONE). continue. at the end"). Match('. parser().com . }}} void parser(){ lookahead =lexer(). F(). printf("and place. display(t.NONE).rishabhdua. F(). }} void E(){ int t. Match(lookahead). T(). default: return.www. T(). case '/':t=lookahead.NONE). while(1) { switch(lookahead) { case '+':t=lookahead. clrscr(). while(lookahead!=DONE) { E(). T(). continue.com while(1) switch(lookahead) { case '*':t=loookahead. Match(lookahead). case '-':t=lookahead. continue. printf("enter the expression").

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

com } void pop(int top) { top=top-1.rishabhdua.com . } Output / Conclusion : parsing process is done and string is accepted www.rishabhdua.www.

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 f d c T3 b a arg2 e T2 T1 T4 T5 result T1 T2 T3 T4 T5 T6 (0) (1) (2) (3) (4) (5) Output / Conclusion : www.rishabhdua.rishabhdua.com .www.com Experiment .

Therefore no space for them is allocated on the stack. y = x + 45.com . there is no need of the variables x. One more interesting thing to observe is that after constant folding. the compiler evaluates the various expressions in the program only once and plugs the final value into the generated code. This is constant folding. Flow Chart (If Required) : Implementation : /* Demonstration of constant folding */ #include <stdio. and means the calculation is done just once. Optimization is done. thus reducing the memory requirement of the program. z = y + 4. www. Hence it will find 45 * 88 = 3960 and generate code that simply copies 3960 into x. An optimizing compiler will detect that both 45 and 88 are constants. create the file test2.c as shown below. To illustrate this.www. This brings out the fact that one optimization may lead to another one.8 Program Name : Implement Constant Folding technique of code optimization Theory Concepts : Constant folding is the simplest code optimization to understand. in your C program. printf("The value of z = %d". y. Let us suppose that you write the statement x = 45 * 88. at compile time.rishabhdua. rather than every time the program is run.com Experiment . so their product will also be a constant. return 0. } Output / Conclusion : constant folding. z).rishabhdua. A non-optimizing compiler will generate code to multiply 45 by 88 and store the value in x. y and z. x = 10. 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.h> int main() { int x. z.

com . y. return 0. 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. hence a stack of just 8 bytes is required as opposed to a 20 byte stack for the unoptimized version. } printf("x = %d. scanf("%d %d".9 Program Name : Implement Common Subexpression Elimination technique of code optimization Theory Concepts : Many a times. If the values of a and b do not change in between these two evaluations of a * b. y = 0.h> int main() { int a.com Experiment . we can save the result of the evaluation of a * b at the beginning in some temporary variable and use it at the end. x = a * b. This optimization is called as common subexpression elimination. &a. int x. For example. Flow Chart (If Required) : Implementation : /* common subexpression elimination #include <stdio. y. x. then instead of evaluating a * b again at the end. z. 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. Thus these two evaluations are common subexpressions that can be eliminated. z = 0. z). the program may evaluate say a * b at the beginning and at the end. } else { z = a * b * 4. b. The first thing to notice is that now only variables a and b are stored on the stack. and then again later. Consider the following program that demonstrates it. You may wonder what's so special about variables a and b.www. &b).rishabhdua. This will help eliminate redundant computations in the program. y = %d. The expression a * b is evaluated the first time. z = %d\n". */ www.rishabhdua. if(b >= 4) { y = a * b. The last two evaluations of a * b are redundant since the value of neither a nor b changes after the first evaluation. } Output / Conclusion : This program has an example of a common subexpression.

the value of i is always going to increase by 1 and since j is an induction variable. Such a variable is called as induction variable. www. as can be seen from the following program.www. i++) { j = i * 7. i. one variable changes in synchronization with the loop variable. Induction variables give the compiler a chance to apply strength reduction. i < 10. printf("i = %d. Flow Chart (If Required) : Implementation : /* demonstration of induction variable elimination */ int main() { int i. the compiler has adjusted the order of the statements in the loop so as to enable it to use strength reduction.rishabhdua. Therefore. One place where this optimization can be applied is in loops. j).rishabhdua. the compiler sees that inside the loop. After analyzing the program. instead of multiplying i by 7 (which is costly).com . its value is always going to increase by 7.com Experiment . } return 0. j. it adds 7 to the old value of j before going on to the next iteration. For example.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. Here. the evaluation of x2 is much more efficient if we multiply x by x rather than call the exponentiation routine. } Output / Conclusion : Here i is the loop variable whereas j is the induction variable as j always changes in lock step with I . Many times in a loop. j = %d". for(i = 0. Thus a costly operation of multiplication has been replaced by addition which is cheaper (in terms of time).

Sign up to vote on this title
UsefulNot useful

Master Your Semester with Scribd & The New York Times

Special offer for students: Only $4.99/month.

Master Your Semester with a Special Offer from Scribd & The New York Times

Cancel anytime.