compiler_design lab manual

45
1. Develop a lexical analyzer to recognize a few patterns in PASCAL and C. (Ex. identifiers, constants, comments, operators etc.) #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 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; }

Upload: priya-chourasiya

Post on 14-Sep-2014

839 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Compiler_Design Lab Manual

1. Develop a lexical analyzer to recognize a few patterns in PASCAL and C.(Ex. identifiers, constants, comments, operators etc.)

#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 999char 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;}

Page 2: Compiler_Design Lab Manual

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==‘<=’ ||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)){

Page 3: Compiler_Design Lab Manual

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)

Page 4: Compiler_Design Lab Manual

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 AnalysisEnter the expression and put ; at the endPress Ctrl + Z to terminate ...2+3Number: 2OperatorNumber: 3if(a<b) a=a+b;

KeywordParenthesisIdentifier: aRelational OperatorIdentifier: bParenthesisIdentifier: aAssigment OperatorIdentifier: aOperator Identifier: b^Z

Page 5: Compiler_Design Lab Manual

2. Develop a recursive decent parser

#include<stdio.h>#include<ctype.h>#include<stdlib.h>#include<string.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;int lineno=1;int lookahead;

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 errormsg(char *m){

fprintf(stderr,"line %d:%s\n",lineno,m);exit(1);

}

int lookup(char s[]){

int k;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){

Page 6: Compiler_Design Lab Manual

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)

Page 7: Compiler_Design Lab Manual

return DONE;else{ tokenval=NONE;

return t;}

}}

void match(int t){

if(lookahead==t)lookahead=lexer();

elseerrormsg("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);

elseprintf("\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)

Page 8: Compiler_Design Lab Manual

{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();

Page 9: Compiler_Design Lab Manual

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 endPress CTRL + Z to terminate2+3*4;

number 2number 3number 4arithmetic operator *arithmetic operator +

2+3*4+5;number 2number 3number 4arithmetic operator *arithmetic operator +number 5arithmetic operator +

a-b;identifier aidentifier barithmetic operator –

+1Line7: syntaxerror

Page 10: Compiler_Design Lab Manual

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<stdio.h>#include<string.h>int nIndex=0;

struct InterCode{

char operand1;char operand2;char opera;

};%}

%union{

char sym;}

%token <sym> LETTER NUMBER%type <sym> expr%left ‘-’ ‘+’%right ‘*’ ’/’%%statement: LETTER ‘=’ expr ‘;’

Page 11: Compiler_Design Lab Manual

{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<nIndex){

printf(“%c : =\t”,temp);if(isAlpha(Code[nCnt]].operand1))

printf(“%c\t”,Code[nCnt].operand1);else

printf(“%c\t”,temp);printf(“%c\t”,Code[nCnt].opera);

if(isAlpha(Code[nCnt]].operand2))printf(“%c\t”,Code[nCnt].operand2);

else

Page 12: Compiler_Design Lab Manual

printf(“%c\t”,temp);printf(“\n”);nCnt++;temp++;

}}

void Quadruples(){

int nCnt=0;char temp =’A’;temp++;printf(“\n\n\t QUADRUPLES\n”);printf(“\n ID OPERATOR OPERAND1 OPERAND2 RESULT\n”);

while(nCnt<nIndex){

printf(“\n(%d)\t%c\t”,nCnt,Code[nCnt].opera);if(isAlpha(Code[nCnt]].operand1))

printf(“%c\t”,Code[nCnt].operand1);else

printf(“%c\t”,temp);

if(isAlpha(Code[nCnt]].operand2))printf(“%c\t”,Code[nCnt].operand2);

elseprintf(“%c\t”,temp);

printf(“%c\t”,temp);nCnt++;temp++;

}}

main(){

printf(“\nEnter The Expression”);yyparse();ThreeAddressCode();Quadruples();

}

yywrap(){

return 1;}

Page 13: Compiler_Design Lab Manual

Output:[root@localhost]# lex intcode.l[root@localhost]# yacc -d intcode.y[root@localhost]# ./a.out

Enter The Expression: a=b+c*d/e;

THREE ADDRESS CODEB:= d / eC:= c * BD:= b + BE:= a = B

QUADRUPLESID OPERATOR OPERAND1 OPERAND2 RESULT(0) / d e B(1) * c B C(2) + b B D(3) = a B E

[root@localhost]# ./a.out

Enter The Expression: a=(b)+(c*d)/e

