Sie sind auf Seite 1von 66

Ex.

No:1
IMPLEMENTATION OF SYMBOL TABLE

AIM:

To write a program for implementing Symbol Table using C.

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:

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.

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:

[CSE@localhost ~]$ lex lex1.l


[CSE@localhost ~]$ gcc lex.yy.c -lfl
[CSE@localhost ~]$. /a.out

abc
ABC

2.(b)Well formedness of brackets

%{
/*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:

[CSE@localhost ~]$ lex lex2.l


[CSE@localhost ~]$ gcc lex.yy.c -lfl
[CSE@localhost ~]$. /a.out b.c
((()));
Well formed input
[CSE@localhost ~]$ lex lex2.l
[CSE@localhost ~]$ gcc lex.yy.c -lfl
[CSE@localhost ~]$. /a.out
(()));
Not well formed

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:

[CSE@localhost ~]$ lex lex2.l


[CSE@localhost ~]$ gcc lex.yy.c -lfl
[CSE@localhost ~]$. /a.out
Enter some input string: infotech
17
Vowels=3 and consonant=5

2.(d) Finding the capital:

%{
%}
%%
[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:

[CSE@localhost ~]$ lex lex2.l


[CSE@localhost ~]$ gcc lex.yy.c -lfl
[CSE@localhost ~]$. /a.out
Enter some input with capital words in between:
I am STUDENT
I STUDENT

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:

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

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:

/* program name is lexp.l */


%{
/* program to recognize a c program */
int COMMENT=0;
%}
identifier [a-zA-Z][a-zA-Z0-9]*
%%
#.* { printf("\n%s is a PREPROCESSOR DIRECTIVE",yytext);}
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",yytext);}
"/*" {COMMENT = 1;}
23
/*{printf("\n\n\t%s is a COMMENT\n",yytext);}*/
"*/" {COMMENT = 0;}
/* printf("\n\n\t%s is a COMMENT\n",yytext);}*/
{identifier}\( {if(!COMMENT)printf("\n\nFUNCTION\n\t%s",yytext);}
\{ {if(!COMMENT) printf("\n BLOCK BEGINS");}
\} {if(!COMMENT) printf("\n BLOCK ENDS");}
{identifier}(\[[0-9]*\])? {if(!COMMENT) printf("\n %s IDENTIFIER",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");}
\( ECHO;
= {if(!COMMENT)printf("\n\t%s is an ASSIGNMENT OPERATOR",yytext);}
\<= |
\>= |
\< |
== |
\> {if(!COMMENT) printf("\n\t%s is a RELATIONAL OPERATOR",yytext);}
%%
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(0);
}
yyin = file;
}
yylex();
printf("\n\n");
return 0;
24
} int yywrap()
{
return 0;
}

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

#include<stdio.h> is a PREPROCESSOR DIRECTIVE


FUNCTION
main(
25
)

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

Program Name : arith_id.y

%{
#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:

[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.out
x=a+b;

Identifier is x
Operator is EQUAL
Identifier is a
Operator is PLUS
Identifier is b

b) Program to recognise a valid variable which starts with a letter


followed by any number of letters or digits.

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

c) Program to recognise the gramar(anb where n>=10)

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
;
%%

int yyerror(char *msg)


{
printf("invalid string\n");
exit(0);
}

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

d) Implementation of Calculator using LEX and YACC


lex program:
%{
#include<stdio.h>
#include "y.tab.h"
extern int yylval;
%}
%%
[0-9]+ {
yylval=atoi(yytext);
return NUMBER;
}
[\t] ;

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

[root@localhost Desktop]# ./a.out


Enter Any Arithmetic Expression which can have operations Addition, Subtraction,
Multiplication, Divison, Modulus and Round brackets:
sin 45/mem
Entered arithmetic expression is Invalid

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

int choice, num;

n = 0;/*Represents number of nodes in the heap*/

while(1)

printf("1.Insert the element \n");

printf("2.Delete the element \n");

printf("3.Display all elements \n");

printf("4.Quit \n");

printf("Enter your choice : ");

scanf("%d", &choice);

switch(choice)

case 1:

printf("Enter the element to be inserted to the list : ");

scanf("%d", &num);

insert(num, n);

n = n + 1;

break;

case 2:

printf("Enter the element to be deleted from the list: ");

48
scanf("%d", &num);

delete(num);

break;

case 3:

display();

break;

case 4:

exit(0);

default: printf("Invalid choice \n");

}/*End of switch */

}/*End of while */

}/*End of main()*/

display()

int i;

if (n == 0)

printf("Heap is empty \n");

return;

for (i = 0; i < n; i++)

printf("%d ", array[i]);

printf("\n");

}/*End of display()*/

insert(int num, int location)

int parentnode;

49
while (location > 0)

parentnode =(location - 1)/2;

if (num <= array[parentnode])

array[location] = num;

return;

array[location] = array[parentnode];

location = parentnode;

}/*End of while*/

array[0] = num; /*assign number to the root node */

}/*End of insert()*/

delete(int num)

int left, right, i, temp, parentnode;

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

if (num == array[i])

break;

if (num != array[i])

printf("%d not found in heap list\n", num);

return;

array[i] = array[n - 1];

n = n - 1;

50
parentnode =(i - 1) / 2; /*find parentnode of node i */

if (array[i] > array[parentnode])

insert(array[i], i);

return;

left = 2 * i + 1; /*left child of i*/

right = 2 * i + 2; /* right child of i*/

while (right < n)

if (array[i] >= array[left] && array[i] >= array[right])

return;

if (array[right] <= array[left])

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*/

if (left == n - 1 && array[i]) {

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;

printf("\n\nENTER THE EXPRESSION\n\n");

scanf("%s",input1);

/*EX:((a*b-c))+((b-c)*d)) like this give with paranthesis.limitis 25 char ucan change


that*/

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;

}}

printf("\n SYNTAX TREE FOR GIVEN EXPRESSION\n\n");

printf("\n\n PTR\t\t LEFT PTR\t\t RIGHT PTR\t\t LABEL\n\n");

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 DAG FOR GIVEN EXPRESSION\n\n");

printf("\n\n PTR\t LEFT PTR\t RIGHT PTR\t LABEL\n\n");

for(i=0;i<n;i++)/*draw DAG for the following output withpointer value*/

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

IMPLEMENTATION OF CODE OPTIMIZATION TECHNIQUES

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;

cout<<"\nEnter a number: ";

cin>>n;

for(i=n ; i>=1 ; i--)

fact = fact*i;

cout<<"The factoral value is: "<<fact;

getch();

return 0;

OUTPUT:

After:

Using do-while:

#include<iostream.h>

#include<conio.h>

void main()

64
{

clrscr();

int n,f;

f=1;

cout<<"Enter the number:\n";

cin>>n;

do

f=f*n;

n--;

}while(n>0);

cout<<"The factorial value is:"<<f;

getch();

OUTPUT:

RESULT:

65
Thus the program for implementation of Code Optimization technique is
executed and verified

66

Das könnte Ihnen auch gefallen