Rajalakshmi Institute of Technology Chennai: Department of Computer Science and Engineering
Rajalakshmi Institute of Technology Chennai: Department of Computer Science and Engineering
CS2352 PRINCIPLES OF COMPILER DESIGN LAB MANUAL PREPARED BY, R. VELUMADHAVA RAO (AP/CSE)
SEMESTER VI 2012-2013
ALGORITHM: 1. Start the program. 2. Declare the file pointer and necessary variables. 3. Open the input file in the read mode. 4. Use the analyze function to analyze the input program and store the identifiers, keywords and operator on idhd, keyhd, ophd respectively. 5. Stores the tokens in data structure linked lists. 6. Increment the line number of each token and its occurrences. 7. Using the show function print the linked lists in a tabular format. 8. Stop the program.
PROGRAM
#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 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
fprintf(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(char s[],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[lastentry+1]; lastchar = lastchar + len + 1; strcpy(symtable[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=='<='||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; } } } int main() { int lookahead; char ans; 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(); } return 0; }
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(a<b) a=a+b; Keyword Parenthesis Identifier: a Relational Operator Identifier: b Parenthesis Identifier: a Assigment Operator Identifier: a Operator Identifier: b ^Z
RESULT:
Thus the implementation of lexical analyzer was successfully done.
PROGRAM
%{ %} identifier[a-zA-Z][a-zA-Z0-9]* %% #.* {printf("\n%s is a preprocessor directive",yytext);} int | float | char | double | while | do | if | break | continue | void | switch | return | else | goto {printf("\n%s is a keyword",yytext);} {identifier}\( {printf("\n function %s",yytext);} \{ {printf("\nblock begins");} \} {printf("\nblock ends");} \( {printf("\n");ECHO;} {identifier}(\[[0-9]*\])* {printf("\n%s is an identifier",yytext);} \".*\" {printf("\n %s is a string ",yytext);} [0-9]+ {printf("\n%s is a number",yytext); } \<= | \>= | \< | \> | \== {printf("\n %s is a relational operator",yytext);}
\= | \+ | \- | \/ | \& | % {printf("\n %s is a operator",yytext);} .| \n; %% int main(int argc,char **argv) { FILE *file; file=fopen("inp.c","r"); if(!file) { printf("could not open the file!!!"); exit(0); } yyin=file; yylex(); printf("\n\n"); return(0); } int yywrap() { return 1; }
INPUT FILE:
#include<stdio.h> void main() { int a,b,c; printf("enter the value for a,b"); scanf("%d%d",&a,&b)'; c=a+b; printf("the value of c:%d",&c); }
OUTPUT:
[3cse01@localhost ~]$ lex ex3.l [3cse01@localhost ~]$ cc lex.yy.c [3cse01@localhost ~]$ ./a.out #include<stdio.h> is a preprocessor directive void is a keyword function main( block begins int is a keyword a is an identifier b is an identifier c is an identifier function printf( "enter the value for a,b" is a string function scanf( "%d%d" is a string & is a operator a is an identifier & is a operator b is an identifier c is an identifier = is a operator a is an identifier + is a operator b is an identifier function printf( "the value of c:%d" is a string & is a operator c is an identifier block ends
RESULT: Thus the program to implement the lexical analyzer using lex tool for a subset of C language was implemented and verified.
ALGORITHM: 1. Start the program. 2. Get the expression from the user and call the parser() function. 3. In lexer() get the input symbol and match with the look ahead pointer and then return the token accordingly. 4. In E(), check whether the look ahead pointer is + or - else return syntax error. 5. In T(),check whether the look ahead pointer is * or / else return syntax error. 6. In F(),check whether the look ahead pointer is a member of any identifier. 7. In main(), check if the current look ahead points to the token in a given CFG it doesnt match the return syntax error.
PROGRAM
#include<stdio.h> #include<string.h> #include<stdlib.h> #define DONE 260 #define NUM 257 #define ID 259 void E(); void T(); void F(); void parser(); int lexer(); void match(int); void parsex(); int i=0,flag=9,lkahd; char inp[75]; int cnt=-1; int main() { int i=-1; char c; FILE *fp; fp=fopen("ep1.text","rt"); while((c=fgetc(fp))!=EOF) { inp[i++]=c; } inp[i]=EOF;
parser(); }
int lexer() { int t; while(1) { t=inp[cnt++]; if(t==' '||t=='\t'||t=='\n') ; else if(t=='+'||t=='-'||t=='*'||t=='/') { printf("arithmetic operator %c\n",t); return t; } else if(isdigit(t)) { printf("\n number: %c\n",t); return NUM; } else if(isalpha(t)) { printf("\n identifier: %c\n",t); return ID; } else if(t==EOF) return DONE; else return t; }} void parser() { lkahd=lexer();
while(lkahd!=DONE) { E(); match(';'); } if(lkahd==DONE) parsex(); } void match(int t) { if(lkahd==t) lkahd=lexer(); else return; } void F() { switch(lkahd) { case '(': match('('); E(); match(')'); break; case NUM: match(NUM); break; case ID: match(ID); break; default:{ printf("syntax error"); flag=7; }}}
void T() { int t; F(); while(1) { switch(lkahd) { case '*': t=lkahd; match(lkahd); F(); continue; case '/': t=lkahd; match(lkahd); F(); continue; default: return; }}} void E() { int t; T(); while(1) { switch(lkahd) { case '+': t=lkahd; match(lkahd); T(); continue;
case '-': t=lkahd; match(lkahd); T(); continue; default: return; }}} void parsex() { if(flag!=7) printf("parse seccessfull\n"); else printf("parse successfull\n errors found\n"); exit(0); }
OUTPUT: [3cse01@localhost ~]$ cc ex4.c [3cse01@localhost ~]$ ./a.out identifier: a arithmetic operator + identifier: b arithmetic operator * identifier: c arithmetic operator / identifier: d arithmetic operator identifier: g number: 1 arithmetic operator + number: 5 number: 5 arithmetic operator number: 3 identifier: a arithmetic operator + number: 2 parse seccessfull
RESULT: Thus the program to implement the recursive descent parser was implemented and verified.