0% found this document useful (0 votes)
2 views

CD LAN manula re

The document outlines various exercises related to implementing lexical analyzers and parsers using C, Lex, and YACC. It includes detailed algorithms, program codes, and results for recognizing patterns in C, implementing a symbol table, and validating arithmetic expressions, variables, and control structures like for and while loops. Each section concludes with a verification of the output, confirming successful implementation.

Uploaded by

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

CD LAN manula re

The document outlines various exercises related to implementing lexical analyzers and parsers using C, Lex, and YACC. It includes detailed algorithms, program codes, and results for recognizing patterns in C, implementing a symbol table, and validating arithmetic expressions, variables, and control structures like for and while loops. Each section concludes with a verification of the output, confirming successful implementation.

Uploaded by

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

EX.

NO:1 DEVELOP A LEXICAL ANALYZER TO RECOGNIZE A FEW


PATTERNS IN C. (EX.IDENTIFIERS, CONSTANTS, COMMENTS,
OPERATORS ETC.)

AIM:

To Create a Lexical Analyzer using C programming and to create lexemes that is


grouped into various categories.

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 the input

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 a character 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 ;<>{}()#,& and print them as

Special Characters.

Step 8: Using a if condition, print the letters/words following the int, char or float as the

Variables.

Step 9: Using a if condition, print the words printf, scanf, main, void etc as the keywords.

Step 10: Terminate the program.

PROGRAM:

#include<stdio.h>

#include<string.h>

int main()

char tot[100][20];

char a[100],temp[100];
int i=0,j;

FILE *p;

p=fopen("input1.txt","r");

fscanf(p,"%s",a);

strcpy(tot[i],a);