THREE ADDRESS CODEB:= c * dC:= B / eD:= b + BE:= a = B

QUADRUPLESID OPERATOR OPERAND1 OPERAND2 RESULT(0) * c d B(1) / B e C(2) + b B D(3) = a B E

Page 14: Compiler_Design Lab Manual

4. Write a program to generate the intermediate code in the form of Polish Notation

#include<stdio.h>#include<conio.h>#include<string.h>#incldue<stdlib.h>

struct stack{char s[30];int top;}st;

void main(){

char input[30];void input_to_code(char infix[30]);clrscr();printf("\n Enter an input in the form of expression ");scanf("%s",input);input_to_code(input);getch();

}

void input_to_code(char input[30]){

st.top=-1;st.s[st.top]='$';char polish[30];int i,j;char ch;int instack(char ch);int incoming(char ch);void push(char item);char pop();j=0;strrev(input);for(i=0;input[i]!='\0';i++) {

ch =input[i];while(instack(st.s[st.top])>incoming(sh)){

polish[j]=pop();j++;

}if(instack(st.s[st.top])!=incoming(ch))

push(ch);else

pop();}

Page 15: Compiler_Design Lab Manual

while((ch=pop()!='$'){

polish[j]=ch;j++;

}polish[j]='\0;;strrev(polish);printf("\n The Polish Notation is %s",polish);

}

int instack(char ch){

int priority;switch(ch){

case ')':priority=0;break;

case '+':case '-':priority=1;

break;case '*';case '/':priority=3;

breakcase '^':priority=6;

break;case '$':priority=-1;

break;default:priority=8;//when it is operand

break;}return priority;

}

int incoming(char ch){

int priority;switch(ch){

case '+':case '-':priority=2;

break;case '*';case '/':priority=4;

breakcase '^':priority=5;

break;case '(':priority=0;

break;case ')':priority=9;

break;default:priority=7;//when it is operand

}return priority;

}

Page 16: Compiler_Design Lab Manual

void push(char item){

st.top++;st.s[st.top]=item;

}

char pop(){

char e;e=st.s[st.top];st.top--;return e;

}

Output:

Enter an input in the form of expression (a+b)*(c-d)

The polish notation is *+ab-cd

Page 17: Compiler_Design Lab Manual

5. Write a program to Simulate Heap storage allocation strategy

/************************************************************Program to perform various operations such as creation,

insertion, deletion, display of heap*************************************************************/#include<stdio.h>#include<conio.h>#include<stdlib.h>#define TRUE 1#include FALSE 0

typedef struct Heap{

int data;struct Heap *next;

}node;

node *create();

void main(){

/*local declarations*/int choice,val;char ans;node *head;void display(node *);node *search(node *,int);node *insert(node *);void dele(node **);head=NULL;do{

clrscr();printf(“\n Program to perform various operations on heap

using dynamic memory management”);printf (“\n1.Create”):printf (“\n2.Display”):printf (“\n3.Insert an element in a list”);printf (“\n4.Delete an element from list”);printf (“\n5.Quit”);printf (“\n Enter Your Choice(1-5)”);scanf(“%d,&choice”);switch(choice){

case 1:head=create();break;

case 2:display(head);break;

case 3:head=insert(head);break;

case 4:dele(&head);break;

case 5:exit(0);

Page 18: Compiler_Design Lab Manual

default:clrscr();printf(“Invalid Choice,Try again”);getch();

}}while(choice!=5);

}

/*The create function creates a list of allocated node*Input:None*Output:Retyurns a pointer to head of list*Parameter Passing Methopd:Node**/

node *create(){

node *temp,*new,* head;int val,flag;char ans=’y’;node *get_node();temp=NULL;flag=TRUE;

/*flag to indicate whether a new node is created for the first time or not*/

do{

printf(“\n Enter the Element”);scanf(“%d”,&val);/*allocate new node*/new =get_node();

if(new==NULL)printf(“\n Memory is not allocated”);new-> data=val;if (flag==TRUE)/* Executed only for the first time*/{

head=new;temp=head; /*head is the first node in the heap*/flag=FALSE;

}else{/*temp keeps track of the most recently created node*/

temp->next=new;temp=new;

}printf(\nDo you want to enter more elements?(y/n)”);ans=getch();

}while(ans= = ‘y’);

printf(“\nThe list is created”);getch();clrscr();return head;

}

Page 19: Compiler_Design Lab Manual

node *get_node(){

node *temp;temp=(node*)malloc(sizeof(node));

//using the mem. Allocation functiontemp->next=NULL;return temp;

}

/**The display function *Input:Address of the first node of the list*Output:Displays the list of allocated nodes*Parameter Passing Method : call by value*Called by main**/

void display(node*head){

node *temp;temp=head;if(temp= =NULL){

printf(“\n The list is empty\n”);getch();clrscr();return;

}while(temp!= NULL){

printf(“%d->”,temp-> data);temp=temp->next;

}print(“NULL”);getch();clrscr();

}

/**The search function *Input: Address of the starting node and the element which is *to be searched*Output:Searches for the element in list*If found returns pointer to that node Otherwise NULL*Parameter passing Method:call by value*Called by:main*Calls:None**/

node *search(node *head,int key){

node*temp;int found;temp=head;if (temp= =Null){

Page 20: Compiler_Design Lab Manual

printf(“The linked list is empty\n”);getch();clrscr();return NULL;

}

found=FALSE;While(temp!= NULL && found= =FALSE){

if(temp->data != key)temp = temp->next;

elsefound = True;

}

if(found == TRUE){

printf(“\n The Elements is present in the list”\n);getch();return temp;

}else

printf(“\n The Element is not present in the list\n”);getch();return NULL;

}

/**The insert function*Input: Address of starting node of the list*Output:inserts element into the list*Parameter Passing Methods: call by value*Called by : main*Calls : search()**/

node *insert(node *head){

int choice;node *insert_head(node*);void insert_after(node*);void insert_last(node*);printf(“\n”1.Insert a node as a head node”);printf(“\n”1.Insert a node as a last node”); printf(“\n”1.Insert a node as at the intermediate position in

the list ”); printf(“\n”1.Enter your choice for insertion of node ”); scanf(“%d”,&choice);switch(choice){

case 1:head = insert_head(head);break;

case2:insert_last(head);break;

case2:insert_after (head);break;

Page 21: Compiler_Design Lab Manual

}return head;

}

/*Insertion of node at first position*/

node *insert_head(node*head){

node *New,*temp;New = get_node();printf (“\n Enter the element which you want to insert ”);scanf(“%d”,&New->data);if(head == NULL)head = New;else{

temp=head;New->next = temp;head= New;

}return head;

}

/*Insertion of node at last position*/

void insert_last(node *head) {

node *New,*temp;New = get_node();printf (“\n Enter the element which you want to insert ”);scanf(“%d”,&New->data);if(head == NULL){

head = New;}else{

temp=head;while(temp->next!=NULL)temp=temp->next;temp->next=New;New->next=NULL;

}}

/*Insertion of node at intermediate position*/

void insert_after(node *head) {

int key;node *New,*temp;New = get_node();printf(“Enter the element after which you want to insert ”);scanf(“%d”,&key);temp=head;

Page 22: Compiler_Design Lab Manual

do{

if(temp->data==key) {

printf (“Enter element which you want to insert ”);scanf(“%d”,&New->data);New->next=temp->next;temp->next=New;return;

}else

temp=temp->next;}while(temp!=NULL);

}

/**The get prev function*Input: Address of starting node and the elemnt to be *searched*Output:looks for the element in the list*If found returns pointer to the previous node otherwise NULL*Parameter Passing Methods: call by value*Called by : dele()*Calls : none**/

node *get_prev(node *head,int val){

node*temp.*prev;int flag;temp = head;if(temp == NULL)

return NULL;flag = FALSE;prev = NULL;while(temp!=NULL && !flag){

if(temp->data!=val){

prev = temp;temp = temp->next;

}else

flag = TRUE;}

if(flag) /*if Flag is true*/return prev;

elsereturn NULL;

}

Page 23: Compiler_Design Lab Manual

/* *The get prev function*Input: Address of starting node and the elemnt to be *searched*Output:looks for the element in the list*If found returns pointer to the previous node otherwise NULL*Parameter Passing Methods: call by value*Called by : dele()*Calls : none**/

void dele(node **head) {

int key;node *New,*temp;temp=*head;if (temp== NULL){

printf (“\n The list is empty\n ”);getch();clrscr();return;

}

clrscr();printf("\nENTER the Element you want to delete:");scanf("%d".&key);temp= search(*head,key);if(temp !=NULL){

prev = get_prev(*head,key);if(prev != NULL){

prev ->next = temp-> next;free(temp);

}else{

*head = temp->next;free(temp); // using the mem. Dellocation function

}printf(“\n”The Element is deleted\n”);getch();clrscr();

}}

Page 24: Compiler_Design Lab Manual

Output:

Program to perform various operations on heap using Dynamic memory management.

1. Create2. Display3. Insert an element in a list4. Delete an element from list5. QuitEnter your choice(1-5) 1

Enter the element: 10

Do you want to enter more elements? (y/n) y

Enter the element:20

Do you want to enter more elements?(y/n)y

Enter the element:30

Do you want to enter more elements?(y/n)n

The List is created

Program to perform various operations on Heap using Dynamic memory management.

1. Create2. Display3. Insert an element in a list4. Delete an element from list5. Quit Enter your choice(1-5) 4

Enter the element you want to delete: 20

The element is present in the list

The element is deleted

Program to perform various operations on Heap using Dynamic memory management.

1. Create2. Display3. Insert an element in a list4. Delete an element from list5. QuitEnter your choice(1-5) 2

10-> 30-> NULL

Page 25: Compiler_Design Lab Manual

6. Generate Lexical analyzer using LEX.

%{/*******************************************************************

Program to obtain tokens from a c program using LEX<lexp.l>

*******************************************************************/ int COMMENT = 0; int cnt = 0;

%}

identifier[a-zA-Z][a-zA-Z0-9]*%%

#.* {printf("\n%is a PREPROCESSOR DIRECTIVE", yytext);}

int |float |char |double |while |for |do |if |break |continue |void |switch |switch |case |long |struct |const |typedef |return |else |goto {printf("\n\t%s is a KEYWORD",yytext);}

"*/" {COMMENT = 1;}

"*/" {COMMENT = 0;}cnt++;}{identifier}\(if(COMMENT){printf("\n\nFUNCTIONAL\n\t%s",yytext);}\{ {if(!COMMENT) printf("\n BLOCK BEGINS");}

\} {if(!COMMENT)printf("\nBLOCK ENDS");}

Page 26: Compiler_Design Lab Manual

{identifier}(\[0-9]*\])? {if(!COMMENT)printf("\n\t%s is an IDENTIFIER",yytext);}

