0% found this document useful (0 votes)
25 views43 pages

CD Lab Manual

The document outlines the development of a lexical analyzer using the LEX tool to recognize patterns in C programming, including identifiers, constants, comments, and operators. It provides algorithms and sample programs for various experiments, such as recognizing arithmetic expressions, valid variables, and control structures like loops and conditionals. Each section includes program code, expected outputs, and results confirming the successful execution of the lexical analyzer.

Uploaded by

dkdivakar281
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views43 pages

CD Lab Manual

The document outlines the development of a lexical analyzer using the LEX tool to recognize patterns in C programming, including identifiers, constants, comments, and operators. It provides algorithms and sample programs for various experiments, such as recognizing arithmetic expressions, valid variables, and control structures like loops and conditionals. Each section includes program code, expected outputs, and results confirming the successful execution of the lexical analyzer.

Uploaded by

dkdivakar281
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 43

Exp No:1 Using the LEX tool, Develop a lexical analyzer to recognize a few

patterns in C. (Ex. identifiers, constants, comments, operators


Date: etc.). Create a symbol table, while recognizing identifiers.

AIM:
To develop a lexical analyzer to recognize a few patterns in C and implement a
symbol table.

ALGORITHM:
Step 1: Start the program.
Step 2: Create some character arrays to store and manipulate the characters.
Step 3: Create a file pointer and get the name of the input file to read theinput from.
Step 4: Open the input file using the read category.
Step 5: Copy the content of the file into a string and then copy it to acharacter array for
processing.
Step 6: Use a while loop and browse the content of the file till the end.
Step 7: Using a if condition, Separate some symbols like ;<>{}()#,& andprint them as
Special Characters.
Step 8: Using a if condition, print the letters/words following the int, char orfloat as the
Variables.
Step 8.1: Find and store the memory address of the variable in the symboltable and print
the symbol table after printing lexeme tokens.
Step 9: Using a if condition, print the words printf, scanf, main, void etc asthe keywords.
Step 10: Terminate the program.
PROGRAM:

