Compiler_Design Lab Manual
April 20, 2017 | Author: Priya R Chourasia | Category: N/A
Short Description
Download Compiler_Design Lab Manual...
Description
1. Develop a lexical analyzer to recognize a few patterns in PASCAL and C. (Ex. identifiers, constants, comments, operators etc.) #include #include #include #include #include #define SIZE 128 #define NONE -1 #define EOS ‘\0’ #define NUM 256 #define KEYWORD 257 #define PAREN 258 #define ID 259 #define ASSIGN 260 #define REL_OP 261 #define DONE 262 #define MAX 999 char lexemes[MAX]; char buffer[SIZE]; int lastchar = -1; int lastentry = 0; int tokenval=NONE; int lineno=1; struct entry { char *lexptr; int token; }symtable[100]; struct entry keywords[]={“if”,KEYWORD,”else”,KEYWORD,”for”,KEYWORD, “int”,KEYWORD,”float”,KEYWORD,”double”,KEYWORD,”char”,KEYWORD, “struct”,KEYWORD,”return”,KEYWORD,0,0}; void Error_Message(char *m) { fprint(stderr,”line %d: %s”,lineno,m); exit(1); } int look_up(char s[]) { int k; for(k=lastentry;k>0;k--) if(strcmp(symtable[k].lexptr,s)==0) return k; return 0; }
int insert(chars[],int tok) { int len; len=strlen(s); if(lastentry+1>=MAX) Error_Message(“Symbol Table is Full”); if(lastchar+len+1>=MAX) Error_Message(“Lexemes Array is Full”); lastentry++; symtable[lastentry].token=tok; symtable[lastentry].lexptr=&lexemes[lastcher+1]; lastchar = lastchar + len + 1; strcpy(smtable[lastentry].lexptr,s); return lastentry; } void Initialize() { 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++; else if(t == ’(‘ || t == ‘)’) return PAREN; else if(t==‘’ ||t==‘=’ ||t == ‘!=’) return REL_OP; else if(t == ’=’) return ASSIGN; 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++; if(i>=SIZE) Error_Message(“compiler error”); } buffer[i]=EOS; if(t!=EOF) ungetc(t,stdin); val=look_up(buffer); if(val==0) val=insert(buffer,ID); tokenval=val; return symtable[val].token; } else if(t==EOF) return DONE; else { tokenval=NONE; return t; } } } void main() { int lookahead; char ans; clrscr(); printf(“\n]t]t Program for Lexical Analysis \n”); Initialize(); printf(“\n Enter the expression and put ; at the end”); printf(“\n Press Ctrl + Z to terminate... \n”); lookahead=lexer(); while(lookahead!=DONE) { if(lookahead==NUM) printf(“\n Number: %d”,tokenval); if(lookahead==’+’|| lookahead==’-’|| lookahead==’*’|| lookahead==’/’) printf(“\n Operator”); if(lookahead==PAREN) printf(“\n Parentesis”); if(lookahead==ID)
printf(“\n Identifier: %s“, symtable[tokenval].lexptr); if(lookahead==KEYWORD) printf(“\n Keyword); if(lookahead==ASSIGN) printf(“\n Assignment Operator”); if(lookahead==REL_OP) printf(“\n Relataional Operator”); lookahead=lexer(); } }
OUTPUT: Program for Lexical Analysis Enter the expression and put ; at the end Press Ctrl + Z to terminate ... 2+3 Number: 2 Operator Number: 3 if(a0;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) errormsg("symtable is full"); if(lastentry+len+1>=MAX) errormsg("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) errormsg("compile error"); } buffer[i]=EOS; if(t!=EOF) ungetc(t,stdin); val=lookup(buffer); if(val==0) val=insert(buffer,ID); tokenval=val; 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 errormsg("syntax error"); } void display(int t,int tval) { if(t=='+'||t=='-'||t=='*'||t=='/') printf("\n arithmetic 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: errormsg("syntax error"); } } void T() { int t; F(); while(1) { switch(lookahead)
{ case '*': t=lookahead; 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(';'); } } int main() { char ans; clrscr();
printf("\n \t \t Program for recursive decent parsing"); initialise(); printf("enter the expression & place;at the end \n Press CTRL + Z to terminate"); parser(); return 0; }
OUTPUT: Program for recursive decent parsing Enter the expression & place ; at the end Press CTRL + Z to terminate 2+3*4; number 2 number 3 number 4 arithmetic operator * arithmetic operator + 2+3*4+5; number 2 number 3 number 4 arithmetic operator * arithmetic operator + number 5 arithmetic operator + a-b; identifier a identifier b arithmetic operator – +1 Line7: syntaxerror
3. Write a program for generating for various intermediate code forms: ● Three address code ● Quadruple /*
Program name: intcode.l */
%{ #include”y.tab.h” extern char yyval; %} NUMBER [0-9]+ LETTER [a-zA-Z]+ %% {NUMBER} {yylval.sym=(char)yytext[0];return NUMBER;} {LETTER} {yylval.sym=(char)yytext[0];return LETTER;} \n
{return 0;} {return yytext[0];}
%% /*
Program name: intcode.y */
%{ #include #include int nIndex=0; struct InterCode { char operand1; char operand2; char opera; }; %} %union { char sym; } %token LETTER NUMBER %type expr %left ‘-’ ‘+’ %right ‘*’ ’/’ %% statement: LETTER ‘=’ expr ‘;’
{AddToTable((char)$1.(char)$3,’=’);} | expr ‘;’ ; expr :expr ‘+’ expr {$$ = AddToTable((char)$1.(char)$3,’+’);} |expr ‘-’ expr {$$ = AddToTable((char)$1.(char)$3,’-’);} |expr ‘*’ expr {$$ = AddToTable((char)$1.(char)$3,’*’);} |expr ‘/’ expr {$$ = AddToTable((char)$1.(char)$3,’/’);} |’(‘expr’)’ {$$=(char)$2;) | NUMBER {$$=(char)$1;} | LETTER {$$=(char)$1;} ; %% yyerror(char *s) { printf(“%s”,s); exit(0); } struct InterCode Code[20]; char AddToTable(char operand1,char operand2,char opera) { char temp = ’A’; Code[nIndex].operand1=operand1; Code[nIndex].operand2=operand2; Code[nIndex].opera=opera; nIndex++; temp++; return temp; } ThreeAddressCode() { int nCnt=0; char temp =’A’; printf(“\n\n\t THREE ADDRESS CODE\n\n”); temp++; while(nCnt=10) Program name: anb.l %{ /*Lex Program for anb(n>=10)*/ %} %% a {return A;} b {return B;} . {return yytext[10];} \n return('\n'); %% int yywrap() { return 1; }
Program name:anb.y %{ /*YACC program for recognising anb(n>=10)*/ %} %token A B %% stmt:A A A A A A A A A A anb'\n'{printf("\n Valid string"); return 0; } ; anb:A anb |A B ; %% main() { printf("\nEnter some valid string\n"); yyparse(); } int yyerror(char*s) { printf("\nInvalid string\n"); }
Output: [root@localhost]# [root@localhost]# [root@localhost]# [root@localhost]#
lex anb.1 yacc -d anb.y gcc lex.yy.c y.tab.c ./a.out
Enter some valid string aaaaaaaaab Invalid string [root@localhost]# ./a.out Enter some valid string aaaaaaaaaaab Valid string [root@localhost]#
d) Implementation of Calculator using LEX and YACC Program name:calci.l %{ #include "y.tab.h" /*defines the tokens*/ #include ,math.h. %} %% /*To recognise a valid number*/ ([0-9] + |([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {yylval.dval = atof(yytext); return NUMBER;} /*For log no | Log no (log base 10)*/ log | LOG {return LOG;} /*For ln no (Natural Log)*/ ln {return nLOG;} /*For sin angle*/ sin | SIN {return SINE;} /*For cos angle*/ cos | COS {return COS;} /*For tan angle*/ tan | TAN {return TAN;} /*For memory*/ mem {return MEM;} [\t]
\$
\n| %%
;
/*Ignore white spaces*/
/*End of input*/ {return 0;} /*Catch the remaining and return a single character token to the parser*/ return yytext[0];
Program Name : calci.y %{ double memvar; %} /*To define possible symbol types*/ %token NUMBER %token MEM %token LOG SINE nLOG COS TAN /*Defining the precedences and associativity*/ %left ‘-’ ‘+’ /*Lowest precedence*/ %left ‘*’ ‘/’ %right ‘^’ %left LOG SINE nLOG COS TAN /*Highest precence*/ /*No associativity*/ %nonassoc UMINUS /*Unary Minus*/ /*Sets the type for non-terminal*/ %type expression %% /*Start state*/ start: statement ‘\n’ | start statement ‘\n’ ; /*For storing the answer(memory)*/ statement: MEM’=’ expression {memvar=$3;} | expression {printf(“Answer = %g\n”,$1);} ; /*For printing the Answer*/
/*For binary arithmetic operations*/ expression: expression ‘+’ expression {$$ = $1 + $3;} | expression ‘-’ expression {$$ = $1 - $3;} | expression ‘*’ expression {$$ = $1 * $3;} | expression ‘/’ expression { /*Tohandle divide by zero case*/ If($3 == 0) yyerror(“divide by zero”); else $$ = $1 / $3; } | expression ‘^’ expression {$$ = pow($1,$3);} ;
/*For unary operators*/ expression: ‘-’expression %prec UMINUS {$$ = -$2;} /*%prec UMINUS signifies that unary minus should have the highest precedence*/
| | | | | | | | ;
‘(’ expression ‘)’ {$$ = $2} LOG expression {$$ = log($2)/log(10);} nLOG expression {$$ = log($2);} */Trigonometric functions*/ SINE expression {$$ = sin($2 * 3.141592654 / 180);} COS expression {$$ = cos($2 * 3.141592654 / 180);} TAN expression {$$ = tan($2 * 3.141592654 / 180);} NUMBER {$$ = $1;} MEM {$$ = $1;} /*Retrieving the memory contents*/
%% main() { printf(“Enter the expression:”); yyparse(); } int yyerror(char *error) { fprintf(stderr,”%s\n”,error); }
Output: The output of the program can be obtained by following commands [root@localhost]]# lex calci.l [root@localhost]]# yacc –d calci.y [root@localhost]]# cc y.tab.c lexyy.c –ll –ly –lm [root@localhost]]# ./a.out Enter the expression: 2+@ Answer = 4 2 * 2 + 5 / 4 Answer = 5.25 mem = cos 45 sin 45/mem Answer = 1 ln 10 Answer = 2.30259
8. Given any intermediate code form implement code optimization techniques. /******************************************************************* Program for Code Optimization Technique of Constant Folding *******************************************************************/ #include #include #include #include #include struct ConstFold ( char new_Str[10]; char str[10]; }Opt_Data[20]; void ReadInput(char Buffer[],FILE *Out_file); int Gen_token(char str[],char Tokens[][10]); int New_Index=0; int main() { file *In_file,*Out_file; char Buffer[100],ch; int i=0; In_file = fopen(“d:\\code.txt”,”r”); Out_file = fopen(“d:\\output.txt”,”w”); clrscr(); while(1) { Ch = fgetc(In_file); i=0; while(1) { If(ch == ‘\n’) break; Buffer[i++]=ch; ch = fgetc(_file); if(ch == EOF) break; }//End while if(ch ==EOF) break; Buffer[i]=’\0’; ReadInput(Bufer, Out_file);//writing to the output file }//End while return 0; }//End main
void ReadInput(char Buffer[],FILE *Out_file) { char temp[100],Token[10][10]; int n,I,j,flag=0; strcpy(temp,Buffer); n= Gen_token(temp,Token); for(i=0;i
View more...
Comments