\".*\" {if(!COMMENT)printf("\n\t% is a STRING",yytext);}

[0-9]+ {if(!COMMENT)printf("\n\t%is a NUMBER",yytext);}

\)(\;)? {if(!COMMENT)printf("\n\t");ECHO;print("\n";)}

\( ECHO;= {if(!COMMENT)printf("\n\t%s is an ASSIGNMENT OPERATOR",yytext)}

\+|\- {if(!COMMENT)printf("\n\t%s is an OPERATOR",yytext);}

\<=|\>=|\<|==|\> {if(!COMMENT)printf(\n\t%s is a RELATIONAL OPERATOR",yytext);}

|\n

%%int main(int argc.char**argv){ if(argc>1) { FILE *file'; file fopen(argv[1]."r"); if(file) { printf(“\n Could not open %s”,argv[1]; exit(0); } yyin = file;}yylex();printf(“ \n Total number of comments are %d”,cnt);return 0;

}

int yywrap(){

return 1;}

Page 27: Compiler_Design Lab Manual

Input File:

#include<stdio.h>#include<stdlib.h>

double area_of_circle(double r);

int main(int argc,char *argv[]){if(argc < 2){

printf(“ Usage: %s radius \n”,argv[0]); exit(1);}else{

/* This is a double line comment */ double radius = atof(argv[1]); double area = area_of_circle(radius); printf(“ Area of circle with radius %f = %f \n”,radius,area);}return 0;

}

Page 28: Compiler_Design Lab Manual

Output:

[root@localhost]# lex lexp.l[root@localhost]# gcc lex.yy.c[root@localhost]# ./a.out area.c

#include<stdio.h>#include<stdlib.h>

double is a KEYWORDarea is an INDENTIFIERof is an INDENTIFIERcircle is an INDENTIFIER(double is a KEYWORDr is an INDENTIFIER

);

int is a KEYWORDmain is an INDENTIFIER(int is a KEYWORDargc is an INDENTIFIERchar is a KEYWORDargv[] is an INDENTIFIER

)

BLOCK BEGINSif is a KEYWORD(argc is an INDENTIFIER

< is a RELATIONAL OPERATOR2 is a NUMBER

)

BLOCK BEGINSprintf is an INDENTIFIER(“ Usage: %s radius \n”,is a STRING

argv[0] is an INDENTIFIER);

exit is an INDENTIFIER (1 is a NUMBER

);

BLOCK ENDSelse is a KEYWORD

BLOCK BEGINSdouble is a KEYWORDradius is an INDENTIFIER= is an ASSIGNMENT OPERATOR

Page 29: Compiler_Design Lab Manual

atof is an INDENTIFIER(argv[1]is an INDENTIFIER);

double is a KEYWORDarea is an INDENTIFIER= is an ASSIGNMENT OPERATORarea is an INDENTIFIERof is an INDENTIFIERcircle is an INDENTIFIER(radius is an INDENTIFIER);

printf is an INDENTIFIER(“Area of circle with radius %f = %f \n”, is a STRINGradius is an INDENTIFIERarea is an INDENTIFIER

);

BLOCK ENDSreturn is a KEYWORD0 is a NUMBER

BLOCK ENDSTotal number of comments are 3{root@localhost]#

Page 30: Compiler_Design Lab Manual

7. Generate YACC specification for a few syntactic categories.a) Program to recognize a valid arithmetic expression that uses

operator +, - , * and /.

Program name:arith_id.l

%{/* This LEX program returns the tokens for the expression */#include “y.tab.h”%}

%%“=” {printf(“\n Operator is EQUAL”);}“+” {printf(“\n Operator is PLUS”);}“-“ {printf(“\n Operator is MINUS”);}“/” {printf(“\n Operator is DIVISION”);}“*” {printf(“\n Operator is MULTIPLICATION”);}

[a-z A-Z]*[0-9]* { printf(“\n Identifier is %s”,yytext); return ID; }return yytext[0];

\n return 0;%%

int yywrap(){ return 1;}

Program Name : arith_id.y

%{#include<stdio.h>/* This YYAC program is for recognizing the Expression */%}%%statement: A’=’E| E {

printf(“\n Valid arithmetic expression”); $$ = $1; };

E: E’+’ID | E’-’ID | E’*’ID | E’/’ID | ID;%%extern FILE *yyin;

Page 31: Compiler_Design Lab Manual

main(){do{

yyparse();}while(!feof(yyin));

}

yyerror(char*s){}

Output:

[root@localhost]# lex arith_id.1[root@localhost]# yacc –d arith_id.y[root@localhost]# gcc lex.yy.c y.tab.c[root@localhost]# ./a.outx=a+b;

Identifier is xOperator is EQUALIdentifier is aOperator is PLUSIdentifier is b

b) Program to recognise a valid variable which starts with a letter followed by any number of letters or digits.

Program name: variable_test.l

%{/* This LEX program returns the tokens for the Expression */#include "y.tab.h"%}%%"int " {return INT;}"float" {return FLOAT;}"double" {return DOUBLE;}[a-zA-Z]*[0-9]*{

printf("\nIdentifier is %s",yytext);return ID;

}return yytext[0];

\n return 0;int yywrap(){return 1;}

Page 32: Compiler_Design Lab Manual

Program name: variable_test.y

%{#include <stdio.h>/* This YACC program is for recognising the Expression*/%}%token ID INT FLOAT DOUBLE%%D;T L;L:L,ID |ID;T:INT |FLOAT |DOUBLE;%%extern FILE *yyin;main(){do { yyparse(); }while(!feof(yyin));}yyerror(char*s){}

Output:

[root@localhost]# lex variable_test.I[root@localhost]# yacc –d variable_test.y[root@localhost]# gcc lex.yy.c y.tab.c[root@localhost]# ./a.outint a,b;

Identifier is aIdentifier is b[root@localhost]#

Page 33: Compiler_Design Lab Manual

c) Program to recognise the gramar(anb where n>=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]# lex anb.1[root@localhost]# yacc -d anb.y[root@localhost]# gcc lex.yy.c y.tab.c[root@localhost]# ./a.out

Page 34: Compiler_Design Lab Manual

Enter some valid stringaaaaaaaaab

Invalid string[root@localhost]# ./a.out

Enter some valid stringaaaaaaaaaaab

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] ; /*Ignore white spaces*/

/*End of input*/\$ {return 0;}

/*Catch the remaining and return a single character token to the parser*/

\n| return yytext[0];%%

Page 35: Compiler_Design Lab Manual

Program Name : calci.y

%{double memvar;

%}

/*To define possible symbol types*/%token <dval> NUMBER%token <dval> 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 <dual> 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*/

Page 36: Compiler_Design Lab Manual

| ‘(’ 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 / 4Answer = 5.25

mem = cos 45sin 45/memAnswer = 1

ln 10Answer = 2.30259

Page 37: Compiler_Design Lab Manual

8. Given any intermediate code form implement code optimization techniques.

/*******************************************************************Program for Code Optimization Technique of Constant Folding

*******************************************************************/#include<stdio.h>#include<string.h>#include<conio.h>#include<stdlib.h>#include<ctype.h>

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 whileif(ch ==EOF)break;Buffer[i]=’\0’;ReadInput(Bufer, Out_file);//writing to the output file

}//End whilereturn 0;

}//End main

Page 38: Compiler_Design Lab Manual

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<n;i++){

if(!strcmp(Token[i],”=”)){

if(isdigit(Token[i+1][0])||Token[i+1][0] == ’.’){ /*If yes then saving that number and its variable In the Opt_Data array*/ flag=1; strcpy(Opt_Data[New_Index].New_Str,Token[i-1]); strcpy(Opt_Data[New_Index++].str,Token[i+1]);}//End if

}//End if}//End forif(!flag){

for(i=0;i<New_index;i++){

for(j=0;j<n;j++){

if(!strcmp(Opt_Data[i].new_Str,Token[j]))strcpy(Token[j],Opt_Data[i].str);

}//End for}//End for

}//End iffflush(Out_file);strcpy(temp,””);for(i=0;i<n;i++) /*Loop to obtain complete tokens*/{

strcat(tem,Token[i]);if(Token[i+1][0]!=’,’||Token[i+1][0] != ‘,’)strcat(temp,” “);

}//End forstrcat(temp,”\n\0”);fwrite(&temp,strlen(temp),1,Out_file);

}