strcpy(temp,"Null"); printf("\

nLexeme\tToken\n\n"); i=1;

while(strcmp(a,"END")!=0)

if((strcmp(a,";")==0)||(strcmp(a,"<")==0)||(strcmp(a,"{")==0)||(strcmp(a,"(")==0)||(strcmp(a,"
)")==

0)||(strcmp(a,"}")==0)||(strcmp(a,"#")==0)||(strcmp(a,">")==0)||(strcmp(a,",")==0)||(strcmp(a,
"&")=

=0))

printf ("\n%s\t", a);

printf("Special Character\t");

else if((strcmp(temp,"int")==0)||(strcmp(temp,"float")==0)||(strcmp(temp,"char")==0))

printf("\n%s\t",a);

printf("variable\t");

else if((strcmp(a,"scanf")==0)||(strcmp(a,"printf")==0)||(strcmp(a,"main")==0)||

(strcmp(a,"void")
==0))

{
printf("\n%s\t",a);

printf("keywords\t");

strcpy(temp,a);

strcpy(tot[i],a);

i++;

fscanf(p,"%s",a);

printf("\t%d",i);

printf("\n%s",tot[i-1]);

}
INPUT:

input1.txt

# include < stdio.h >

void main ( )

int a = 100 ;

END

OUTPUT:

[root@sys70 2]# cc

ex2.c [root@sys70

2]# ./a.out LexemeToken

# Special Character

< Special Character

> Special

Character void

keywords main

keywords

( Special Character

) Special Character

{ Special Character

a variable

; Special Character

} Special Character

RESULT:

Thus the C program to implement the Lexical Analyzer is done and the required
Lexemes are obtained and the output is verified.
EX.NO :1.B IMPLEMENTATION OF SYMBOL TABLE

AIM: To write a C program to implement a symbol table.

ALGORITHM:

Step 1:Start the Program.

Step 2: Get the input from the user with the terminating symbol ‘$’.

Step 3: Allocate memory for the variable by dynamic memory allocation function.

Step 4: If the next character of the symbol is an operator then only the

memory is allocated.

Step 5: While reading , the input symbol is inserted into symbol table

along with its memory address.

Step 6: The steps are repeated till”$”is reached.

Step 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.

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

{
int i=0,j=0,x=0,n,flag=0; void *p,*add[15];

char ch,srch,b[15],d[15],c;

//clrscr();

printf("expression terminated by $:");

while((c=getchar())!='$')

b[i]=c; i++;

n=i-1;

printf("given expression:");

i=0;

while(i<=n)

printf("%c",b[i]);

i++;

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

else

ch=b[j+1];

if(ch=='+'||ch=='-'||ch=='*'||ch=='=')

p=malloc(c);

add[x]=p;

d[x]=c; printf("%c\t%d\

tidentifier\n",c,p); x++;

} j++;

printf(“The symbol is to be

searched”); srch=getch();

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

if(srch==d[i])

printf("symbol found\n"); printf("%c%s%d\

n",srch,"@address",add[i]); flag=1;

if(flag==0)
printf("symbol not found\n");

//getch();

}
OUTPUT:

RESULT:

Thus the C program to implement the symbol table was executed and the

Output is verified.
Ex. No.2 IMPLEMENT A LEXICAL ANALYZER USING LEX TOOL

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("%s=>
Keywords",yytext);}\ #.* { printf("\n%s=>Preprocessor
Directive",yytext);} printf|scanf|main { printf("\n
%s=>functions",yytext);} [a-zA-Z]+ { printf("\n
%s=>Identifiers",yytext);}
["][a-z]["] { printf("\n
%s=>Keywords",yytext);} [0-9] { printf("\n
%s=>Keywords",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:
[root@sys70 3]# lex ex3.l
[root@sys70 3]# cc
lex.yy.c [root@sys70 3]#
./a.out int=> Keywords
main=>functions
(=>Special Characters
)=>Special Characters
{=>Special Characters
int=> Keywords
a=>Identifiers
,=>Special Characters
b=>Identifiers
;=>Special Characters
printf=>functions
(=>Special Characters
"=>Special Characters
hello =>Identifiers
"=>Special Characters
)=>Special Characters
;=>Special Characters
float=> Keywords
c=>Identifiers
;=>Special Characters
char=> Keywords
d=>Identifiers
;=>Special Characters
return=> Keywords
0=>Keywords
;=>Special Characters
}=>Special Characters

RESULT:
Thus the required Lexical Analyzer is designed and the required output is obtained
and verified.
EX.NO:3. A) YACC PROGRAM TO RECOGNIZE A VALID ARITHMETIC
EXPRESSION

AIM:
To write a YACC program to recognize valid arithmetic expression

ALGORITHM:

Step1: Start the program.

Step2: Reading an expression .

Step3: Checking the validating of the given expression according to the rule using yacc.

Step4: Using expression rule print the result of the given values

Step5: Stop the program.

PROGRAM:

//Program to recognize a valid arithmetic expression that uses operator +, -, * and /

LEX PART:

%{

#include "y.tab.h"

%}

%%

[a-zA-Z_][a-zA-Z_0-9]* return id;

[0-9]+(\.[0-9]*)? return num;

[+/*] return op;

. return yytext[0];

\n return 0;

%%

int yywrap()

{
return 1;

YACC PART:

%{

#include<stdio.h>

int valid=1;

%}

%token num id op

%%

start : id '=' s ';'

s: id x

| num x

| '-' num x

| '(' s ')' x

x: op s

| '-' s

%%

int yyerror()

valid=0;

printf("\nInvalid expression!\n");

return 0;
}

int main()

printf("\nEnter the expression:\n");

yyparse();

if(valid)

printf("\nValid expression!\n");

}
OUTPUT:

RESULT:

Thus the arithmetic expression using YACC was recognized successfully.


EX.NO:3 B) YACC PROGRAM TO RECOGNIZE A VALID VARIABLE WHICH
STARTS WITH A LETTER FOLLOWED BY ANY NUMBER OF
LETTERS OR DIGITS

AIM :

To write a yacc program to check valid variable followed by letter or digits

ALGORITHM:

Step1: Start the program

Step2: Reading an expression

Step3: Checking the validating of the given expression according to the rule using yacc.

Step4: Using expression rule print the result of the given values

Step5: Stop the program

PROGRAM CODE:

//Program to recognize a valid variable

LEX PART:

%{

#include "y.tab.h"

%}

%%

[a-zA-Z_][a-zA-Z_0-9]* return letter;

[0-9] return digit;

. return yytext[0];

\n return 0;

%%

int yywrap()

return 1;
}
}

YACC PART:

%{

#include<stdio.h>

int valid=1;

%}

%token digit letter

%%

start : letter s

s: letter s

| digit s

%%

int yyerror()

printf("\nIts not a identifier!\n");

valid=0;

return 0;

int main()

{
printf("\nEnter a name to tested for identifier ");

yyparse();

if(valid)
{

printf("\nIt is a identifier!\n");
}
}
OUTPUT:

RESULT:
Thus the YACC program to recognize valid variable followed by letter or
digits was executed successfully.
EX.NO:3 C I) YACC PROGRAM TO RECONIZE FOR LOOP
STATEMENT

AIM :
To write a yacc program to recognize FOR loop statement.

ALGORITHM:

Step1: Start the program


Step2: Reading the for loop statement.
Step3: Checking the validating of the given for loop according to the rule using yacc.
Step4: Using expression rule print the result of the given values
Step5: Stop the program

PROGRAM:

// Lex file: for.l

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

// Yacc file: 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
;
%%

#include "lex.yy.c"
main() {
printf("Enter the expression:\n");
yyparse();
}

Output:
nn@linuxmint ~ $ lex for.l
nn@linuxmint ~ $ yacc
for.y
conflicts: 25 shift/reduce, 4 reduce/reduce
nn@linuxmint ~ $ gcc y.tab.c -ll -ly
nn@linuxmint ~ $ ./a.out
Enter the expression:
for(i=0;i<n;i++)
i=i+1;
Input accepted

RESULT:
Thus the YACC program for FOR loop statement was executed successfully.
EX.NO:3 C II) YACC PROGRAM TO RECONIZE WHILE LOOP
STATEMENT

AIM :

To write a yacc program to recognize while loop statement.

ALGORITHM:

Step 1: Start the program

Step 2: Reading the WHILE loop statement.

Step 3: Checking the validating of the given WHILE loop according to the rule using
yacc.

Step 4: Using expression rule print the result of the given values

Step5 : Stop the program

PROGRAM:

(wh.l)

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

(wh.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
;

%%

#include "lex.yy.c"

main()
{
printf("Enter the exp:
"); yyparse();
}
OUTPUT:

students@ccflab-desktop:~$ lex wh.l


students@ccflab-desktop:~$ yacc wh.y
conflicts: 2 shift/reduce
students@ccflab-desktop:~$ gcc y.tab.c -ll -
ly students@ccflab-desktop:~$ ./a.out
Enter the exp: while(a>1){
b=1;} Input accepted

RESULT:
Thus the YACC program for WHILE loop statement was executed successfully.
EX.NO:3C III) YACC PROGRAM TO RECONIZE WHILE SWITCH
CASE STATEMENT

AIM :

To write a yacc program to recognize SWITCH CASE statement.

ALGORITHM:

Step 1: Start the program


Step 2: Reading the SWITCH CASE statement.
Step 3: Checking the validating of the given SWITCH CASE statement according
to the rule using yacc.
Step 4: Using expression rule print the result of the given values
Step5: Stop the program

PROGRAM:
(sw.l)
alpha [A-Za-z]
digit [0-9]
%%
[ \t\n]
switch return SWITCH;
case return CASE;
break return BREAK;
default return
DEFAULT;
{digit}+ return NUM;
{alpha}({alpha}|{digit})* return ID;
"<=" return LE;
">=" return GE;
"==" return EQ; "!
=" return NE;
"||" return OR;
"&&" return
AND;
. return yytext[0];
%%

(sw.y)
%{
#include <stdio.h>
#include <stdlib.h>
%}
%token ID NUM SWITCH CASE DEFAULT BREAK 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 : SWITCH '(' ID ')' '{' B '}'
;

B : C
| C D
;

C : C C
| CASE NUM ':' E ';'
| BREAK ';'
;

D : DEFAULT ':' E ';' BREAK ';'


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

%%

#include "lex.yy.c"

main()
{
printf("Enter the exp:
"); yyparse();
}
OUTPUT:

students@cselab-desktop:~$ lex sw.l


students@cselab-desktop:~$ yacc
sw.y conflicts: 2 shift/reduce
students@cselab-desktop:~$ gcc y.tab.c -ll -
ly students@cselab-desktop:~$ ./a.out
Enter the exp: switch(a)
{
case 1: a=1;
break;
case 2: a=2;
break;
default:a=0
;
break;
}
Input accepted.

RESULT:
Thus the YACC program for SWITCH CASE statement was executed successfully.
EX.NO:3 D IMPLEMENTATION OF CALCULATOR USING LEX & YACC

AIM:

To write a program for implementing a calculator for computing the given


expression using semantic rules of the YACC tool and LEX.

ALGORITHM:

Step1: A Yacc source program has three parts as follows:

Declarations %% translation rules %% supporting C routines

Step2: Declarations Section: This section contains entries that:

i. Include standard I/O header file.

ii. Define global variables.

iii. Define the list rule as the place to start processing.

iv. Define the tokens used by the parser. v. Define the operators and their precedence.

Step3: Rules Section: The rules section defines the rules that parse the input stream.
Each rule of a grammar production and the associated semantic action.

Step4: Programs Section: The programs section contains the following subroutines.
Because these subroutines are included in this file, it is not necessary to use the yacc
library when processing this file.

Step5: Main- The required main program that calls the yyparse subroutine to start the
program.

Step6: yyerror(s) -This error-handling subroutine only prints a syntax error message.
Step7: yywrap -The wrap-up subroutine that returns a value of 1 when the end of
input occurs. The calc.lex file contains include statements for standard input and
output, as programmar 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.

Step8: calc.lex contains the rules to generate these tokens from the input stream.

PROGRAM :

//Implementation of calculator using LEX and YACC

LEX PART:

%{

#include<stdio.h>

#include "y.tab.h"

extern int yylval;

%}

%%

[0-9]+ {

yylval=atoi(yytext);

return NUMBER;
}

[\t] ;

[\n] return 0;

. return yytext[0];

%%

int yywrap()

return 1;

YACC PART:

%{

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

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:

RESULT:
Thus the program for implementing a calculator for computing the given expression
using semantic rules of the YACC tool and LEX was executed successfully.
EX .NO :4 GENERATE THREE ADDRESS CODE FOR A SIMPLE PROGRAM
USING LEX AND YACC

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 and
results.
Step 6: Use a stack top push and pop all the contents of the input file to the output screen.
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:
ex5.l
%{
#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];
%%
ex5.y
%{
#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++;
};
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].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:
[root@sys70 5]# lex ex5.l
[root@sys70 5]# yacc -d ex5.y [root@sys70 5]# cc y.tab.c lex.yy.c -ll
[root@sys70 5]# ./a.out input.c

Pos Operator Arg1 Arg2 Result

0 < a b t0
1 == t0 FALSE 5
2 + a b t1
3 = t1 a
4 GOTO 5
5 < a b t2
6 == t2 FALSE 10
7 + a b t3
8 = t3 a
9 GOTO 5
10 <= a b t4
11 == t4 FALSE 15
12 - a b t5
13 = t5 c
14 GOTO 17
15 + a b t6
16 = t6 c

RESULT:
Thus the three address code for a simple program is created and the output is verified
successfully.
EX. NO : 5 IMPLEMENTATION OF TYPE CHECKING

AIM:
To write a lex and YACC program to implement type checking .

ALGORITHM:

Step1: Track the global scope type information (e.g. classes and their members)
Step2: Determine the type of expressions recursively, i.e. bottom-up, passing the
resulting types upwards.
Step3: If type found correct, do the operation
Step4: Type mismatches, semantic error will be notified

PROGRAM :

//To implement type


checking #include<stdio.h>
#include<stdlib.h>
int main()
{
int n,i,k,flag=0;
char vari[15],typ[15],b[15],c;
printf("Enter the number of variables:");
scanf(" %d",&n);
for(i=0;i<n;i++)
{
printf("Enter the variable[%d]:",i);
scanf(" %c",&vari[i]);
printf("Enter the variable-type[%d](float-f,int-i):",i);
scanf(" %c",&typ[i]);
if(typ[i]=='f')
flag=1;
}
printf("Enter the Expression(end with
$):"); i=0;
getchar();
while((c=getchar())!='$')
{
b[i]=c;
i++; }
k=i;
for(i=0;i<k;i++)
{
if(b[i]=='/')
{
flag=1;
break; } }
for(i=0;i<n;i++)
{
if(b[0]==vari[i])
{
if(flag==1)
{
if(typ[i]=='f')
{ printf("\nthe datatype is correctly defined..!\n");
break; }
else
{ printf("Identifier %c must be a float type..!\n",vari[i]);
break; } }
else
{ printf("\nthe datatype is correctly defined..!\n");
break; } }
}
return 0;
}
OUTPUT:

RESULT:
Thus the program for type checking in LEX and YACC was implemented successfully.
EX. NO : 6 IMPLEMENT SIMPLE CODE OPTIMIZATION TECHNIQUES

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 to
include it.
Step 4: Get the Input: Set of ‘L’ values with corresponding ‘R’ values and
Step 4: Implement the principle source of optimization techniques.
Step 5: The Output should be of Intermediate code and Optimized code after eliminating
common expressions.
Step 6: 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:
Enter the Number of Values: 5
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
After Dead Code
Elimination b =c+d
e
=c+d f
=b+e r
=:f
Eliminate Common Expression
b =c+d
b
=c+d f
=b+b r
=:f
Optimized Code
b=c+d
f=b+b
r=:f

RESULT:
Thus the required C program for implementation of code optimization techniques is
done and the required output is obtained and verified.
Ex.No.7 IMPLEMENTING THE BACK END OF THE COMPILER

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 to
include 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 to implement
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 '/': lOMoARcPSD|
5550124 15
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:
Enter the set of intermediate code(terminated by exit):
d=2/3
c=4/5
a=2*
e exit
target code generation
******************************************************************
MOV 2,R0
DIV 3,R0
MOV R0,d
MOV 4,R1
DIV5,R1
MOV R1.c
MOV 2,,R2
MULe,R2
MOV R2,a

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

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy