CD LAB PROGRAMS

DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING

Compiler Design Lab Manual

Prepared by

Mohan Rao Mamdikar
ASST-PROF,CSE

LORDS INSTITUTE OF ENGINEERING AND TECHNOLOGY
(Affiliated to JNTU, Hyd. & Approved by AICTE)

Himayat Sagar, Hyderabad

1

CD LAB PROGRAMS

TABLE OF CONTENTS
(As per syllabus)
S.N o 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Convert the BNF rules into Yacc form and write code to generate abstract syntax tree. A program to generate machine code Design predictive parser for the given language Design a LALR bottom up parser for the given language 11 16 18 25 TOPIC System Requirements Lab Objectives Design a lexical analyzer for given language .the lexical analyzer should ignore redundant spaces, tabs and new lines. Implement the lexical analyzer using JLex, flex or other lexical analyzer generating tools. Wee k Page No. 3 4 5 8

2

C++ compiler and JDK kit. 2.CD LAB PROGRAMS System Requirements 1. Intel based destktop PC of 166MHz or faster processor with at least 64 MB RAM and 100 MB free disk space. 3 .

To provide an understanding of the design aspect of operating system. 4 .CD LAB PROGRAMS Lab Objectives 1. To provide an Understanding of the language translation peculiarities by designing complete translator for mini language. 2.

str)==0||strcmp("float".st1[10].i=0.f1).h> #include<stdio. } main() { FILE *f1.str)==0|| strcmp("double".CD LAB PROGRAMS 1)A Program to Design Lexical Analyzer."w")./*gets(st1). f2=fopen("identifier".str)==0|| strcmp("int". ungetc(c. while(isdigit(c)) { tokenvalue*=10+c-'0'. c=getc(f1). c=getc(f1).str).str)==0||strcmp("static". else printf("\n%s is an identifier".f1). fclose(f1).str)==0) printf("\n%s is a keyword".*f2.str)==0||strcmp("char".str)==0||strcmp("switch". while((c=getchar())!=EOF) putc(c.*f3. f1=fopen("input".k=0. int num[100].f2).tokenvalue=0.h> #include<ctype.str)==0||strcmp("while".str)==0|| strcmp("case". } num[i++]=tokenvalue.h> void keyword(char str[10]) { if(strcmp("for". while((c=getc(f1))!=EOF) { if(isdigit(c)) { tokenvalue=c-'0'. 5 .lineno=0.str[10]. } else if(isalpha(c)) { putc(c. char c."r")."w"). f3=fopen("specialchar". c=getc(f1).j=0. #include<string.str)."w"). printf("\nEnter the c program").str)==0||strcmp("do".*/ f1=fopen("input".

c=getc(f1).c). for(j=0.j<i. printf("\n"). f3=fopen("specialchar". k=0. } else if(c==' '||c=='\t') printf(" "). printf("Total no. } putc(' '. } fclose(f2). else if(c=='\n') lineno++.f2). printf("\nSpecial characters are").j++) printf("%d". fclose(f3).lineno). of lines are:%d"."r"). printf("The keywords and identifiersare:"). ungetc(c. else putc(c.CD LAB PROGRAMS while(isdigit(c)||isalpha(c)||c=='_'||c=='$') { putc(c. printf("\nThe no's in the program are").f3). keyword(str). else { str[k]='\0'. printf("\n"). while((c=getc(f2))!=EOF) { if(c!=' ') str[k++]=c.num[j]). } } fclose(f2)."r"). fclose(f1). fclose(f3). } 6 .f1). k=0. while((c=getc(f3))!=EOF) printf("%c". f2=fopen("identifier".f2).

of lines are: 1 7 .CD LAB PROGRAMS Output: Enter the C program a+b*c Ctrl-D The no’s in the program are: The keywords and identifiers are: a is an identifier and terminal b is an identifier and terminal c is an identifier and terminal Special characters are: +* Total no.

* { printf("\n%s is a PREPROCESSOR DIRECTIVE".}*/ "*/" {COMMENT = 0. /* program name is lexp.CD LAB PROGRAMS 2)Implement the Lexical Analyzer Using Lex Tool.}*/ {identifier}\( {if(!COMMENT)printf("\n\nFUNCTION\n\t%s".yytext).} \} {if(!COMMENT) printf("\n BLOCK ENDS").yytext).} /*{printf("\n\n\t%s is a COMMENT\n".} /* printf("\n\n\t%s is a COMMENT\n".yytext). %} identifier [a-zA-Z][a-zA-Z0-9]* %% #.} 8 .yytext).} \{ {if(!COMMENT) printf("\n BLOCK BEGINS").yytext).l */ %{ /* program to recognize a c program */ int COMMENT=0.} "/*" {COMMENT = 1.} int | float | char | double | while | for | do | if | break | continue | void | switch | case | long | struct | const | typedef | return | else | goto {printf("\n\t%s is a KEYWORD".

ECHO.CD LAB PROGRAMS {identifier}(\[[0-9]*\])? {if(!COMMENT) printf("\n %s IDENTIFIER".} \( = ECHO. {if(!COMMENT)printf("\n\t%s is an ASSIGNMENT OPERATOR"."r").*\" {if(!COMMENT) printf("\n\t%s is a STRING".yytext).} \<= | \>= | \< | == | \> {if(!COMMENT) printf("\n\t%s is a RELATIONAL OPERATOR". } yyin = file. printf("\n\n").argv[1]).} [0-9]+ {if(!COMMENT) printf("\n\t%s is a NUMBER". if(!file) { printf("could not open %s \n". } int yywrap() { return 0. file = fopen(argv[1].printf("\n").char **argv) { if (argc > 1) { FILE *file. exit(0). } yylex().yytext). } 9 .yytext).} \)(\.yytext).)? {if(!COMMENT) printf("\n\t"). return 0.yytext).} %% int main(int argc.} \".

out var.c #include<stdio.l $cc lex.yy. } Output: $lex lex.h> is a PREPROCESSOR DIRECTIVE FUNCTION main ( ) BLOCK BEGINS int is a KEYWORD a IDENTIFIER b IDENTIFIER BLOCK ENDS 10 ./a.CD LAB PROGRAMS Input: $vi var.c $.b.h> main() { int a.c #include<stdio.

} int look_up(char s[ ]) { int k."else"."int"."ret urn"."char". %s \n"."line %d.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]."for". "float". } int insert(char s[ ]. 11 .KEYWORD."double".k>0.KEYWORD.lexptr.KEYWORD.m). void Error_Message(char *m) { fprintf(stderr. char buffer[SIZE]. int tokenval=DONE.h> #include<stdlib. int lineno=1.lineno. for(k=lastentry.KEYWORD.KEYWORD. int lookahead.CD LAB PROGRAMS 3) Implementation of Predictive Parser.KEYWORD. int lastentry=0.KEYWORD.KEYWORD. struct entry { char *lexptr. int token. exit(1).k--) if(strcmp(symtable[k]. int lastchar=-1.KEYWORD."struct". return 0. #include<stdio.int tok) { int len.h> #include<ctype.0. struct entry keywords[]={"if".s)==0) return k. }symtable[100].0}.h> #include<string.

lastentry=lastentry+1. if(lastchar+len+1>=MAX) Error_Message("Lexemes array is full"). t=getchar(). lastchar=lastchar+len+1.ptr->token).&tokenval). else if(t=='\n') lineno=lineno+1. for(ptr=keywords. else if(isdigit(t)) { ungetc(t. symtable[lastentry].ptr+1) insert(ptr->lexptr. int val. return NUM.token=tok. if(t==' '||t=='\t'). if(t!=EOF) 12 . if(i>=SIZE) Error_Message("Compiler error"). if(lastentry+1>=MAX) Error_Message("Symbpl table is full").CD LAB PROGRAMS len=strlen(s). symtable[lastentry]. while(1) { t=getchar(). }*/ int lexer() { int t. i=i+1.lexptr=&lexemes[lastchar+1].lexptr.stdin). } else if(isalpha(t)) { while(isalnum(t)) { buffer[i]=t.ptr->token. strcpy(symtable[lastentry]. } /*void Initialize() { struct entry *ptr.s).i=0. } buffer[i]=EOS. return lastentry. scanf("%d".

CD LAB PROGRAMS ungetc(t.lexptr). return symtable[val]. if(val==0) val=insert(buffer. break. return t. E(). Match(NUM). tokenval=val. else Error_Message("Syntax error"). else printf("\n Token %d tokenval %d". } void display(int t.int tval) { if(t=='+'||t=='-'||t=='*'||t=='/') printf("\nArithmetic Operator: %c".tval). switch(lookahead) { case '(' : Match('('). else { tokenval=NONE. 13 . else if(t==ID) printf("\n Identifier: %s". case NUM : display(NUM.token. break. } void F() { //void E(). } else if(t==EOF) return DONE.symtable[tval].tokenval). Match(')').stdin).tokenval).t). else if(t==NUM) printf("\n Number: %d".ID). } } } void Match(int t) { if(lookahead==t) lookahead=lexer(). val=look_up(buffer).t.

continue. default : return. display(t. default : Error_Message("Syntax error"). case '/' : t=lookahead.NONE).tokenval). Match(lookahead). Match(lookahead). T(). Match(lookahead). Match(lookahead). display(t.NONE). 14 . T().NONE). default : return. } } } void E() { int t. break. continue. case '-' : t=lookahead. display(t. F(). continue.CD LAB PROGRAMS case ID : display(ID. continue. } } void T() { int t. Match(ID). T(). while(1) { switch(lookahead) { case '*' : t=lookahead. F(). display(t. while(1) { switch(lookahead) { case '+' : t=lookahead.NONE).

Identifier: a Identifier: b Identifier: c Arithmetic Operator: * Arithmetic Operator: + 2*3. printf("\n Program for recursive decent parsing "). while(lookahead!=DONE) { E(). line 5. Number: 2 Number: 3 Arithmetic Operator: * +3. at the end Press Ctrl-Z to terminate a+b*c.Syntax error Ctrl-Z 15 . } Output: Program for recursive decent parsing Enter the expression And place . printf("And place .CD LAB PROGRAMS } } } void parser() { lookahead=lexer(). parser(). printf("Press Ctrl-Z to terminate\n"). at the end\n"). } } main() { char ans[10].'). printf("\n Enter the expression "). Match('.

expr: expr '+' term | term .$1). return yytext[0].h> %} %union { double dval.} 16 .*/ #include<stdio.CD LAB PROGRAMS 4) Design LALR Bottom up Parser .tab. return DIGIT.} {$$=$2 . term: term '*' factor | factor .h> #include "y. <parser. %% <parser.y> %{ /*This YACC specification file generates the LALR parser for the program considered in experiment 4.} {$$=$1 * $3 .dval=atof(yytext). factor: '(' expr ')' { printf("%g\n". } {$$=$1 + $3 .l> %{ #include<stdio. } \n|.h" %} %% [0-9]+ {yylval. } %token <dval> DIGIT %type <dval> expr %type <dval> term %type <dval> factor %% line: expr '\n' .

c y.y $cc lex.s).l $yacc –d parser. } yyerror(char *s) { printf("%s".out 2+3 5.0000 17 .CD LAB PROGRAMS | DIGIT .c –ll –lm $. } Output: $lex parser.tab.yy./a. %% int main() { yyparse().

\n LineNo++. if else while int | char | float return IF. %% 18 . return WHILE. return VAR. return yytext[0].yytext).} {number} \< | \> | \>= | \<= | == {strcpy(yylval.} {strcpy(yylval.yytext). .l> %{ #include"y. return NUM.tab. return ELSE.} [ \t] .h" #include<stdio.[0-9]+) %% main\(\) return MAIN.var. {identifier} {strcpy(yylval. return RELOP.h> int LineNo=1. %} identifier [a-zA-Z][_a-zA-Z0-9]* number [0-9]+|([0-9]*\.var. <int.yytext). return TYPE.CD LAB PROGRAMS 5) Convert The BNF rules into Yacc form and write code to generate abstract syntax tree.var.h> #include<string.

char arg1[10]. char arg2[10]. }QUAD[30].y> %{ #include<string. BLOCK: '{' CODE '}' . int top.h> struct quad { char op[5]. struct stack { int items[100]. }stk.tInd. STATEMENT: DESCT '.' 19 .' | ASSIGNMENT '. int Index=0.h> #include<stdio. extern int LineNo.tIndex=0. CODE: BLOCK | STATEMENT CODE | STATEMENT .CD LAB PROGRAMS <int. %} %union { char var[10]. char result[10].Ind.StNo. } %token <var> NUM VAR RELOP %token MAIN IF ELSE WHILE TYPE %type <var> EXPR ASSIGNMENT CONDITION IFST ELSEST WHILELOOP %left '-' '+' %left '*' '/' %% PROGRAM : MAIN BLOCK .

} | EXPR '*' EXPR {AddQuadruple("*". VARLIST: VAR '.$3.result)."==").result.result. strcpy($$. strcpy(QUAD[Index].result. IFST: IF '(' CONDITION ')' { strcpy(QUAD[Index].$$).$$).$1.Index).Index). DESCT: TYPE VARLIST .$1.$3.$3).result.} | '(' EXPR ')' {strcpy($$. Index++.$3).' VARLIST | VAR . Ind=pop().} | '-' EXPR {AddQuadruple("UMIN"."-1").op. push(Index). strcpy(QUAD[Index]. strcpy(QUAD[Index]. } | IFST ELSEST .} | EXPR '/' EXPR {AddQuadruple("/".arg2. } .QUAD[Index++].$2.$$).op."%d". CONDST: IFST{ Ind=pop()."FALSE"). strcpy(QUAD[Index]."="). EXPR: EXPR '+' EXPR {AddQuadruple("+"."").} | EXPR '-' EXPR {AddQuadruple("-".$1).$3.arg2.arg1.$3.$1. sprintf(QUAD[Ind]. sprintf(QUAD[Ind]."%d".CD LAB PROGRAMS | CONDST | WHILEST . strcpy(QUAD[Index].$$). ASSIGNMENT: VAR '=' EXPR{ strcpy(QUAD[Index].$2).$1."".arg1. strcpy(QUAD[Index]. 20 .$$).} | VAR | NUM .

"")."%d"."%d". sprintf(QUAD[Ind]."=="). strcpy(QUAD[Index]."%d". } | VAR | NUM .arg1. strcpy(QUAD[Index].StNo).$$).op."%d".$3.arg1. Index++.result. strcpy(QUAD[Index]. Index++. sprintf(QUAD[Ind]."GOTO").result. StNo=Index-1.Index). WHILEST: WHILELOOP{ Ind=pop(). sprintf(QUAD[Ind]. sprintf(QUAD[Ind].Index). ELSEST: ELSE{ tInd=pop().$3).$1.Index).CD LAB PROGRAMS } BLOCK { strcpy(QUAD[Index]. strcpy(QUAD[Index]. strcpy(QUAD[Index].result. Ind=pop(). Ind=pop(). push(Index).arg2."-1")."FALSE"). push(tInd).result. WHILELOOP: WHILE '(' CONDITION ')' { strcpy(QUAD[Index]. } BLOCK { 21 . } BLOCK{ Ind=pop().result. strcpy(QUAD[Index].result. } .arg2."-1"). } . } .""). CONDITION: VAR RELOP VAR {AddQuadruple($2. push(Index).op.

op.top++. push(Index). } printf("\n\t\t -----------------------").""). } yyparse().char *argv[]) { FILE *fp."GOTO"). if(argc>1) { fp=fopen(argv[1]. } yyin=fp. printf("\n\n"). Index++. return 0. strcpy(QUAD[Index].result).result.QUAD[i].top==100) { printf("\n Stack overflow\n"). if(stk. int main(int argc."").op.CD LAB PROGRAMS strcpy(QUAD[Index].arg1.items[stk. exit(0). strcpy(QUAD[Index]. %% extern FILE *yyin.QUAD[i].i.arg2.arg2."r"). } void push(int data) { stk. } . exit(0)."-1"). int i.top]=data.QUAD[i].QUAD[i]. strcpy(QUAD[Index].i++) { printf("\n\t\t %d\t %s\t %s\t %s\t %s". for(i=0. } 22 .i<Index.arg1. } stk. printf("\n\n\t\t ----------------------------""\n\t\t Pos Operator Arg1 Arg2 Result" "\n\t\t --------------------"). if(!fp) { printf("\n File not found").

arg2. } Input: $vi test. if(a<b) { a=a+b."t%d".QUAD[Index++].char arg1[10]. return data.CD LAB PROGRAMS int pop() { int data.c main() { int a. } if(a<=b) { c=a-b.top==-1) { printf("\n Stack underflow\n"). sprintf(QUAD[Index].op).op.tIndex++). } yyerror() { printf("\n Error on line no:%d". } else { c=a+b.arg1). strcpy(QUAD[Index].result. if(stk.char result[10]) { strcpy(QUAD[Index]. strcpy(QUAD[Index].arg1.result). } data=stk.char arg2[10]. exit(0).b.items[stk. strcpy(result. } void AddQuadruple(char op[5].arg2). } while(a<b) { a=a+b. 23 .c.LineNo).top--].

tab.c –ll –lm $.c Pos 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Operator < == + = GOTO < == + = GOTO <= == = GOTO + = Arg1 a to a t1 Arg2 b FALSE b 5 Result to t1 a 5 a t2 a t3 FALSE b 10 b t2 t3 a 5 a t4 a t5 b FALSE b t4 15 t5 c 17 a t6 b t3 c ___________________________________________________ 24 .out test./a.yy.l $yacc –d int.CD LAB PROGRAMS } } Output: $lex int.y $gcc lex.c y.

char fname[10]."[]=")==0) { fscanf(fp1.operand1. printf("\n Enter filename of the intermediate code"). fprintf(fp2. exit(0).operand1."\n\t JMP %s."w")."\nlabel#%d". #include<stdio.&fname).operand2)."%s". fscanf(fp1.result). } while(!feof(fp1)) { fprintf(fp2."goto")==0) { fscanf(fp1.operand1."r"). fp2=fopen("target. fprintf(fp2.result[8]."print")==0) { fscanf(fp1.operand1. } if(strcmp(op. char operand1[8]. int no=0."\n\t STORE %s[%s].h> #include<stdlib.op[10].operand2.h> int label[20]."uminus")==0) 25 . fp1=fopen(fname. fprintf(fp2.operand2). if(strcmp(op.op).ch.i).%s".label#%s". scanf("%s". } if(strcmp(op. int main() { FILE *fp1."%s". label[no++]=atoi(operand2). i++.*fp2."%s %s %s".result).result)."\n\t OUT %s".CD LAB PROGRAMS 6) A Program to Generate Machine Code.operand2[8].result)."%s %s". int i=0.h> #include<string. if(fp1==NULL || fp2==NULL) { printf("\n Error opening the file"). } if(strcmp(op.txt".operand2."\n"). if(check_label(i)) fprintf(fp2.j=0.

fprintf(fp2.R0").result).operand1."\n \t STORE R0."\n \t DIV R1. fprintf(fp2.operand2. fprintf(fp2."\n \t LOAD %s."\n \t LOAD %s.operand2."%s %s %s".R0")."\n \t LOAD %s.R1".R0".result)."%s %s %s"."\n \t LOAD %s.R1"."\n\t JGT %s.operand1).R0").operand2."%s %s %s". fprintf(fp2. break. fprintf(fp2."%s %s".operand1)."\n \t LOAD %s."\n \t STORE R0. fprintf(fp2. case '/': fscanf(fp1. fprintf(fp2."\n \t DIV R1.R1".result). case '+': fscanf(fp1.R0".operand1."\n \t LOAD %s.%s".R0").operand2.%s"."\n \t STORE R0.operand1.CD LAB PROGRAMS { fscanf(fp1.R0".R1". fprintf(fp2.result). label[no++]=atoi(result). fprintf(fp2."%s %s".operand2).operand2)."\n \t SUB R1. 26 .operand1. case '%': fscanf(fp1. case '-': fscanf(fp1.result).result). fprintf(fp2. break.result).operand2)."%s %s %s". break.operand1). fprintf(fp2. fprintf(fp2.result)."\n \t LOAD %s. fprintf(fp2.result).operand1.operand1). break."\n \t LOAD %s. fprintf(fp2. fscanf(fp1. case '=': fscanf(fp1.%s"."\n\t STORE %s %s".%s". fprintf(fp2.result)."\n \t LOAD". } switch(op[0]) { case '*': fscanf(fp1. fprintf(fp2.operand1."\n\t STORE R1.R1". fprintf(fp2.operand1)."\n \t LOAD %s.operand2. break.result)."%s %s %s".operand2).operand1. break.result)."%s %s %s"."\n \t MUL R1. fprintf(fp2. fprintf(fp2.result). fprintf(fp2. fprintf(fp2.%s".operand2.result)."\n\t LOAD -%s. break.label#%s". fprintf(fp2.R0".operand1).operand1). fprintf(fp2.%s".operand1. fprintf(fp2. fprintf(fp2.R1".R0")."\n \t LOAD %s.operand1."\n \t STORE R0.result). case '>': j++.result).operand2.operand2)."\n \t ADD R1."\n \t STORE R0.R0".

CD LAB PROGRAMS case '<': fscanf(fp1."%s %s %s".result). return 0. } int check_label(int k) { int i. fprintf(fp2.txt"."\n \t LOAD %s. fprintf(fp2.R0".operand2."\n\t JLT %s. if(fp2==NULL) { printf("Error opening the file\n"). fclose(fp1). label[no++]=atoi(result). printf("%c". } return 0. }while(ch!=EOF). } do { ch=fgetc(fp2). for(i=0.operand2. exit(0). fp2=fopen("target. fclose(fp1).label#%d".operand1.i<no. break.txt =t1 2 []=a 0 1 []=a 1 2 []=a 2 3 *t1 6 t2 +a[2] t2 t3 27 . } } fclose(fp2)."r").result).ch).operand1). } Input: $vi int.i++) { if(k==label[i]) return 1.

R1 ADD R1.R0 LOAD t2.R0 STORE R0.t3 LOAD a[2].R0 STORE R0.2 STORE a[2].CD LAB PROGRAMS -a[2] t1 t2 /t3 t2 t2 uminus t2 t2 print t2 goto t2 t3 =t3 99 uminus 25 t2 *t2 t3 t3 uminus t1 t1 +t1 t3 t4 print t4 Output: Enter filename of the intermediate code: int.txt STORE t1.t2 LOAD t2.R0 LOAD t1.R1 DIV R1.R1 SUB R1.R1 ADD R1.t2 LOAD t3.2 STORE a[0].R0 LOAD t2.R0 STORE R0.3 LOAD t1.1 STORE a[1].R0 STORE R0.R0 JGT 5.t3 LOAD a[t2].t2 LOAD t2.R0 LOAD 6.R1 STORE R1.label#11 28 .

t2 LOAD t2.R1 STORE R1.t4 OUT t4 29 .R0 LOAD t3.label#13 Label#13: STORE t3.t3 LOAD t1.R1 STORE R1.R0 STORE R0.CD LAB PROGRAMS Label#11: OUT t2 JMP t2.99 LOAD 25.R1 MUL R1.R0 STORE R0.R0 LOAD t3.R1 ADD R1.t1 LOAD t1.

Master your semester with Scribd & The New York Times

Special offer for students: Only $4.99/month.

Master your semester with Scribd & The New York Times

Cancel anytime.