/*The Gen_Token function breaks the input line into tokens*/

int Gen_Token(char str[], char Token[][10]){

int i=0;j=0,k=0;while(str[k]!=’\0’){

j=0;while(str[k] ==’ ‘|| str[k] ==’\t’)k++;

Page 39: Compiler_Design Lab Manual

while(str[k])!=’ ’&& str[k]!=’\0’&& str[k]!= ‘=’ && str[k] != ‘/’&& str[k]!= ‘+’ && str[k] != ‘-’&& str[k]!= ‘*’ && str[k] != ‘,’ && str[k]!= ‘;’)

Token[i][j++] = str[k++];Token[i++][j] = ‘\0’;if(str[k] == ‘=’|| str[k] == ‘/’|| str[k] == ‘+’|| str[k] == ‘-’|| str[k] == ‘*’|| str[k] == ‘*’|| str[k] == ‘,’|| str[k] == ‘;’){

Token[i][0] = str[k++];Token[i++][1] = ‘\0’;

}//End ifif (str[k] == ‘\0’)break;

}//End whilereturn i;

}

Input File: code.txt

#include<stdio.h>

main(){

float pi=3.14,r,a;a = pi*r*r;printf(“a = %f”,a);return 0;

}

Output File: output.txt

#include<stdio.h>main(){float pi = 3.14, r, a;a = 3.14 * r * r;printf(“a = %f”,a);return 0;}

Page 40: Compiler_Design Lab Manual

9. Write a program to find FIRST of NON TERMINALS of the given grammar.

#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 { 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') {

Page 41: Compiler_Design Lab Manual

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:

Enter the no. of productions :6Enter the productions :S/aBDhB/cCC/bC/@D/E/FE/g/@F/f/@First(S) : [ a ].First(B) : [ c ].First(C) : [ b,@ ].First(D) : [ g,@,f ].First(E) : [ g,@ ].First(F) : [ f,@ ].

Page 42: Compiler_Design Lab Manual

10. Write a program to find out FOLLOW of NONTERMINALS of givenproductions.

#include"stdio.h"#include<conio.h>#define max 10#define MAX 15char 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 { 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')

Page 43: Compiler_Design Lab Manual

{ 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);

}

Page 44: Compiler_Design Lab Manual

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();}

}

Output:Enter the no. of productions :6Enter the productions :S/aBDhB/cCC/bC/@D/E/FE/g/@F/f/@First(S) : [ a ].First(B) : [ c ].First(C) : [ b,@ ].First(D) : [ g,@,f ].

Page 45: Compiler_Design Lab Manual

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 ]