Compiler Lab Manual
Compiler Lab Manual
(Autonomous)
PREPARED BY
Mrs.C.GAYATHRI AP/CSE
Mrs.C.ANUSUYA AP/CSE
INDEX
SIGNATURE
S.NO DATE NAME OF THE EXPERIMENT OF THE
STAFF
1 SYMBOL TABLE
6 TYPE CHECKING
9 CONSTRUCTION OF DAG
AIM:
To write a C program to implement a symbol table.
ALGORITHM:
2. Get the input from the user with the terminating symbol ‘$’.
4. If the next character of the symbol is an operator then only the memory is allocated.
5. While reading, the input symbol is inserted into symbol table along with its
memory address.
6. The steps are repeated till”$”is reached.
7. To reach a variable, enter the variable to the searched and symbol table has been
checked for corresponding variable, the variable along its address is displayed as
result.
8. Stop the program.
PROGRAM
#include<stdio.h>
#include<conio.h>
#include<malloc.h>
#include<string.h>
#include<math.h>
#include<ctype.h>
void main()
char ch,srch,b[15],d[15],g[10],c;
clrscr();
while((c=getchar())!='$')
b[i]=c; i++;
n=i-1;
printf("Given expression:::");
i=0;
while(i<=n)
printf("%c",b[i]); i++;
}
printf("\n.....symbol table. . .\n");
printf("symbol\taddr\ttype\n");
while(j<=n)
c=b[j];
if(isalpha(toascii(c)))
if(j<=n)
p=malloc(c); add[x]=p;
d[x]=c;
printf("%c\t%d\tidentifier\n",c,p); goto b;
else
b:
ch=b[j+1];
if(ch=='+'||ch=='-'||ch=='*'||ch=='='||ch==’/’)
p=malloc(c);
add[x]=p;
g[x]=ch;
x++;
}
} j++;
scanf("%s",&srch);
//srch=getch();
for(i=0;i<=x;i++)
if(srch==d[i]||srch==g[i])
%p\n",srch,"@address",d[i]); flag=1;
if(flag==0)
}
═══════════ Output ═════════════════════════════
║Given expression:::C=A*B+C-D/H
║.....symbol table....
║C 2034 identifier
║= 083A Operator
║A 2178 identifier
║* 08C8 Operator
║B 2318 identifier
║+ 0954 Operator
║C 2458 identifier
║- 09E2 Operator
║D 2602 identifier
║H 2674 identifier
║+
RESULT:
Thus the C program to implement the symbol table was executed and the output is verified.
Ex. No: 02 DEVELOP A LEXICAL ANALYZER TO RECOGNIZE A FEW
PATTERNS IN C
Date:
AIM:
To Write a C program to develop a lexical analyzer to recognize a few patterns in C.
ALGORITHM:
6. Separate all the file contents as tokens and match it with the functions.
10. Finally print the output after recognizing all the tokens.
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<string.h>
void main()
FILE *fi,*fo,*fop,*fk;
int flag=0,i=1;
char c,t,a[15],ch[15],file[20];
clrscr();
scanf("%s",&file);
fi=fopen(file,"r");
fo=fopen("inter.c","w");
fop=fopen("Oper.c","r");
fk=fopen("key.c","r");
c=getc(fi); while(!
feof(fi))
if(isalpha(c)||isdigit(c)||(c=='['||c==']'||c=='.'==1))
fputc(c,fo);
else
if(c=='\n') fprintf(fo,"\t$\
t");
else fprintf(fo,"\t%c\t",c);
c=getc(fi);
fclose(fi);
fclose(fo);
fi=fopen("inter.c","r");
fscanf(fi,"%s",a);
while(!feof(fi))
if(strcmp(a,"$")==0)
fscanf(fi,"%s",a);
fscanf(fop,"%s",ch);
while(!feof(fop))
if(strcmp(ch,a)==0)
fscanf(fop,"%s",ch); printf("\t\t
%s\t:\t%s\n",a,ch); flag=1;
fscanf(fop,"%s",ch);
rewind(fop);
fscanf(fk,"%s",ch);
while(!feof(fk))
if(strcmp(ch,a)==0)
fscanf(fk,"%k",ch); printf("\t\t
%s\t:\tKeyword\n",a); flag=1;
fscanf(fk,"%s",ch);
}
rewind(fk);
if(flag==0)
if(isdigit(a[0])) printf("\t\t%s\t:\tConstant\
n",a);
else
printf("\t\t%s\t:\tIdentifier\n",a);
flag=0;
fscanf(fi,"%s",a);
getch();
Key.c
int
void
main
char
if
for
while
else
printf
scanf
FILE
include
stdio.h
conio.h
iostream.h
Oper.c
( open para
) closepara
{ openbrace
} closebrace
< lesser
> greater
: colon
; semicolon
# preprocessor
= equal
== asign
% percentage
^ bitwise
& reference
* star
+ add
- sub
\ backslash
/ slash
INPUT.c
#include "stdio.h"
#include "conio.h"
void main()
int a=10,b,c;
a=b*c;
getch();
}
OUTPUT:
Line:1
# : preprocessor
include : Identifier
" : doublequote
stdio.h : Keyword
" : doublequote
Line: 2
# : preprocessor
include : Identifier
" : doublequote
conio.h : Keyword
" : doublequote
Line: 3
void : Keyword
main : Keyword
( : open
) : closepara
Line: 4
{ : openbrace
Line: 5
int : Keyword
a : Identifier
= : equal
10 : Constant
, : Identifier
b : Identifier
, : Identifier
c : Identifier
; : semicolon
Line: 6
a : Identifier
= : equal
b : Identifier
* : star
c : Identifier
; : semicolon
Line: 7
getch : Identifier
( : open
) : closepara
; : semicolon
Line: 8
} : closebrace
RESULT:
Thus the above program for developing the lexical the lexical analyzer and recognizing the
few pattern s in C is executed successfully and the output is verified
Ex. No: 3
DATE:
IMPLEMENTATION OF LEXICAL ANALYSER USING LEX TOOL
Date:
AIM:
To write a lex program to implement the lexical analyzer
INTRODUCTION
Lex is officially known as a "Lexical Analyzer". It’s main job is to break up an input
stream into more into meaningful units, or tokens. For example, consider breaking a text
file up into individual words. More pragmatically, Lex is a tool for automatically
Lex specifications:
declarations
%%
translation rules
%%
auxiliary procedures
manifest constant is an identifier that is declared to represent a constant. e.g. # define PIE
: p1 {action 1}
p2 {action 2}
p3 {action 3}
……
……
where each p is a regular expression and each action is a program fragment describing
what action the lexical analyzer should take when a pattern p matches a lexeme. In Lex the
3. The third section holds whatever auxiliary procedures are needed by the actions.
Alternatively, these procedures can be compiled separately and loaded with the lexical
analyzer.
form: declarations
%%
translation rules
%%
auxiliary functions
The declarations section includes declarations of variables, manifest constants and regular
definitions.
Each pattern is a regular expression, which may use the regular definitions of the
declaration section. The actions are fragments of code, typically written in C, although
1. write the lex program in a file and save it as file.l (where file is the name of the file).
2. open the terminal and navigate to the directory where you have saved the file.l
2. open the terminal and navigate to the directory where you have saved the files.
ALGORITHM:
2. Pass file.c via command line arguments as Input file and include the yylex() tool
5. Print the relational, assignment and all the operator using yytext()
tool 6.Also scan and print where the loop ends and begins.
int COMMENT=0;
%}
identifier [a-zA-Z][a-zA-Z0-9]*
%%
int |
float |
char |
double |
while |
for |
do |
if |
break |
continue |
void |
switch |
case |
long |
struct |
const |
typedef |
return |
else |
{identifier}\( {if(!COMMENT)printf("\n\nFUNCTION\n\t%s",yytext);}
NUMBER",yytext);}
\( ECHO;
\<= |
\>= |
\< |
== |
%%
if (argc > 1)
{
FILE *file;
file = fopen(argv[1],"r");
if(!file)
exit(0);
yyin = file;
yylex();
printf("\n\n");
return 0;
} int yywrap()
return 0;
ODDREVEN.C
#include <stdio.h>
int main()
int number;
if(number % 2 == 0)
else
return 0;
═══════════=============Output ═════════════════════════
int is a KEYWORD
FUNCTION
main(
)
BLOCK BEGINS
int is a KEYWORD
number IDENTIFIER;
FUNCTION
printf(
);
FUNCTION
scanf(
number IDENTIFIER
);
FUNCTION
if(
number IDENTIFIER %
2 is a NUMBER
== is a RELATIONAL OPERATOR
0 is a NUMBER
FUNCTION
printf(
);
else is a KEYWORD
FUNCTION
printf(
number IDENTIFIER
);
return is a KEYWORD
0 is a NUMBER;
BLOCK ENDS
RESULT:
Thus the C program to implement the lexical analyzer using LEX tool was executed and the
output is verified.
Ex. No: 4.A
PROGRAM TO RECOGNIZE A VALID ARITHMETIC EXPRESSION
Date:
THAT USESOPERATOR +, - , * AND / USING YACC
AIM:
Step-1:Reading an expression
Step-2: Checking the validating of the given expression according to the rule
using yacc.
PROGRAM
vae.l
%{
#include"y.tab.h"
#include<math.h>
extern yylval;
%}
%%
[0-9]+ {yylval=atoi(yytext);return NUM;}
[+] {return '+';}
[-] {return '-';}
[*] {return '*';}
[/] {return '/';}
[\t]+;
[\n] {return 0;}
%%
vae.y
%{
#include<stdio.h>
%}
%token NUM
%left '-''+'
%right '*''/'
%%
start: exp {printf("%d\n",$$);}
exp:exp'+'exp {$$=$1+$3;}
|exp'-'exp {$$=$1-$3;}
|exp'*'exp {$$=$1*$3;}
|exp'/'exp
{
if($3==0)
yyerror("error");
else
{
$$=$1/$3;
}
}
|'('exp')' {$$=$2;}
|NUM {$$=$1;}
;
%%
main()
{
printf("Enter the Expr. in terms of integers\n");
if(yyparse()==0)
printf("Success\n");
}
yywrap(){}
yyerror()
{
printf("Error\n");
}
OUTPUT:
D:\MOHANRAJ\CS6612 COMPILER LAB\lex_yacc\YACC\CD4A>lex vae.l
RESULT:
AIM:
ALGORITHM:
Step-1:Reading an expression
Step-2: Checking the validating of the given expression according to the rule
using yacc.
PROGRAM
vid.l
%{
#include "y.tab.h"
%}
%%
[a-zA-z_] {return ALPHA;}
[0-9]+ {return NUMBER;}
"\n" { return ENTER;}
. {return ER;}
%%
yywrap()
{}
vid.y
%{
#include <stdio.h>
#include<stdlib.h>
%}
%token ALPHA NUMBER ENTER ER
%%
var:v ENTER {printf("Valid Variable\n");exit(0);}
v:ALPHA exp1
exp1:ALPHA exp1
|NUMBER exp1
|;
%%
yyerror()
{
printf("Invalid Variable\n");
}
main()
{
printf("Enter the expression:");
yyparse();
}
OUTPUT:
RESULT:
AIM:
ALGORITHM:
The rules section defines the rules that parse the input stream. Each rule consists of a
grammar production and the associated semantic action.
Programs Section
5. The calc.lex file contains include statements for standard input and output, as well as for
the y.tab.h file. The yacc program generates that file from the yacc grammar file information
if we use the -d flag with the yacc command. The y.tab.h file contains definitions for the
tokens that the parser program uses.
6. calc.lex contains the rules to generate these tokens from the input stream.
PROGRAM
calc.l
%{
#include<stdio.h>
#include"y.tab.h"
int c;
extern int yylval;
%}
%%
"";
[a-z] {
c=yytext[0];
yylval=c-'a';
return(LETTER);
}
[0-9] {
c=yytext[0];
yylval=c-'0';
return(DIGIT);
}
[^a-z 0-9\b] {
c=yytext[0];
return(c);
}
calc.y
%{
#include<stdio.h>
int regs[26];
int base;
%}
%start list
%token DIGIT LETTER
%left '|'
%left '&'
%left '+''-'
%left '*''/''%'
%left UMINUS
%%
list:
|
list stat '\n'
|
list error '\n'
{
yyerrok;
}
;
stat: expr
{
printf("%d\n",$1);
}
|
LETTER '=' expr
{
regs[$1]=$3;
}
;
expr: '(' expr ')'
{
$$=$2;
}
|
expr '*' expr
{
$$=$1*$3;
}
|
expr '/' expr
{
$$=$1/$3;
}
|
expr '%' expr
{
$$=$1%$3;
}
|
expr '+' expr
{
$$=$1+$3;
}
|
expr '-' expr
{
$$=$1-$3;
}
|
expr '&' expr
{
$$=$1&$3;
}
|
'-'expr %prec UMINUS
{
$$=-$2;
}
|
LETTER
{
$$=regs[$1];
}
|
number
;
number: DIGIT
{
$$=$1; base=($1==0)?
8:10;
}
|
number DIGIT
{
$$=base * $1+$2;
}
;
%%
main()
{
return(yyparse());
}
yyerror(s)
char *s;
{
fprintf(stderr,"%s\n",s);
}
yywrap()
{
return(1);
}
OUTPUT:
D:\MOHANRAJ\CS6612 COMPILER LAB\lex_yacc\yacc\calc>lex calc.l D:\
^C
D:\MOHANRAJ\CS6612 COMPILER LAB\lex_yacc\yacc\calc>
RESULT:
AIM:
To convert the bnf rules into yacc form and write code to generate
abstract syntax tree using and yacc.
ALGORITHM:
BNF.l
%{
#include"y.tab.h"
#include<stdio.h>
#include<string.h>
#define yywrap() 1
int LineNo=1;
%}
identifier [a-zA-Z][_a-zA-Z0-9]*
number [0-9]+|([0-9]*\.[0-9]+)
%%
if return IF;
else return ELSE;
while return WHILE;
int |
char |
float return TYPE;
\< |
\> |
\>= |
\<= |
== {strcpy(yylval.var,yytext); return
RELOP;} [ \t] ;
\n LineNo++;
. return yytext[0];
%%
BNF.y
%{
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
void AddQuadruple(char op[5],char arg1[10],char arg2[10],char
result[10]);
int pop();
void push(int data);
int Index=0,tIndex=0,StNo,Ind,tInd;
extern int LineNo;
struct quad
{
char op[5];
char arg1[10];
char arg2[10];
char result[10];
}QUAD[30];
struct stack
{
int items[100];
int top;
}stk;
%}
%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();
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");
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].resu
lt);
}
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;
}
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 (char const *s)
{
fprintf (stderr, "%s\n", s);
}
TEST.c
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:
RESULT:
Thus the program for the exercise on the syntax using YACC
has been executed successfully and output is verified.
Ex. No: 06
IMPLEMENTATION OF TYPE CHECKING
Date:
Date
AIM:
ALGORITHM:
Step-1: Track the global scope type information (e.g. classes and their
members)
#include<stdio.h>
#include<string.h>
struct symTable
{
int type;
char var[10];
}sT[50];
int c = 0;
void sep(char a[])
{
int len = strlen(a);
int i,j=0;
char temp[50],tp[50];
for(i = 0; i < len;++i)
{
if(a[i] != 32)
tp[i] = a[i];
else
break;
}
tp[i] = '\0';
temp[0]='\0';
++i;
for(;i < len;++i)
{
if(a[i] != ',' && a[i] != 32 && a[i] != ';')
temp[j++] = a[i];
else
{
if(strcmp(tp,"int") == 0)
sT[c].type = 1;
else if(strcmp(tp,"float") == 0)
sT[c].type = 2; strcpy(sT[c+
+].var,temp); temp[0] = '\0';
j=0;
}
}
}
int check(char a[])
{
int len = strlen(a);
int i, j = 0,key = 0,k;
char temp[50];
for(i = 0;i < len;++i)
{
if(a[i] != 32 && a[i] != '+' && a[i] != '=' && a[i] != ';')
temp[j++] = a[i];
else
{
temp[j]='\0';
for(k = 0;k < c;++k)
{
if(strcmp(sT[k].var,temp) == 0)
{
if(key == 0)
key = sT[k].type;
else if(sT[k].type != key)
return 0;
}
}
j = 0;
}
}
return 1;
}
void main()
{
int N,ans,i;
char s[50];
printf("\n Enter the total lines of declaration\n");
scanf("%d",&N);
while(N--)
{
scanf(" %[^\n]",s);
sep(s);
}
printf("Enter the expression:\n");
scanf(" %[^\n]",s);
if(check(s))
printf("Correct\n");
else
printf("Semantic error\n");
OUTPUT:
RESULT:
– static: global variable storage, permanent for the entire run of the program.
– stack: local variable storage (automatic, continuous memory).
– heap: dynamic storage (large pool of memory, not allocated in contiguous order).
STATIC MEMORY
Static memory persists throughout the entire life of the program, and is usually used to store things
like global variables, or variables created with the static clause. For example:
int theforce;
On many systems this variable uses 4 bytes of memory. This memory can come from one of two
places. If a variable is declared outside of a function, it is considered global, meaning it is
accessible anywhere in the program. Global variables are static, and there is only one copy for the
entire program. Inside a function the variable is allocated on the stack. It is also possible to force a
variable to be static using the static clause. For example, the same variable created inside a
function using the static clause would allow it to be stored in static memory.
STACK MEMORY
The stack is used to store variables used on the inside of a function (including the main()function).
It’s a LIFO, “Last-In,-First-Out”, structure. Every time a function declares a new variable it is
“pushed” onto the stack. Then when a function finishes running, all the variables associated with
that function on the stack are deleted, and the memory they use is freed up. This leads to the
“local” scope of function variables. The stack is a special region of memory, and automatically
managed by the CPU – so you don’t have to allocate or deallocate memory. Stack memory is
divided into successive frames where each time a function is called, it allocates itself a fresh stack
frame.
Note that there is generally a limit on the size of the stack – which can vary with the operating
system (for example OSX currently has a default stack size of 8MB). If a program tries to put too
much information on the stack, stack overflow will occur. Stack overflow happens when all the
memory in the stack has been allocated, and further allocations begin overflowing into other
sections of memory. Stack overflow also occurs in situations where recursion is incorrectly used.
the stack grows and shrinks as variables are created and destroyed
stack variables only exist whilst the function that created them exists
HEAP MEMORY
The heap is the diametrical opposite of the stack. The heap is a large pool of memory that can be
used dynamically – it is also known as the “free store”. This is memory that is not automatically
managed – you have to explicitly allocate (using functions such as malloc), and deallocate (e.g.
free) the memory. Failure to free the memory when you are finished with it will result in what is
known as a memory leak – memory that is still “being used”, and not available to other processes.
Unlike the stack, there are generally no restrictions on the size of the heap (or the variables it
creates), other than the physical size of memory in the machine. Variables created on the heap are
accessible anywhere in the program.
the heap is managed by the programmer, the ability to modify it is somewhat boundless
in C, variables are allocated and freed using functions like malloc() and free()
the heap is large, and is usually limited by the physical memory available
Consider the following example of a program containing all three forms of memory:
#include <stdio.h>
#include <stdlib.h>
int x;
int main(void)
int y;
char *str;
y = 4;
str = malloc(100*sizeof(char));
str[0] = 'm';
printf("heap memory: %c\n", str[0]);
free(str);
return 0;
The variable x is static storage, because of its global nature. Both y and str are dynamic stack
storage which is deallocated when the program ends. The function malloc() is used to allocate 100
pieces of of dynamic heap storage, each the size of char, to str. Conversely, the function free(),
deallocates the memory associated with str.
Ex. No: 08
IMPLEMENT ANY ONE STORAGE ALLOCATION
Date: STRATEGIES(HEAP,STACK,STATIC)
Date
AIM:
ALGORITHM:
Step-3: Insert more elements onto the stack until stack becomes
full Step-4: Delete an element from the stack using pop operation
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#define size 5
struct stack
{
int s[size];
int top;
} st;
int stfull()
{
if (st.top >= size - 1)
return 1;
else
return 0;
}
void push(int item)
{
st.top++;
st.s[st.top] = item;
}
int stempty()
{
if (st.top == -1)
return 1;
else
return 0;
}
int pop()
{
int item;
item = st.s[st.top];
st.top--;
return (item);
}
void display()
{
int i;
if (stempty()) printf("\
nStack Is Empty!"); else
{
for (i = st.top; i >= 0; i--)
printf("\n%d", st.s[i]);
}
}
int main()
{
int item, choice;
char ans;
st.top = -1;
printf("\n\tImplementation Of Stack");
do {
printf("\nMain Menu");
printf("\n1.Push \n2.Pop \n3.Display \n4.exit");
printf("\nEnter Your Choice");
scanf("%d", &choice);
switch (choice)
{
case 1:
printf("\nEnter The item to be pushed");
scanf("%d", &item);
if (stfull())
printf("\nStack is Full!");
else
push(item);
break;
case 2:
if (stempty())
printf("\nEmpty stack!Underflow !!");
else
{
item = pop();
printf("\nThe popped element is %d", item);
}
break;
case 3:
display();
break;
case 4:
goto halt;
}
printf("\nDo You want To Continue?");
ans = getche();
} while (ans == 'Y' || ans == 'y');
halt:
return 0;
}
OUTPUT:
Implementation Of Stack
Main Menu
1.Push
2.Pop
3.Display
4.exit
Enter Your Choice 1
20
10
Do You want To Continue?n
RESULT:
Thus the above program is compiled and executed successfully and output is verified.
Ex. No: 06
CONSTRUCTION OF DAG (DIRECTED ACYCLIC GRAPH)
Date:
Date
AIM:
INTRODUCTION:
The code optimization is required to produce an efficient target code. These are two important
issues that used to be considered while applying the techniques for code optimization.
They are:
The semantics equivalences of the source program must not be changed.
The improvement over the program efficiency must be achieved without changing the
algorithm.
ALGORITHM:
3. Check for postfix expression and construct the in order DAG representation
PROGRAM
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<conio.h>
void 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++)
{
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.limit
is 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++)
{
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 following
output with pointer value*/ 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 with
pointer value*/
printf("\n %dt\t%d\t\t%d\t\t%c\n",dag[i].ptr,dag[i].left,dag[i].right,dag[i].label);
getch();
}
OUTPUT:
ENTER THE EXPRESSION
((a*b-c))+((b-c)*d))
0 0 0 a
1 0 0 b
2 0 0 c
3 1 2 -
4 0 3 -
0 0 0 a
1 0 0 b
2 0 0 c
3 1 2 -
4 0 3 -
RESULT:
Thus the program for implementation of DAG has been successfully executed and output is
verified.
Ex. No: 10
AIM:
ALGORITHM:
2. Get the three variables from statements and stored in the text file k.txt.
3. Compile the program and give the path of the source file.
RESULT:
Thus the above program is compiled and executed successfully and output is verified.
Ex. No: 11
AIM:
ALGORITHM:
1. Start
2. Create an input file which contains three address code.
3. Open the file in read mode.
4. If the file pointer returns NULL, exit the program else go to 5.
5. Scan the input symbol from the left to right.
Common Sub expression elimination
6. Store the first expression in a string.
7. Compare the string with the other expressions in the file.
8. If there is a match, remove the expression from the input file.
9. Perform these steps 5 to 8 for all the input symbols in the file.
Dead code Elimination
10. Scan the input symbol from the file from left to right.
11. Get the operand before the operator from the three address code.
12. Check whether the operand is used in any other expression in the three address code.
13. If the operand is not used, then eliminate the complete expression from the three address
code else go to 14.
14. Perform steps 11 to 13 for all the operands in the three address code till end of file is
reached.
15.Stop..
PROGRAM
#include <stdio.h>
#include <conio.h>
#include <string.h >
struct op
{
char l;
char r[20];
}
op[10], pr[10];
void main()
{
int a, i, k, j, n, z = 0, m, q;
char * p, * l;
char temp, t;
char * tem;
clrscr();
printf("enter no of values");
scanf("%d", & n);
for (i = 0; i < n; i++)
{
printf("\tleft\t");
op[i].l = getche();
printf("\tright:\t");
scanf("%s", op[i].r);
}
printf("intermediate Code\n");
for (i = 0; i < n; i++)
{
printf("%c=", op[i].l);
printf("%s\n", op[i].r);
}
for (i = 0; i < n - 1; i++)
{
temp = op[i].l;
for (j = 0; j < n; j++)
{
p = strchr(op[j].r, temp);
if (p)
{
pr[z].l = op[i].l;
strcpy(pr[z].r, op[i].r);
z++;
}
}
}
pr[z].l = op[n - 1].l;
strcpy(pr[z].r, op[n - 1].r);
z++;
printf("\nafter dead code elimination\n");
for (k = 0; k < z; k++)
{
printf("%c\t=", pr[k].l);
printf("%s\n", pr[k].r);
}
{
pr[i].l = '\0';
strcpy(pr[i].r, '\0');
}
}
}
printf("optimized code");
for (i = 0; i < z; i++)
{
if (pr[i].l != '\0') {
printf("%c=", pr[i].l);
printf("%s\n", pr[i].r);
} } getch();
}
OUTPUT:
left a right: 9
left b right: c+d
left e right: c+d
left f right: b+e
left r right: f
intermediate Code
a=9
b=c+d
e=c+d
f=b+e
r=f
RESULT:
Thus the above program is compiled and executed successfully and output is verified.
1 of 15