#include<stdio.h>
#include<string.h>
void main(){
char a[100],temp[100];
char *word;
char delim[]=";><{}+)(&%#,= ";
char variable[10][20],datatype[10][20];

int k,noofvar=0;
void *i;
FILE *p;
p=fopen("add.c","r");
//FILE OPEN READ MODE
fscanf(p,"%s",a);

strcpy(temp,"Null");
printf("\nLexeme\tToken\n\n");
while(strcmp(a,"END")!=0){
for(k=0;k<strlen(a);k++){
if (a[k]==';'||a[k]=='<'||a[k]=='{'||a[k]=='>'||a[k]==')'||a[k]=='}'||a[k]=='#'||a[k]=='>'||a[k]== ','
||a[k]=='&'||a[k]=='+'||a[k]=='='||a[k]=='(')
{
printf("\033[0;37m");

printf("\n%c\tSpecial Character",a[k]);
}
}
word=strtok(a,delim);
while(word!=NULL){
if((strcmp(word,"scanf")==0)||(strcmp(word,"printf")==0)||(strcmp(word,"main")==0))
{
printf("\033[0;36m"); printf("\n%s\t",word);

printf("BUILT IN FUNCTION\t");
}
else if((strcmp(word,"int")==0)||(strcmp(word,"float")==0)||(strcmp(word,"char")==0)||
(strcmp(word," void")==0))
{
printf("\033[0;32m");
printf("\n%s\t",word);
printf("KEYWORD\t");
}
else if((strcmp(word,"include")==0))
{
printf("\033[0;32m");
printf("\n%s\t",word);
printf("PREPROCESSOR\t");
}
else if((strcmp(word,"stdio.h")==0)||(strcmp(word,"conio.h")==0)){
printf("\033[0;33m");
printf("\n%s\t",word);
printf("HEADER FILE\t");
}
else if((strcmp(temp,"int")==0)||(strcmp(temp,"float")==0)||(strcmp(temp,"char")==0))
{
printf("\033[0;36m");
printf("\n%s\t",word);
printf("VARIABLE\t");
strcpy(variable[noofvar], word);
strcpy(datatype[noofvar], temp);
noofvar++;
}
word = strtok(NULL, delim);
}
strcpy(temp,a);
fscanf(p,"%s",a);

fclose(p);
//file close
//SYMBOL TABLE PGRM
printf("\n\nSYMBOL TABLE \n");

printf(" \n");
printf("symbol\taddr\t\ttype\n");
for(k=0;k<noofvar;k++){
i=malloc(variable[k][0]);
printf("\033[0;31m");
printf("%s\t%d\t%s\n",variable[k],i,datatype[k]);
}
}
ADD.c
#include<stdio.h>
#include<string.h>

void main(){
int a,b,sum;
printf("Enter number");
scanf("%d",&a);
printf("Enter number");
scanf("%d",&b);
sum=a+b;
printf("sum=%d",sum);
}
END

OUTPUT:
RESULT:
Thus the C program to implement the Lexical Analyzer is done and the requiredLexemes are
obtained and the implementation of a symbol table is verified.
Exp No: 2
Implement a Lexical Analyzer using LEX Tool
Date:

AIM:
To implement a Lexical Analyzer using a Lex Tool to divide the lexemes into
various categories.

ALGORITHM:
Step 1: Start the program.
Step 2: Include the header files needed.
Step 3: Use a if condition for separating the keywords like int,char,float,return.

Step 4: Use another if condition for separating the preprocessor directives like #.*

Step 5: Use another if condition for separating the function names like
main, printf, scanf.
Step 6: Use another if condition for separating the letters and words as identifiers.
Step 7: Use another if condition for separating the operators like +-/*%
Step 8: Use another if condition for separating the Special characters like ,;&{}()
Step 9: Terminate the program.
PROGRAM:
%{

#include<stdio.h>

%}

%%

int|char|float|return { printf("\n%s=> Keywords",yytext);}

#.* { printf("\n%s=>Preprocessor Directive",yytext);}

printf|scanf|main { printf("\n%s=>functions",yytext);}

["][a-z]+["] { printf("\n%s=>Strings",yytext);}

[[a-z]|[A-Z]][[a-z]|[A-Z]|[0-9]]+ { printf("\n%s=>Identifiers",yytext);}
[0-9] { printf("\n%s=>Numbers",yytext);}

"+"|"-"|"*"|"/"|"%" { printf("\n%s=>Operators",yytext);}

","|";"|"&"|"("|")"|”["|”]”|"{"|"}" { printf("\n%s=>Special Characters",yytext);}

%%

int main()

FILE *fp;

fp=fopen("input.txt","r");

yyin=fp;

yylex();

return 0;

int yywrap()

return 1;

}
input.txt:

int main()
{
int a,b;

printf("hello");

float c;
char d;
return 0;
}
OUTPUT:

RESULT:
Thus the required Lexical Analyzer is designed and the required output isobtained and
verified.
Expt. No: 3(a) Program to recognize a valid arithmetic expression that
uses operator +, -,* and /.
Date:

AIM:
To program to recognize a valid arithmetic expression that uses operator +,-,* and /.

ALGORITHM:
LEX
1. Declare the required header file and variable declaration with in ‘%{‘ and ‘%}’.
2. LEX requires regular expressions to identify valid arithmetic expression token of lexemes.
3. LEX call yywrap() function after input is over. It should return 1 when work is done or
should return 0 when more processing is required.
YACC
1. Declare the required header file and variable declaration with in ‘%{‘ and ‘%}’.
2. Define tokens in the first section and also define the associativity of the operations
3. Mention the grammar productions and the action for each production.
4. $$ refer to the top of the stack position while $1 for the first value, $2 for the second value in
the stack.
5. Call yyparse() to initiate the parsing process.
6. yyerror() function is called when all productions in the grammar in second section doesn't
match to the input statement.

PROGRAM:

//art_expr.l
%{
#include<stdio.h>
#include “y.tab.h”
%}
%%
[a-zA-Z][0-9a-zA-Z]* {return ID;}
[0-9]+ {return DIG;}
[ \t]+ {;}
. {return yytext[0];}
\n {return 0;}
%%
int yywrap()
{
return 1;
}

//art_expr.y
%{
#include<stdio.h>
%}
%token ID DIG
%left '+''-'
%left '*''/'
%right UMINUS
%%
stmt:expn ;
expn:expn'+'expn
|expn'-'expn
|expn'*'expn
|expn'/'expn
|'-'expn %prec UMINUS
|'('expn')'
|DIG
|ID
;
%%
int main()
{
printf("Enter the Expression \n");
yyparse();
printf("valid Expression \n");
return 0;
}
int yyerror()
{
printf("Invalid Expression");
exit(0);
}

OUTPUT:

RESULT:
Thus the program to to recognize a valid arithmetic expression that uses operator +,-,* and /
was executed successfully.
Expt. No:3(b)
Program to recognize a valid variable which starts with a
Date: letter followed by any number of letters or digits.

AIM:
To program to recognize a valid variable which starts with a letter followed by any number of
letters or digits.

ALGORITHM:
LEX
1. Declare the required header file and variable declaration with in ‘%{‘ and ‘%}’.
2. LEX requires regular expressions or patterns to identify token of lexemes for recognize a
valid variable.
3. Lex call yywrap() function after input is over. It should return 1 when work is done or
should return 0 when more processing is required.
YACC
1. Declare the required header file and variable declaration with in ‘%{‘ and ‘%}’.
2. Define tokens in the first section and also define the associativity of the operations
3. Mention the grammar productions and the action for each production.
4. $$ refer to the top of the stack position while $1 for the first value, $2 for the second value in
the stack.
5. Call yyparse() to initiate the parsing process.
6. yyerror() function is called when all productions in the grammar in second section doesn't
match to the input statement.

PROGRAM:
//valvar.l
%{
#include "y.tab.h"
%}
%%
[a-zA-Z] {return LET;}
[0-9] {return DIG;}
. {return yytext[0];}
\n {return 0;}
%%
int yywrap()
{
return 1;
}

//valvar.y

%{
#include<stdio.h>
%}
%token LET DIG
%%
variable:var
;
var:var DIG
|var LET
|LET
;
%%
int main()
{
printf("Enter the variable:\n");
yyparse();
printf("Valid variable \n");
return 0;
}
int yyerror()
{
printf("Invalid variable \n");
exit(0);
}

OUTPUT:

RESULT:
Thus the program to recognize a valid variable which starts with a letter followed by any
number of letters or digits was executed successfully .
Expt. No:3(c) Program to recognize a valid control structures syntax of C
language (For loop, while loop, if-else, if-else-if,
Date: switch-case, etc.).

AIM:
To program to recognize a valid control structures syntax of C language (For loop, while loop, if-else, if-
else-if, switch-case, etc.).

ALGORITHM:

Step1: Start the program.


Step2: Read the statement.
Step3: Validating the given statement according to the rule using yacc.
Step4: Using the syntax rule print the result of the given syntax.
Step5: Stop the program.

PROGRAM:
FOR LOOP
LEX PART: for.l
%{
#include<stdio.h>
#include "y.tab.h"
%}
alpha [A-Za-z]
digit [0-9]
%%
[\t \n]
for return FOR;
{digit}+ return NUM;
{alpha}({alpha}|{digit})* return ID;
"<=" return LE;
">=" return GE;
"==" return EQ;
"!=" return NE;
"||" return OR;
"&&" return AND;
. return yytext[0];
%%
yywrap()
{}
YACC PART: for.y
%{
#include <stdio.h>
#include <stdlib.h>
%}
%token ID NUM FOR LE GE EQ NE OR AND
%right '='
%left OR AND
%left '>' '<' LE GE EQ NE
%left '+' '-'
%left '' '/'
%right UMINUS
%left '!'
%%
S : ST {printf("Input accepted\n"); exit(0);};
ST : FOR '(' E ';' E2 ';' E ')' DEF
;
DEF : '{' BODY '}'
| E';'
| ST
|
;
BODY : BODY BODY
| E ';
| ST
|
;
E : ID '=' E
| E '+' E
| E '-' E
| E '' E
| E '/' E
| E '<' E
| E '>' E
| E LE E
| E GE E
| E EQ E
| E NE E
| E OR E
| E AND E
| E '+' '+'
| E '-' '-'
| ID
| NUM
;
E2 : E'<'E
| E'>'E
| E LE E
| E GE E
| E EQ E
| E NE E
| E OR E
| E AND E
;
%%
main() {
printf("Enter the expression:\n") ;
yyparse();
}
yyerror()
{
printf("\nEntered arithmetic expression is Invalid\n\n");
}

OUTPUT:

PROGRAM:
WHILE LOOP
LEX PART : while.l
%{
#include<stdio.h>
#include "y.tab.h"
%}
alpha [A-Za-z]
digit [0-9]
%%
[\t \n]
while return WHILE;
{digit}+ return NUM;
{alpha}({alpha}|{digit})* return ID;
"<=" return LE;
">=" return GE;
"==" return EQ;
"!=" return NE;
"||" return OR;
"&&" return AND;
. return yytext[0];
%%
yywrap()
{}
YACC PART: while.y
%{
#include <stdio.h>
#include <stdlib.h>
%}
%token ID NUM WHILE LE GE EQ NE OR AND
%right '='
%left AND OR
%left '<' '>' LE GE EQ NE
%left '+''-'
%left '''/'
%right UMINUS
%left '!'
%%
S : ST1 {printf("Input accepted.\n");exit(0);};
ST1 : WHILE'(' E2 ')' '{' ST '}'
ST : ST ST
| E';'
;
E : ID'='E
| E'+'E
| E'-'E
| E''E
| E'/'E
| E'<'E
| E'>'E
| E LE E
| E GE E
| E EQ E
| E NE E
| E OR E
| E AND E
| ID
| NUM
;
E2 : E'<'E
| E'>'E
| E LE E
| E GE E
| E EQ E
| E NE E
| E OR E
| E AND E
| ID
| NUM
;
%%
main()
{
printf("Enter the exp: ");
yyparse();
}
yyerror()
{
printf("\nEntered arithmetic expression is Invalid\n\n");
}
OUTPUT:

PROGRAM:
IF THEN ELSE
LEX PART : if.l
%{
#include<stdio.h>
#include "y.tab.h"
%}
alpha [A-Za-z]
digit [0-9]
%%
[ \t\n]
if return IF;
then return THEN;
else return ELSE;
{digit}+ return NUM;
{alpha}({alpha}|{digit})* return ID;
"<=" return LE;
">=" return GE;
"==" return EQ;
"!=" return NE;
"||" return OR;
"&&" return AND;
. return yytext[0];
%%
yywrap()
{}
YACC PART : if.y

%{
#include <stdio.h>
#include <stdlib.h>
%}
%token ID NUM IF THEN LE GE EQ NE OR AND ELSE
%right '='
%left AND OR
%left '<' '>' LE GE EQ NE
%left '+''-'
%left '*''/'
%right UMINUS
%left '!'
%%
S : ST {printf("Input accepted.\n");exit(0);};
ST : IF '(' E2 ')' THEN ST1';' ELSE ST1';'
| IF '(' E2 ')' THEN ST1';'
;
ST1 : ST
|E
;
E : ID'='E
| E'+'E
| E'-'E
| E'*'E
| E'/'E
| E'<'E
| E'>'E
| E LE E
| E GE E
| E EQ E
| E NE E
| E OR E
| E AND E
| ID
| NUM
;
E2 : E'<'E
| E'>'E
| E LE E
| E GE E
| E EQ E
| E NE E
| E OR E
| E AND E
| ID
| NUM
;
%%
main()
{
printf("Enter the exp: ");
yyparse();
}
yyerror()
{
printf("\nEntered arithmetic expression is Invalid\n\n");

}
OUTPUT:

PROGRAM:
IF THEN ELSEIF THEN ELSE
LEX PART : elseif.l
%{
#include<stdio.h>
#include "y.tab.h"
%}
alpha [A-Za-z]
digit [0-9]
%%
[ \t\n]
if return IF;
then return THEN;
else return ELSE;
elseif return ELSEIF;
{digit}+ return NUM;
{alpha}({alpha}|{digit})* return ID;
"<=" return LE;
">=" return GE;
"==" return EQ;
"!=" return NE;
"||" return OR;
"&&" return AND;
. return yytext[0];
%%yywrap()
{}
YACC PART : elseif.y
%{
#include <stdio.h>
#include <stdlib.h>
%}%
token ID NUM IF THEN LE GE EQ NE OR AND ELSE
%right '='
%left AND OR
%left '<' '>' LE GE EQ NE
%left '+''-'
%left '''/'
%right UMINUS
%left '!'
%%
S : ST {printf("Input accepted.\n");exit(0);};
ST : IF '(' E2 ')' THEN ST1';' ELSEIF '(' E2 ')' THEN ST1';' ELSE ST1';'
| IF '(' E2 ')' THEN ST1';'
;
ST1 : ST
|E
;
E : ID'='E
| E'+'E
| E'-'E
| E''E
| E'/'E
| E'<'E
| E'>'E
| E LE E
| E GE E
| E EQ E
| E NE E
| E OR E
| E AND E
| ID
| NUM
;
E2 : E'<'E
| E'>'E
| E LE E
| E GE E
| E EQ E
| E NE E
| E OR E
| E AND E
| ID
| NUM
;
%%
main()
{
printf("Enter the exp: ");
yyparse();
}
yyerror()
{
printf("\nEntered arithmetic expression is Invalid\n\n");
}
OUTPUT:

PROGRAM:
SWITCH
LEX PART : switch.l
%{
#include <stdio.h>
#include “y.tab.h”
%}
alpha[A-Za-z]
digit[0-9]
%%
[ \n\t]
if return IF;
then return THEN;
while return WHILE;
switch return SWITCH;
case return CASE;
default return DEFAULT;
break return BREAK;
{digit}+ return NUM;
{alpha}({alpha}|{digit})* return ID;
"<=" return LE;
">=" return GE;
"==" return EQ;
"!=" return NE;
"&&" return AND;
"||" return OR;
. return yytext[0];
%%
yywrap()
{}
YACC PART : switch.y
%{
#include<stdio.h>
#include “y.tab.h”
%}
%token ID NUM SWITCH CASE DEFAULT BREAK LE GE EQ NE AND OR IF THEN WHILE
%right '='
%left AND OR
%left '<' '>' LE GE EQ NE
%left '+''-'
%left '*''/'
%right UMINUS
%left '!'
%%
S : ST{printf("\nInput accepted.\n");exit(0);};
;
ST : SWITCH'('ID')''{'B'}'
;
B : C
| CD
;
C : CC
| CASE NUM':'ST1 BREAK';'
;
D : DEFAULT':'ST1 BREAK';'
| DEFAULT':'ST1
;
ST1 : WHILE'('E2')' E';'
| IF'('E2')'THEN E';'
| ST1 ST1
| E';'
;
E2 : E'<'E
| E'>'E
| E LE E
| E GE E
| E EQ E
| E NE E
| E AND E
| E OR E
;
E : ID'='E
| E'+'E
| E'-'E
| E'*'E
| E'/'E
| E'<'E
| E'>'E
| E LE E
| E GE E
| E EQ E
| E NE E
| E AND E
| E OR E
| ID
| NUM
;
%%
main()
{
printf("Enter the exp: ");
yyparse();
}
yyerror()
{
printf("\nEntered arithmetic expression is Invalid\n\n");
}

OUTPUT:

RESULT:
Thus the given program to recognize valid control control structures is executed successfully.
Expt.No:4 GENERATE THREE ADDRESS CODE FOR A SIMPLEPROGRAM USING LEX
AND YACC
Date:

AIM:
To convert the given input of BNF rules into Yacc form and to generate a
abstract syntax tree.

ALGORITHM:
Step 1: Start the program.
Step 2: Include the necessary header files.
Step 3: Separate the identifier and the numbers.
Step 4: Use conditions to print the keywords using the lex file.
Step 5: Create a structure and use the variables separately for operands, arguments andresults.
Step 6: Use a stack top push and pop all the contents of the input file to the outputscreen,
Step 7: Use the file functions to read the input from a file.
Step 8: Use string functions to operate on the input.
Step 9: Terminate the program.
PROGRAM:
LEX
%{
#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];
%%
YACC
%{
#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;
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(); 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++;
};
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].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;
}
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);
}
input.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 three address code for a simple program is created and the output isverified
successfully
Expt.NO:5
Implement type checking using Lex and Yacc.
Date:

AIM:

To write a C program to implement type checking.

ALGORITHM:

1. Start the program for type checking of given expression


2. Read the expression and declaration
3. Based on the declaration part define the symbol table
4. Check whether the symbols present in the symbol table or not. If it is found in the symbol table
it displays“Label already defined”.
5. Read the data type of the operand 1, operand 2 and result in the symbol table.
6. If the both the operands’ type are matched then check for result variable. Else, print “Type mismatch”.
7. If all the data type are matched then displays “No type mismatch”.

PROGRAM:

#include<stdio.h>
#include<string.h>
#include<conio.h>
int count=1,i=0,j=0,l=0,findval=0,k=0,kflag=0;
char key[4][12]= {"int","float","char","double"};
char dstr[100][100],estr[100][100];
char token[100],resultvardt[100],arg1dt[100],arg2dt[100];
void entry();
int check(char[]);
int search(char[]);
void typecheck();
struct table
{
char var[10];
char dt[10];
};
struct table tbl[20];
void main()
{
clrscr();
printf("\n IMPLEMENTATION OF TYPE CHECKING \n");
printf("\n DECLARATION \n\n");
do
{
printf("\t");
gets(dstr[i]);
i++;
} while(strcmp(dstr[i-1],"END"));
printf("\n EXPRESSION \n\n");
do
{
printf("\t");
gets(estr[l]);
l++;
}while(strcmp(estr[l-1],"END"));
i=0;
printf("\n SEMANTIC ANALYZER(TYPE CHECKING): \n");
while(strcmp(dstr[i],"END"))
{
entry();
printf("\n");
i++;
}
l=0;
while(strcmp(estr[l],"END"))
{
typecheck();
printf("\n");
l++;
}
printf("\n PRESS ENTER TO EXIT FROM TYPE CHECKING\n");
getch();
}
void entry()
{
j=0;
k=0;
memset(token,0,sizeof(token));
while(dstr[i][j]!=' ')
{
token[k]=dstr[i][j];
k++;
j++;
}
kflag=check(token);
if(kflag==1)
{
strcpy(tbl[count].dt,token);
k=0;
memset(token,0,strlen(token));
j++;
while(dstr[i][j]!=';')
{
token[k]=dstr[i][j];
k++;
j++;
}
findval=search(token);
if(findval==0)
{
strcpy(tbl[count].var,token);
}
else
{
printf("The variable %s is already declared",token);
}
kflag=0;
count++;
}
else
{
printf("Enter valid datatype\n");
}
}
void typecheck()
{
memset(token,0,strlen(token));
j=0;
k=0;
while(estr[l][j]!='=')
{
token[k]=estr[l][j];
k++;
j++;
}
findval=search(token);
if(findval>0)
{
strcpy(resultvardt,tbl[findval].dt);
findval=0;
}
else
{
printf("Undefined Variable\n");
}
k=0;
memset(token,0,strlen(token));
j++;
while(((estr[l][j]!='+')&&(estr[l][j]!='-')&&(estr[l][j]!='*')&&(estr[l][j]!='/')))
{
token[k]=estr[l][j];
k++;
j++;
}
findval=search(token);
if(findval>0)
{
strcpy(arg1dt,tbl[findval].dt);
findval=0;
}
else
{
printf("Undefined Variable\n");
}
k=0;
memset(token,0,strlen(token));
j++;
while(estr[l][j]!=';')
{
token[k]=estr[l][j];
k++;
j++;
}
findval=search(token);
if(findval>0)
{
strcpy(arg2dt,tbl[findval].dt);
findval=0;
}
else
{
printf("Undefined Variable\n");
}
if(!strcmp(arg1dt,arg2dt))
{
if(!strcmp(resultvardt,arg1dt))
{
printf("\tThere is no type mismatch in the expression %s ",estr[l]);
}
else
{
printf("\tLvalue and Rvalue should be same\n");
}
}
else
{
printf("\tType Mismatch\n");
}
}
int search(char variable[])
{
int i;
for(i=1;i<=count;i++)
{
if(strcmp(tbl[i].var,variable) == 0)
{
return i;
}
}
return 0;
}
int check(char t[])
{
int in;
for(in=0;in<4;in++)
{
if(strcmp(key[in],t)==0)
{
return 1;
}
}
return 0;
}
OUTPUT:

RESULT:
Thus the program for type checking is executed and verified.
Expt.No:6 Implement simple code optimization techniques (Constant folding, Strength
reduction and Algebraic transformation)
Date:

AIM:
To write a C program to implement Code Optimization Techniques.

ALGORITHM:
Step 1: Start the program.
Step 2: Include the necessary header files.
Step 3: Declare necessary character arrays for input and output and also a structure toinclude it.
Step 4: Get the Input: Set of ‘L’ values with corresponding ‘R’ values and
Step 5: Implement the principle source of optimization techniques.
Step 6: The Output should be of Intermediate code and Optimized code aftereliminating
common expressions. .
Step 7: Terminate the program.

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 the Number of Values:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("left: ");
op[i].l=getche();
printf("\tright: ");
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);
}
for(m=0;m<z;m++)
{
tem=pr[m].r;
for(j=m+1;j<z;j++)
{
p=strstr(tem,pr[j].r);if(p)
{
t=pr[j].l; pr[j].l=pr[m].l;
for(i=0;i<z;i++)
{
l=strchr(pr[i].r,t) ;if(l)
{
a=l-pr[i].r;
printf("pos: %d",a);
pr[i].r[a]=pr[m].l;
}
}
}
}
}
printf("Eliminate Common Expression\n");
for(i=0;i<z;i++)
{
printf("%c\t=",pr[i].l);
printf("%s\n",pr[i].r);
}
for(i=0;i<z;i++)
{
for(j=i+1;j<z;j++)
{
q=strcmp(pr[i].r,pr[j].r);
if((pr[i].l==pr[j].l)&&!q)
{
pr[i].l='\0';
strcpy(pr[i].r,'\0');
}
}
}
printf("Optimized Code\n");
for(i=0;i<z;i++)
{
if(pr[i].l!='\0')
{
printf("%c=",pr[i].l);
printf("%s\n",pr[i].r);
}
}
getch();

OUTPUT:

RESULT:
Thus the required C program for implementation of code optimizationtechniques is
done and the required output is obtained and verified.
Expt.No:7 Implement back-end of the compiler for which the three address code is given
as input and the 8086 assembly language code is produced as output.
Date:

AIM:
To implement the back end of a compiler which takes the three address code
and produces the 8086 assembly language instructions using a C program.

ALGORITHM:
Step 1: Start the program.
Step 2: Include the necessary header files.
Step 3: Declare necessary character arrays for input and output and also a structure toinclude it.
Step 4: Get the Intermediate Code as the input.
Step 5: Display the options to do the various operations and use a switch case toimplement that
operation.
Step 6: Terminate the program.

PROGRAM:
#include<stdio.h>
#include<stdio.h>
#include<conio.h>
#include<string.h> void
main()
{
char icode[10][30],str[20],opr[10];int i=0;
clrscr();
printf("\n Enter the set of intermediate code (terminated by exit):\n");do
{
scanf("%s",icode[i]);
} while(strcmp(icode[i++],"exit")!=0); printf("\n target
code generation"); printf("\n************************");
i=0;
do
{
strcpy(str,icode[i]);switch(str[3])
{
case '+': strcpy(opr,"ADD");
break;
case '-': strcpy(opr,"SUB");
break;
case '*': strcpy(opr,"MUL");

break; case '/':


strcpy(opr,"DIV");break;
}
printf("\n\tMov %c,R%d",str[2],i);
printf("\n\t%s%c,R%d",opr,str[4],i);
printf("\n\tMov R%d,%c",i,str[0]);
}while(strcmp(icode[++i],"exit")!=0);getch();
}

OUTPUT:

RESULT:
Thus the required C program to implement the back end of the compiler is doneand the required
output is obtained and verified.

You might also like