Compiler Lab Final
Compiler Lab Final
No:1
IMPLEMENTATION OF SYMBOL TABLE
AIM:
ALGORITHM:
1. Start the program for performing insert, display, delete, search and modify
option in symbol table
2. Define the structure of the Symbol Table
3. Enter the choice for performing the operations in the symbol Table
4. If the entered choice is 1, search the symbol table for the symbol to be
inserted. If the symbol is already present, it displays “Duplicate Symbol”.
Else, insert the symbol and the corresponding address in the symbol table.
5. If the entered choice is 2, the symbols present in the symbol table are
displayed.
6. If the entered choice is 3, the symbol to be deleted is searched in the
symbol table.
7. If it is not found in the symbol table it displays “Label Not found”. Else, the
symbol is deleted.
8. If the entered choice is 5, the symbol to be modified is searched in the
symbol table. The label or address or both can be modified.
PROGRAM:
# include <stdio.h>
# include <conio.h>
# include <alloc.h>
# include <string.h>
# define null 0
int size=0;
void insert();
void del();
int search(char lab[]);
void modify();
void display();
1
struct symbtab
{
char label[10];
int addr;
struct symtab *next;
};
struct symbtab *first,*last;
void main()
{
int op;
int y;
char la[10];
clrscr();
do
{
printf("\nSYMBOL TABLE IMPLEMENTATION\n");
printf("1. INSERT\n");
printf("2. DISPLAY\n");
printf("3. DELETE\n");
printf("4. SEARCH\n");
printf("5. MODIFY\n");
printf("6. END\n");
printf("Enter your option : ");
scanf("%d",&op);
switch(op)
{
case 1:
insert();
display();
break;
case 2:
display();
break;
case 3:
2
del();
display();
break;
case 4:
printf("Enter the label to be searched : ");
scanf("%s",la);
y=search(la);
if(y==1)
{
printf("The label is already in the symbol Table");
}
else
{
printf("The label is not found in the symbol table");
}
break;
case 5:
modify();
display();
break;
case 6:
break;
}
}
while(op<6);
getch();
}
void insert()
{
int n;
char l[10];
printf("Enter the label : ");
scanf("%s",l);
3
n=search(l);
if(n==1)
{
printf("The label already exists. Duplicate cant be inserted\n");
}
else
{
struct symbtab *p;
p=malloc(sizeof(struct symbtab));
strcpy(p->label,l);
printf("Enter the address : ");
scanf("%d",&p->addr);
p->next=null;
if(size==0)
{
first=p;
last=p;
}
else
{
last->next=p;
last=p;
}
size++;
}
}
void display()
{
int i;
struct symbtab *p;
p=first;
printf("LABEL\tADDRESS\n");
for(i=0;i<size;i++)
4
{
printf("%s\t%d\n",p->label,p->addr);
p=p->next;
}
}
int search(char lab[])
{
int i,flag=0;
struct symbtab *p;
p=first;
for(i=0;i<size;i++)
{
if(strcmp(p->label,lab)==0)
{
flag=1;
}
p=p->next;
}
return flag;
}
void modify()
{
char l[10],nl[10];
int add, choice, i, s;
struct symbtab *p;
p=first;
printf("What do you want to modify?\n");
printf("1. Only the label\n");
printf("2. Only the address of a particular label\n");
printf("3. Both the label and address\n");
printf("Enter your choice : ");
scanf("%d",&choice);
switch(choice)
5
{
case 1:
printf("Enter the old label\n");
scanf("%s",l);
printf("Enter the new label\n");
scanf("%s",nl);
s=search(l);
if(s==0)
{
printf("NO such label");
}
else
{
for(i=0;i<size;i++)
{
if(strcmp(p->label,l)==0)
{
strcpy(p->label,nl);
}
p=p->next;
}
}
break;
case 2:
printf("Enter the label whose address is to modified\n");
scanf("%s",l);
printf("Enter the new address\n");
scanf("%d",&add);
s=search(l);
if(s==0)
{
printf("NO such label");
}
else
6
{
for(i=0;i<size;i++)
{
if(strcmp(p->label,l)==0)
{
p->addr=add;
}
p=p->next;
}
}
break;
case 3:
printf("Enter the old label : ");
scanf("%s",l);
printf("Enter the new label : ");
scanf("%s",nl);
printf("Enter the new address : ");
scanf("%d",&add);
s=search(l);
if(s==0)
{
printf("NO such label");
}
else
{
for(i=0;i<size;i++)
{
if(strcmp(p->label,l)==0)
{
strcpy(p->label,nl);
p->addr=add;
}
p=p->next;
}
7
}
break;
}
}
void del()
{
int a;
char l[10];
struct symbtab *p,*q;
p=first;
printf("Enter the label to be deleted\n");
scanf("%s",l);
a=search(l);
if(a==0)
{
printf("Label not found\n");
}
else
{
if(strcmp(first->label,l)==0)
{
first=first->next;
}
else if(strcmp(last->label,l)==0)
{
q=p->next;
while(strcmp(q->label,l)!=0)
{
p=p->next;
q=q->next;
}
p->next=null;
last=p;
}
8
else
{
q=p->next;
while(strcmp(q->label,l)!=0)
{
p=p->next;
q=q->next;
}
p->next=q->next;
}
size--;
}
}
OUTPUT:
9
10
11
RESULT:
Thus the program for implementation of Symbol Table is executed and
verified.
12
Ex.No:2
IMPLEMENTATION OF A LEXICAL ANALYZER TO RECOGNIZE
FEW PATTERNS IN C
AIM:
To write a program for implementing a Lexical analyser using LEX tool in
Linux platform.
ALGORITHM:
6. In user subroutine section, main routine calls yylex(). yywrap() is used to get
more input.
13
7. The lex command uses the rules and actions contained in file to generate a
program,lex.yy.c, which can be compiled with the cc command. That program
can then receive input, break the input into the logical pieces defined by the
rules in file, and run program fragments contained in the actions in file.
PROGRAM:
2.(a) The program replaces the substring abc by ABC fromthe given input
string:
%{
#include<stdio.h>
#include<string.h>
int i;
%}
%%
[a-z A-Z]* {
for(i=0;i<=yyleng;i++)
{
if((yytext[i]=='a')&&(yytext[i+1]=='b')&&(yytext[i+2]=='c'))
{
yytext[i]='A';
yytext[i+1]='B';
yytext[i+2]='C';
}
}
printf("%s",yytext);
}
[\t]* return;
.* {ECHO;}
\n {printf("%s",yytext);}
%%
main()
{
yylex();
}
14
int yywrap()
{
return 1;
}
OUTPUT:
abc
ABC
%{
/*input is b.c*/
#include<stdio.h>
#include<string.h>
char temp[10];
int i=0,openbracket=0,closebracket=0;
extern FILE *yyin;
%}
%%
"("[()]*")"";"{
strcpy(temp,yytext);
printf("%s\n",temp);
i=0;
while(temp[i]!=';')
{
15
if(temp[i]=='(')
openbracket++;
if(temp[i]==')')
closebracket++;
else ;
i++;
}
if(openbracket==closebracket)
printf("Well formed input!\n");
else
printf("not well formed!\n");
}
%%
main(int argc,char *argv[])
{
FILE *fp=fopen(argv[1],"r");
yyin=fp;
yylex();
fclose(fp);
}
OUTPUT:
16
2.(c) Finding vowels and consonant in a string:
%{
int vowel_cnt=0,consonant_cnt=0;
%}
vowel [aeiou]+
consonant [^aeiou]
eol \n
%%
{eol} return 0;
[\t]+ ;
{vowel} {vowel_cnt++;}
{consonant} {consonant_cnt++;}
%%
int main()
{
printf("\n Enter some input string:\n");
yylex();
printf("Vowels=%d and consonant=%d\n",vowel_cnt,consonant_cnt);
return 0;
}
int yywrap()
{
return 1;
}
OUTPUT:
%{
%}
%%
[A-Z]+[ \t\n\.\,] {printf("%s",yytext);}
. ;
%%
main()
{
printf("\n Enter some input with capital words in between:\n");
yylex();
}
int yywrap()
{
return 1;
}
OUTPUT:
2.(e) It is used to display the Keywords and identifiers in the given program:
18
%{
int COMMENT=0;
%}
identifier[a-z|A-Z][a-z|A-Z|0-9]*
%%
#.* {printf("\n%s is a preprocesor directive",yytext);}
int {printf("\n\t%s is a keyword",yytext);}
float {printf("\n\t%s is a keyword",yytext);}
double {printf("\n\t%s is a keyword",yytext);}
char {printf("\n\t%s is a keyword",yytext);}
if {printf("\n\t%s is a keyword",yytext);}
else {printf("\n\t%s is a keyword",yytext);}
while {printf("\n\t%s is a keyword",yytext);}
do {printf("\n\t%s is a keyword",yytext);}
return {printf("\n\t%s is a keyword",yytext);}
break {printf("\n\t%s is a keyword",yytext);}
continue {printf("\n\t%s is a keyword",yytext);}
void {printf("\n\t%s is a keyword",yytext);}
switch {printf("\n\t%s is keyword",yytext);}
for {printf("\n\t%s is a keyword",yytext);}
typedef {printf("\n\t%s is a keyword",yytext);}
struct {printf("\n\t%s is a keyword",yytext);}
goto {printf("\n\t%s is a keyword",yytext);}
"/*" {COMMENT=1;}
"*/" {COMMENT=0;}
{identifier}\( {if(!COMMENT) printf("\nFUNCTIONS\n\t%s",yytext);}
\{ {if(!COMMENT) printf("\nBLOCK BEGINS");}
\} {if(!COMMENT) printf("\nBLOCK ENDS");}
{identifier} {if(!COMMENT) printf("\n%sIDENTIFIER",yytext);}
{identifier}(\[[0-9]*\])?\( {if(!COMMENT)
printf("\n%sIDENTIFIER",yytext);}
\".*\" {if(COMMENT)printf("\n\t%s is a string",yytext);}
[0-9]+ {if(COMMENT)printf("\n\t%s is a number",yytext);}
\)(\;)? {if(!COMMENT)printf("\n\t");ECHO;printf("\n");}
19
\(ECHO;
= {if(!COMMENT) printf("\n\t%s is an assignment 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("COULD NOT OPEN %s\n",argv[1]);
exit(1);
}
yyin=file;
}
yylex();
printf("\n\n");
return 0;
}
int yywrap()
{
return 0;
}
OUTPUT:
20
[CSE@localhost ~]$ lex lex5.l
[CSE@localhost ~]$ gcc lex.yy.c -IfI
[CSE@localhost ~]$. /a.out
FUNCTIONS
main()
{
BLOCK BEGINS
int a,b,c;
int is a keyword
aIDENTIFIER,
bIDENTIFIER,
cIDENTIFIER;
RESULT:
Thus the program for implementation of Lexical Analyzer to recognize
patterns is executed and verified.
Ex.No:3
IMPLEMENTATION OF A LEXICAL ANALYZER USING LEX TOOL
21
AIM:
To write a program for implementing a Lexical analyser using LEX tool in
Linux platform.
ALGORITHM:
6. In user subroutine section, main routine calls yylex(). yywrap() is used to get
more input.
7. The lex command uses the rules and actions contained in file to generate a
program,lex.yy.c, which can be compiled with the cc command. That program
22
can then receive input, break the input into the logical pieces defined by the
rules in file, and run program fragments contained in the actions in file.
PROGRAM:
Input:
$vi var.c
#include<stdio.h>
main()
{
int a,b;
}
OUTPUT:
[root@localhost Desktop]# lex lexp.l
[root@localhost Desktop]# gcc lex.yy.c -lfl
[root@localhost Desktop]# ./a.out
$vi var.c
#include<stdio.h>
main()
{
int a,b;
}$
vi IDENTIFIER
var IDENTIFIER.
c IDENTIFIER
BLOCK BEGINS
int is a KEYWORD
a IDENTIFIER,
b IDENTIFIER;
RESULT:
Ex.No:4 Thus the program for implementing Lexical Analyzer is executed and verified.
GENERATE YACC SPECIFICATION FOR A FEW SYNCTATIC CATEGORIES
AIM:
26
To write a program for generate yacc specification for few syntactic categories
in Linux platform.
ALGORITHM:
1. Lex program contains three sections: definitions, rules, and user subroutines.Each
section must be separated from the others by a line containing only the delimiter, %
%.
a. The format is as follows:
b. definitions
c. %%
d. rules
e. %%
f. user_subroutines
2. In definition section, the variables make up the left column, and their
definitions make up the right column. Any C statements should be enclosed in
%{..}%. Identifier is defined such that the first letter of an identifier is alphabet
and remaining letters are alphanumeric.
3. In rules section, the left column contains the pattern to be recognized in an
input file to yylex(). The right column contains the C program fragment
executed when that pattern is recognized. The various patterns are keywords,
operators, new line character, number, string, identifier, beginning and end of
block, comment statements, preprocessor directive statements etc.
4. Each pattern may have a corresponding action, that is, a fragment of C
source code to execute when the pattern is matched.
5. When yylex() matches a string in the input stream, it copies the matched text
to an external character array, yytext, before it executes any actions in the
rules section.
6. In user subroutine section, main routine calls yylex(). yywrap() is used to get
more input.
7. The lex command uses the rules and actions contained in file to generate a
program,lex.yy.c, which can be compiled with the cc command. That program
can then receive input, break the input into the logical pieces defined by the
rules in file, and run program fragments contained in the actions in file.
27
PROGRAM:
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;
}
%{
#include
/* This YYAC program is for recognizing the Expression */
%}
%%
statement: A’=’E
|E{
printf(“\n Valid arithmetic expression”);
$$ = $1;
};
28
E: E’+’ID
| E’-’ID
| E’*’ID
| E’/’ID
| ID
;
%%
extern FILE *yyin;
main()
{
do
{
yyparse();
}while(!feof(yyin));
}
yyerror(char*s)
{
}
OUTPUT:
Identifier is x
Operator is EQUAL
Identifier is a
Operator is PLUS
Identifier is b
lex progarm:
29
%{
/* 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;
}
yacc program:
%{
#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
30
;
%%
extern FILE *yyin;
main()
{
do
{
yyparse();
}while(!feof(yyin));
}
yyerror(char*s)
{
}
OUTPUT:
[root@localhost Desktop]# lex yacb.l
[root@localhost Desktop]# yacc -d yacb.y
[root@localhost Desktop]# gcc lex.yy.c y.tab.c
[root@localhost Desktop]# ./a.out
int a,b;
Identifier is a
Identifier is b
lex program:
%{
#include "y.tab.h"
%}
31
%%
a {return A;}
b {return B;}
. {return yytext[10];}
\n return('\n');
%%
int yywrap()
{
return 1;
}
Yacc progarm:
%{
#include<stdio.h>
#include<stdlib.h>
%}
%token A B
%%
stmt: A A A A A A A A A A S '\n'{printf("valid string\n");
return 0;}
;
S: A S
|A B
;
%%
32
main()
{
printf("enter the string\n");
yyparse();
}
OUTPUT:
[root@localhost Desktop]# lex yacc.l
[root@localhost Desktop]# yacc -d yacc.y
[root@localhost Desktop]# gcc lex.yy.c y.tab.c
[root@localhost Desktop]# ./a.out
enter the string
aaaaabbb
invalid string
[root@localhost Desktop]# ./a.out
enter the string
aaaaaaaaaaab
valid string
33
[\n] return 0;
. return yytext[0];
%%
int yywrap()
{
return 1;
}
Yacc progarm:
%{
#include<stdio.h>
int flag=0;
%}
%token NUMBER
%left '+' '-'
%left '*' '/' '%'
%left '(' ')'
%%
ArithmeticExpression: E{
printf("\nResult=%d\n",$$);
return 0;
};
E:E'+'E {$$=$1+$3;}
|E'-'E {$$=$1-$3;}
|E'*'E {$$=$1*$3;}
|E'/'E {$$=$1/$3;}
|E'%'E {$$=$1%$3;}
|'('E')' {$$=$2;}
| NUMBER {$$=$1;}
;
%%
void main()
{
34
printf("\nEnter Any Arithmetic Expression which can have operations Addition,
Subtraction, Multiplication, Divison, Modulus and Round brackets:\n");
yyparse();
if(flag==0)
printf("\nEntered arithmetic expression is Valid\n\n");
}
void yyerror()
{
printf("\nEntered arithmetic expression is Invalid\n\n");
flag=1;
}
OUTPUT:
[root@localhost Desktop]# lex yacd.l
[root@localhost Desktop]# yacc -d yacd.y
[root@localhost Desktop]# gcc lex.yy.c y.tab.c
[root@localhost Desktop]# ./a.out
35
Enter Any Arithmetic Expression which can have operations Addition, Subtraction,
Multiplication, Divison, Modulus and Round brackets:
5*5+2
Result=27
Entered arithmetic expression is Valid
RESULT:
Thus the program for Yacc specification is executed and verified.
Ex.No:5 CONVERT THE BNF RULES INTO YACC FORM AND
WRITE CODE TO GENERATE ABSTRACT SYNTAX TREE
AIM:
36
To write a program for implementing a calculator for computing the given
expression using BNF rules into Yacc form and write code to generate abstract
syntax tree.
ALGORITHM:
1. Lex program contains three sections: definitions, rules, and user subroutines.Each
section must be separated from the others by a line containing only the delimiter,
%%.
The format is as follows:
definitions
%%
rules
%%
user_subroutines
2. In definition section, the variables make up the left column, and their definitions
make up the right column. Any C statements should be enclosed in %{..}%. Identifier
is defined such that the first letter of an identifier is alphabet and remaining letters
are alphanumeric.
3. In rules section, the left column contains the pattern to be recognized in an input
file to yylex(). The right column contains the C program fragment executed when that
pattern is recognized. The various patterns are keywords, operators, new line
character, number, string, identifier, beginning and end of block, comment
statements, preprocessor directive statements etc.
4. Each pattern may have a corresponding action, that is, a fragment of C source
code to execute when the pattern is matched.
5. When yylex() matches a string in the input stream, it copies the matched text to an
external character array, yytext, before it executes any actions in the rules section.
6. In user subroutine section, main routine calls yylex(). yywrap() is used to get more
input.
7. The lex command uses the rules and actions contained in file to generate a
program,lex.yy.c, which can be compiled with the cc command. That program can
then receive input, break the input into the logical pieces defined by the rules in file,
and run program fragments contained in the actions in file.
PROGRAM:
Lex program:
%{
37
#include"y.tab.h"
#include<stdio.h>
#include<string.h>
int LineNo=1;
%}
identifier [a-zA-Z][_a-zA-Z0-9]*
number [0-9]+|([0-9]*\.[0-9]+)
%%
main\(\) return MAIN;
if return IF;
else return ELSE;
while return WHILE;
int |
char |
float return TYPE;
{identifier} {strcpy(yylval.var,yytext);
return VAR;}
{number} {strcpy(yylval.var,yytext);
return NUM;}
\< |
\> |
\>= |
\<= |
== {strcpy(yylval.var,yytext);
return RELOP;}
[ \t] ;
\n LineNo++;
. return yytext[0];
%%
int yywrap()
{
return 1;
}
Yacc progarm:
%{
#include<string.h>
#include<stdio.h>
struct quad
{
char op[5];
char arg1[10];
char arg2[10];
char result[10];
}QUAD[30];
struct stack
{
int items[100];
int top;
}stk;
38
int Index=0,tIndex=0,StNo,Ind,tInd;
extern int LineNo;
%}
%union
{
char var[10];
}
%token <var> NUM VAR RELOP
%token MAIN IF ELSE WHILE TYPE
%type <var> EXPR ASSIGNMENT CONDITION IFST ELSEST WHILELOOP
%left '-' '+'
%left '*' '/'
%%
PROGRAM : MAIN BLOCK
;
BLOCK: '{' CODE '}'
;
CODE: BLOCK
| STATEMENT CODE
| STATEMENT
;
STATEMENT: DESCT ';'
| ASSIGNMENT ';'
| CONDST
| WHILEST
;
DESCT: TYPE VARLIST
;
VARLIST: VAR ',' VARLIST
| VAR
;
ASSIGNMENT: VAR '=' EXPR{
strcpy(QUAD[Index].op,"=");
strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,$1);
strcpy($$,QUAD[Index++].result);
}
;
EXPR: EXPR '+' EXPR {AddQuadruple("+",$1,$3,$$);}
| EXPR '-' EXPR {AddQuadruple("-",$1,$3,$$);}
| EXPR '*' EXPR {AddQuadruple("*",$1,$3,$$);}
| EXPR '/' EXPR {AddQuadruple("/",$1,$3,$$);}
| '-' EXPR {AddQuadruple("UMIN",$2,"",$$);}
| '(' EXPR ')' {strcpy($$,$2);}
| VAR
| NUM
;
CONDST: IFST{
Ind=pop();
39
sprintf(QUAD[Ind].result,"%d",Index);
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}
| IFST ELSEST
;
IFST: IF '(' CONDITION ')' {
strcpy(QUAD[Index].op,"==");
strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"FALSE");
strcpy(QUAD[Index].result,"-1");
push(Index);
Index++;
}
BLOCK {
strcpy(QUAD[Index].op,"GOTO");
strcpy(QUAD[Index].arg1,"");
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,"-1");
push(Index);
Index++;
};
ELSEST: ELSE{
tInd=pop();
Ind=pop();
push(tInd);
sprintf(QUAD[Ind].result,"%d",Index);
}
BLOCK{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
};
CONDITION: VAR RELOP VAR {AddQuadruple($2,$1,$3,$$);
StNo=Index-1;
}
| VAR
| NUM
;
WHILEST: WHILELOOP{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",StNo);
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}
;
WHILELOOP: WHILE '(' CONDITION ')' {
strcpy(QUAD[Index].op,"==");
strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"FALSE");
strcpy(QUAD[Index].result,"-1");
40
push(Index);
Index++;
}
BLOCK {
strcpy(QUAD[Index].op,"GOTO");
strcpy(QUAD[Index].arg1,"");
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,"-1");
push(Index);
Index++;
}
;
%%
extern FILE *yyin;
int main(int argc,char *argv[])
{
FILE *fp;
int i;
if(argc>1)
{
fp=fopen(argv[1],"r");
if(!fp)
{
printf("\n File not found");
exit(0);
}
yyin=fp;
}
yyparse();
printf("\n\n\t\t ----------------------------""\n\t\t Pos Operator Arg1 Arg2 Result"
"\n\t\t--------------------");
for(i=0;i<Index;i++)
{
printf("\n\t\t %d\t %s\t %s\t %s\t
%s",i,QUAD[i].op,QUAD[i].arg1,QUAD[i].arg2,QUAD[i].result);
}
printf("\n\t\t -----------------------");
printf("\n\n");
return 0;
}
void push(int data)
{
stk.top++;
if(stk.top==100)
{
printf("\n Stack overflow\n");
exit(0);
}
stk.items[stk.top]=data;
}
41
int pop()
{
int data;
if(stk.top==-1)
{
printf("\n Stack underflow\n");
exit(0);
}
data=stk.items[stk.top--];
return data;
}
void AddQuadruple(char op[5],char arg1[10],char arg2[10],char result[10])
{
strcpy(QUAD[Index].op,op);
strcpy(QUAD[Index].arg1,arg1);
strcpy(QUAD[Index].arg2,arg2);
sprintf(QUAD[Index].result,"\t%d",tIndex++);
strcpy(result,QUAD[Index++].result);
}
yyerror()
{
printf("\n Error on line no:%d",LineNo);
}
C progarm:
main()
{
int a,b,c;
if(a<b)
{
a=a+b;
}
while(a<b)
{
a=a+b;
}
if(a<=b)
{
c=a-b;
}
else
{
c=a+b;
}
OUTPUT:
[root@localhost Desktop]# lex yac5.l
[root@localhost Desktop]# yacc -d yac5.y
42
[root@localhost Desktop]# gcc lex.yy.c y.tab.c
[root@localhost Desktop]# ./a.out var.c
Error on line no:20
----------------------------
Pos Operator Arg1 Arg2 Result
--------------------
0 < a b 0
1 == 0 FALSE 5
2 + a b 1
3 = 1 a
4 GOTO 5
5 < a b 2
6 == 2 FALSE 10
7 + a b 3
8 = 3 a
9 GOTO 5
10 <= a b 4
11 == 4 FALSE 15
12 - a b 5
13 = 5 c
14 GOTO 17
15 + a b 6
16 = 6 c
-----------------------
RESULT:
Thus the program for implementation of Abstract Syntax Tree is executed and
verified.
Ex.No: 6
IMPLEMENTATION OF TYPE CHECKING
AIM:
To write a program for implementation of type checking.
ALGORITHM:
43
1. Lex program contains three sections: definitions, rules, and user subroutines.Each
section must be separated from the others by a line containing only the delimiter,
%%.
The format is as follows:
definitions
%%
rules
%%
user_subroutines
2. In definition section, the variables make up the left column, and their definitions
make up the right column. Any C statements should be enclosed in %{..}%. Identifier
is defined such that the first letter of an identifier is alphabet and remaining letters
are alphanumeric.
3. In rules section, the left column contains the pattern to be recognized in an input
file to yylex(). The right column contains the C program fragment executed when that
pattern is recognized. The various patterns are keywords, operators, new line
character, number, string, identifier, beginning and end of block, comment
statements, preprocessor directive statements etc.
4. Each pattern may have a corresponding action, that is, a fragment of C source
code to execute when the pattern is matched.
5. When yylex() matches a string in the input stream, it copies the matched text to an
external character array, yytext, before it executes any actions in the rules section.In
user subroutine section, main routine calls yylex(). yywrap() is used to get more
input.
PROGRAM:
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
char* type(char[],int);
void main()
{
44
char a[10],b[10],mess[20],mess1[20];
int i,l;
clrscr();
printf( "\n\n int a,b;\n\n int c=a+b\n");
printf( "\n\n Enter a value for a\n");
scanf("%s", a); l=strlen(a);
printf(" \n a is :");
strcpy(mess,type(a,l));
printf("%s",mess);
printf( "\n\n Enter a value for b\n\n");
scanf("%s",b); l=strlen(b);
printf(" \n b is :");
strcpy(mess1,type(b,l));
printf("%s",mess1);
if(strcmp(mess,"int")==0&&strcmp(mess1,"int")==0)
{
printf("\n\n No Type Error");
}
Else
{
printf("\n\n Type Error");
}
getch();
}
char* type(char x[],int m)
{
int i; char mes[20];
for(i=0;i<m;i++)
{
if(isalpha(x[i]))
{
strcpy(mes,"AlphaNumeric");
goto X;
45
}
else if (x[i]=='.')
{
strcpy(mes,"float");
goto X;
}
}
strcpy(mes,"int");
X: return mes;
}
OUTPUT:
46
RESULT:
Thus the program for implementation of Abstract Syntax Tree is executed and
Ex.No:7
verified.
IMPLEMENTATION OF STORAGE ALLOCATION STRATEGIES
HEAP STORAGE ALLOCATION STRATEGY
AIM:
To write a program for Implementation Of Storage Allocation Strategies using
Heap.
ALGORITHM:
1. The storage allocation strategies using the relational operator is get from
the user.
2. Identifying the heap value of the given heap.
47
3. Identify the relational operator used in the statement.
4. Generate and display the heap.
PROGRAM:
#include <stdio.h>
int array[100], n;
main()
while(1)
printf("4.Quit \n");
scanf("%d", &choice);
switch(choice)
case 1:
scanf("%d", &num);
insert(num, n);
n = n + 1;
break;
case 2:
48
scanf("%d", &num);
delete(num);
break;
case 3:
display();
break;
case 4:
exit(0);
}/*End of switch */
}/*End of while */
}/*End of main()*/
display()
int i;
if (n == 0)
return;
printf("\n");
}/*End of display()*/
int parentnode;
49
while (location > 0)
array[location] = num;
return;
array[location] = array[parentnode];
location = parentnode;
}/*End of while*/
}/*End of insert()*/
delete(int num)
if (num == array[i])
break;
if (num != array[i])
return;
n = n - 1;
50
parentnode =(i - 1) / 2; /*find parentnode of node i */
insert(array[i], i);
return;
return;
temp = array[i];
array[i] = array[left];
array[left] = temp;
i = left;
else
temp = array[i];
array[i] = array[right];
array[right] = temp;
i = right;
left = 2 * i + 1;
51
right = 2 * i + 2;
}/*End of while*/
temp = array[i];
array[i] = array[left];
array[left] = temp;
52
OUTPUT:
RESULT:
53
Thus the program for implementation of Heap storage allocation strategy is
executed and verified.
Ex.No:8
IMPLEMENTAION OF DAG
AIM:
To write a program for Implementation Of DAG.
ALGORITHM:
1. Recall: topological sort takes O(E) time.
2. Recall: in Dijkstra's algorithm, vertices are explored in "priority" order.
3. In a DAG, exploring a "downstream" vertex cannot affect the shortest path to
an upstream vertex.
4. If the source is "downstream", no path is possible.
5. Key observation: exploring vertices in topological-sort order is sufficient.
PROGRAM:
#include<stdio.h>
main()
struct da
int ptr,left,right;
char label;
}dag[25];
int ptr,l,j,change,n=0,i=0,state=1,x,y,k;
char store,*input1,input[25],var;
clrscr();
for(i=0;i<25;i++)
54
dag[i].ptr=NULL;
dag[i].left=NULL;
dag[i].right=NULL;
dag[i].label=NULL;
scanf("%s",input1);
for(i=0;i<25;i++)
input[i]=NULL;
l=strlen(input1);
a:
for(i=0;input1[i]!=')';i++);
for(j=i;input1[j]!='(';j--);
for(x=j+1;x<i;x++)
if(isalpha(input1[x]))
input[n++]=input1[x];
else
if(input1[x]!='0')
store=input1[x];
input[n++]=store;
for(x=j;x<=i;x++)
input1[x]='0';
if(input1[0]!='0')
goto a;
for(i=0;i<n;i++)
55
{
dag[i].label=input[i];
dag[i].ptr=i;
if(!isalpha(input[i])&&!isdigit(input[i]))
dag[i].right=i-1;ptr=i;
var=input[i-1];
if(isalpha(var))
ptr=ptr-2;
else
ptr=i-1;
b:
if(!isalpha(var)&&!isdigit(var))
ptr=dag[ptr].left;
var=input[ptr];
goto b;
else
ptr=ptr-1;
dag[i].left=ptr;
}}
for(i=0;i<n;i++)/* draw the syntax tree for the followingoutput withpointer value*/
56
printf("\n%d\t%d\t%d\t%c\n",dag[i].ptr,dag[i].left,dag[i].right,dag[i].label);
getch();
for(i=0;i<n;i++)
{for(j=0;j<n;j++)
{if((dag[i].label==dag[j].label&&dag[i].left==dag[j].left)&&dag[i].right==dag[j].right)
for(k=0;k<n;k++)
if(dag[k].left==dag[j].ptr)
dag[k].left=dag[i].ptr;
if(dag[k].right==dag[j].ptr)
dag[k].right=dag[i].ptr;
dag[j].ptr=dag[i].ptr;
}}}
printf("\n %d\t\t%d\t\t%d\t\t%c\n",dag[i].ptr,dag[i].left,dag[i].right,dag[i].label);
getch();
57
OUTPUT:
RESULT:
58
Thus the program for Implementation DAG is executed and verified.
Ex.No:9
GENERATION OF CODE FOR A GIVEN INTERMEDIATE CODE
(Assembly Language)
AIM:
To write a program for the generation of assembly language code of relational
operator.
ALGORITHM:
1. The three address code using the relational operator is get from the user.
2. Identifying the addressing mode of the given three address code.
3. Identify the relational operator used in the statement.
4. Generate and display the assembly language code.
PROGRAM:
#include<iostream.h>
#include<stdlib.h>
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
void forswitch(char,int);
void conv(int);
char arg[10][10],op[5][2],ch[10],go[3][3],c[10];
void main()
{
int i=-1,m=0,k=10;
clrscr();
cout<<"\t\t\tTHREE ADDRESS CODE";
gotoxy(15,7);
cout<<"OPERATOR";
gotoxy(30,7);
cout<<"ARGUMENT-1";
59
gotoxy(45,7);
cout<<"ARGUMENT-2";
gotoxy(60,7);
cout<<"GOTO";
gotoxy(15,8);
cout<<"~~~~~~~~~~~~~~~~~~~~~~~~~~";
do
{
i++;
gotoxy(2,k);
printf("[%d]",i);
gotoxy(18,k);
scanf("%s",&op[i]);
forswitch(op[i][0],i);
gotoxy(33,k);
scanf("%s",&arg[m+i]);
gotoxy(48,k);
scanf("%s",&arg[m+1+i]);
gotoxy(61,k);
scanf("%s",&go[i]);
conv(m+i);
conv(m+1+i);
k++;
m++;
}while(i!=3);
clrscr();
printf("ASSEMBLY LANGUAGE CODE");
printf("\n\n100\tMOV %s,RO",arg[0]);
printf("\n101\tMOV %s,R1",arg[1]);
printf("\n102\tCMP R0,R1");
printf("\n103\t%s 107",ch);
printf("\n104\tMOV%s,R2",arg[3]);
printf("\n105\tMOV R2,%s",arg[2]);
printf("\n106\tJUMP 109");
60
printf("\n107\tMOV %s,R2",arg[5]);
printf("\n109\tend");
getch();
}
void conv(int x)
{
if(isdigit(arg[x][0]))
{
strcpy(c,"#");
strcat(c,arg[x]);
strcpy(arg[x],c);
}
}
void forswitch(char sh,int t)
{
if(t<1)
switch(sh)
{
case '<':
strcpy(ch,"JC");
break;
case '>':
strcpy(ch,"JNC");
break;
case '=':
strcpy(ch,"JZ");
break;
case '-':
break;
default:
gotoxy(8,40);
cout<<"\n\t\tINVALID ENTRY";
getch();
exit(0);
61
break;
}
}
OUTPUT:
RESULT:
62
Thus the program for generation of Machine Code for the given Intermediate
code is generated.
Ex.No:10
AIM:
To write a program for implementation of Code Optimization Technique in for
and do-while loop using C++.
ALGORITHM:
1. Generate the program for factorial program using for and do-while loop
to specify optimization technique.
2. In for loop variable initialization is activated first and the condition is
checked next. If the condition is true the corresponding statements are
executed and specified increment / decrement operation is performed.
3. The for loop operation is activated till the condition failure.
4. In do-while loop the variable is initialized and the statements are
executed then the condition checking and increment / decrement
operation is performed.
5. When comparing both for and do-while loop for optimization do-while is
best because first the statement execution is done then only the
condition is checked.So, during the statement execution itself we can
fin the inconvenience of the result and no need to wait for the specified
condition result.
6. Finally when considering Code Optimization in loop do-while is best
with respect to performance.
PROGRAM:
Before:
Using for:
#include<iostream.h>
#include <conio.h>
63
int main()
int i, n;
int fact=1;
cin>>n;
fact = fact*i;
getch();
return 0;
OUTPUT:
After:
Using do-while:
#include<iostream.h>
#include<conio.h>
void main()
64
{
clrscr();
int n,f;
f=1;
cin>>n;
do
f=f*n;
n--;
}while(n>0);
getch();
OUTPUT:
RESULT:
65
Thus the program for implementation of Code Optimization technique is
executed and verified
66