0% found this document useful (0 votes)
29 views29 pages

20DCS020 DLP

Uploaded by

20dcs109
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)
29 views29 pages

20DCS020 DLP

Uploaded by

20dcs109
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/ 29

CS450-Design of Language Processor 20DCS109

PRACTICAL 1

AIM:
Write a Lex program to count the number of characters, words and lines in the given input.
Supplementary Experiment:
1. Implement a lexical analyzer for a subset of Java using LEX. Implementation should
support Error handling. [L: M]

IMPLEMENTATION:
 lex <filename with .l extension>
In this case, create an extra text file named input.txt which will contain some sample text to work
as input for lexical analysis.

CODE:

%{
int charCount = 0;
int wordCount = 0;
int lineCount = 0;
int inWord = 0;
int inSingleLineComment = 0;
int inMultiLineComment = 0;
%}

%x COMMENT

%%
"//" { inSingleLineComment = 1; BEGIN(COMMENT); }
"/*" { inMultiLineComment = 1; BEGIN(COMMENT); }
<COMMENT>"*/" { inMultiLineComment = 0; BEGIN(INITIAL); }
<COMMENT>. { /* Inside a multi-line comment, ignore */ }

[\t ]+ { if (inWord) { wordCount++; inWord = 0; } /* whitespace, end of word */ }


\n {
charCount++;
if (inWord) { wordCount++; inWord = 0; }
lineCount++;
if (inSingleLineComment) {
inSingleLineComment = 0;
BEGIN(INITIAL);
}
}
. { charCount++; inWord = 1; }

%%

DEPSTAR-CSE Page No. 1


CS450-Design of Language Processor 20DCS109
int main() {
yylex();
printf("Character Count: %d\n", charCount);
printf("Word Count: %d\n", wordCount);
printf("Line Count: %d\n", lineCount);
return 0;
}

Input.txt
This is a sample text.
It has multiple lines.
// This is a single-line comment.
/* This is
a multi-line
comment. */
Counting words and characters.

OUTPUT:

CONCLUSION:
In conclusion, the provided Lex program effectively counts the number of characters, words, and
lines in a given input text, while also handling single-line and multi-line comments gracefully. It
demonstrates the use of Lex states to transition between regular parsing and comment handling
states, ensuring that comments do not interfere with the counting process.

DEPSTAR-CSE Page No. 2


CS450-Design of Language Processor 20DCS109
PRACTICAL 2

AIM:
Implement a lexical analyzer for identification of numbers.

IMPLEMENTATION:
 lex <filename with .l extension>
 gcc <newly created .c file> -o <file name for exe file>
 <filename of exe file>

CODE:
bin (0|1)+
char [A-Za-z]+
digit [0-9]
oct [0-7]
dec [0-9]*
float {digit}+("."{digit}+)
exp {digit}+("."{digit}+)?("E"("+"|"-")?{digit}+)?
hex [0-9a-fA-F]+

%%
{bin} {printf("\n %s= it is a binary number",yytext);}
{char} {printf("\n %s=it is a char",yytext);}
{oct} {printf("\n %s=it is a octal number",yytext);}
{digit} {printf("\n %s=it is a digit",yytext);}
{dec} {printf("\n %s=it is a decimal",yytext);}
{float} {printf("\n %s=it is a float",yytext);}
{exp} {printf("\n %s=it is a exp",yytext);}
{hex} {printf("\n %s=it is a hex",yytext);}
%%
int yywrap()
{
return 1;
}
int main()
{
printf("Enter the number=");
yylex();
return 0;
}

DEPSTAR-CSE Page No. 3


CS450-Design of Language Processor 20DCS109

OUTPUT:

CONCLUSION:
In this practical, we learnt about lexical analysis for numbers and characters.

DEPSTAR-CSE Page No. 4


CS450-Design of Language Processor 20DCS109
PRACTICAL 3
AIM:
Implement a Calculator using LEX and YACC.

IMPLEMENTATION:
 lex <filename with .l extension>
 yacc <filename with .y extension>
 gcc <newly created .c file from yacc> -o <file name for exe file>
 <filename of exe file>

CODE:
Lex File:

DIGIT [0-9]
%option noyywrap
%%
{DIGIT} { yylval=atof(yytext); return NUM;}
\n|. {return yytext[0];}
Yacc File:
%{
#include<ctype.h>
#include<stdio.h>
#define YYSTYPE double
%}
%token NUM
%left '+' '-'
%left '*' '/'
%%
S : S E '\n' { printf("Answer: %g \nEnter:\n", $2); }
| S '\n'
|
| error '\n' { yyerror("Error: Enter once more�\n" );yyerrok; }
;
E : E '+' E { $$ = $1 + $3; }
| E'-'E { $$=$1-$3;}
| E'*'E {$$=$1*$3;}
| E'/'E {$$=$1/$3;}
| NUM
;
%%
#include "lex.yy.c"
int main()
{
printf("Enter the expression: ");
yyparse();
}

DEPSTAR-CSE Page No. 5


CS450-Design of Language Processor 20DCS109

yyerror (char * s)
{
printf ("% s \n", s);
exit (1);
}

OUTPUT:

CONCLUSION:
In this practical, we learnt implemented a calculator using lex and yacc which takes expression as
input and perform basic arithmetic operations.

DEPSTAR-CSE Page No. 6


CS450-Design of Language Processor 20DCS109
PRACTICAL 4
AIM:
Implement a program to identify keywords and identifiers using finite automata.

IMPLEMENTATION:
· python <filename with .py extension>

CODE:
import re

# Define keywords for Python and Java


python_keywords = {'if', 'else', 'while', 'for', 'def', 'class', 'return', 'import'}
java_keywords = {'if', 'else', 'while', 'for', 'class', 'return', 'import', 'public', 'private', 'static'}

# Define a function to tokenize input


def tokenize(input_str, language='python'):
keywords = python_keywords if language == 'python' else java_keywords
tokens = []

# Define regex patterns for identifiers and whitespace


identifier_pattern = r'[a-zA-Z_][a-zA-Z0-9_]*'
whitespace_pattern = r'\s+'

# Combine all regex patterns


combined_pattern = f'({"|".join(keywords)}|{identifier_pattern}|{whitespace_pattern})'

# Tokenize using regex


for match in re.finditer(combined_pattern, input_str):
token = match.group(0)
if token in keywords:
tokens.append((token, 'Keyword'))
elif re.match(identifier_pattern, token):
tokens.append((token, 'Identifier'))
elif re.match(whitespace_pattern, token):
pass # Ignore whitespace
else:
tokens.append((token, 'Unknown'))

return tokens

# Test with Python code


python_code = """
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)
"""

DEPSTAR-CSE Page No. 7


CS450-Design of Language Processor 20DCS109
python_tokens = tokenize(python_code, language='python')
for token, token_type in python_tokens:
print(f"{token}: {token_type}")

# Test with Java code


java_code = """
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
"""

java_tokens = tokenize(java_code, language='java')


for token, token_type in java_tokens:
print(f"{token}: {token_type}")

OUTPUT:

CONCLUSION:
This practical experiment demonstrates the versatility of finite automata in language tokenization
and highlights the importance of adapting the automaton's rules and keywords to specific
programming languages for accurate recognition.

DEPSTAR-CSE Page No. 8


CS450-Design of Language Processor 20DCS109
PRACTICAL 5
AIM:
Write an ambiguous CFG to recognize an infix expression and implement a parser that
recognizes the infix expression using YACC.

IMPLEMENTATION:
 yacc <filename with .y extension>
 gcc <newly created .c file> -o <file name for exe file>
 <filename of exe file>

CODE:
%{
/*** Auxiliary declarations section ***/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

/* Custom function to print an operator*/


void print_operator(char op);

/* Variable to keep track of the position of the number in the input */


int pos=0;
char p;
%}

/*** YACC Declarations section ***/


%token NUM
%left '+'
%left '*'
%%

/*** Rules Section ***/


start : expr '\n' {exit(1);}
;

expr: expr '+' expr {print_operator('+');}


| expr '*' expr {print_operator('*');}
| '(' expr ')'
| NUM {printf("%c ",p);}
;

%%

/*** Auxiliary functions section ***/

void print_operator(char c){


DEPSTAR-CSE Page No. 9
CS450-Design of Language Processor 20DCS109
switch(c){
case '+' : printf("+ ");
break;
case '*' : printf("* ");
break;
}
return;
}

yyerror(char const *s)


{
printf("yyerror %s",s);
}

yylex(){
char c;
c = getchar();
p=c;
if(isdigit(c)){
pos++;
return NUM;
}
else if(c == ' '){
yylex(); /*This is to ignore whitespaces in the input*/
}
else {
return c;
}
}

main()
{
yyparse();
return 1;
}

OUTPUT:
DEPSTAR-CSE Page No. 10
CS450-Design of Language Processor 20DCS109

CONCLUSION:
In this practical, we learnt about yacc and performed infix to postfix conversion.

DEPSTAR-CSE Page No. 11


CS450-Design of Language Processor 20DCS109
PRACTICAL 6
AIM:
Implement a C program to find FIRST and FOLLOW set of given grammar.

IMPLEMENTATION:
· gcc <newly created .c file> -o <file name for exe file>
· <filename of exe file>

CODE:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_PROD 10
#define MAX_LENGTH 10

struct Production {
char nonTerminal;
char body[MAX_LENGTH];
};

struct Set {
char values[MAX_LENGTH];
};

void addToSet(struct Set *s, char value) {


if (strchr(s->values, value) == NULL) {
strncat(s->values, &value, 1);
}
}

void calculateFirst(struct Production productions[], int n, struct Set firstSets[]) {


int changed = 1;
while (changed) {
changed = 0;
for (int i = 0; i < n; i++) {
struct Production production = productions[i];
char nonTerminal = production.nonTerminal;
char firstChar = production.body[0];

if (firstChar >= 'A' && firstChar <= 'Z') {


int foundEpsilon = 1;
int j = 0;
while (production.body[j] != '\0') {
char currentChar = production.body[j];
if (currentChar >= 'A' && currentChar <= 'Z') {
if (strchr(firstSets[currentChar - 'A'].values, 'e') == NULL) {

DEPSTAR-CSE Page No. 12


CS450-Design of Language Processor 20DCS109
foundEpsilon = 0;
break;
}
} else {
addToSet(&firstSets[nonTerminal - 'A'], currentChar);
foundEpsilon = 0;
break;
}
j++;
}
if (foundEpsilon) {
addToSet(&firstSets[nonTerminal - 'A'], 'e');
}
} else {
addToSet(&firstSets[nonTerminal - 'A'], firstChar);
}
}
}
}

void calculateFollow(struct Production productions[], int n, struct Set firstSets[], struct Set
followSets[]) {
addToSet(&followSets[0], '$'); // Start symbol

int changed = 1;
while (changed) {
changed = 0;
for (int i = 0; i < n; i++) {
struct Production production = productions[i];
char nonTerminal = production.nonTerminal;

for (int j = 0; j < strlen(production.body); j++) {


char currentChar = production.body[j];

if (currentChar >= 'A' && currentChar <= 'Z') {


int k = j + 1;
while (k < strlen(production.body)) {
char nextChar = production.body[k];
if (nextChar >= 'A' && nextChar <= 'Z') {
addToSet(&followSets[currentChar - 'A'], nextChar);
if (strchr(firstSets[nextChar - 'A'].values, 'e') == NULL) {
break;
}
} else {
addToSet(&followSets[currentChar - 'A'], nextChar);
break;
}
k++;
}
DEPSTAR-CSE Page No. 13
CS450-Design of Language Processor 20DCS109
if (k == strlen(production.body)) {
addToSet(&followSets[currentChar - 'A'], nonTerminal);
}
}
}
}
}
}

int main() {
struct Production productions[MAX_PROD];
int n;

// Example grammar
n = 3;
productions[0].nonTerminal = 'S';
strcpy(productions[0].body, "AB");

productions[1].nonTerminal = 'A';
strcpy(productions[1].body, "aA|e");

productions[2].nonTerminal = 'B';
strcpy(productions[2].body, "bB|e");

struct Set firstSets[MAX_PROD];


struct Set followSets[MAX_PROD];

for (int i = 0; i < MAX_PROD; i++) {


firstSets[i].values[0] = '\0';
followSets[i].values[0] = '\0';
}

calculateFirst(productions, n, firstSets);
calculateFollow(productions, n, firstSets, followSets);

printf("FIRST Sets:\n");
for (int i = 0; i < n; i++) {
printf("FIRST(%c): %s\n", productions[i].nonTerminal, firstSets[i].values);
}

printf("\nFOLLOW Sets:\n");
for (int i = 0; i < n; i++) {
printf("FOLLOW(%c): %s\n", productions[i].nonTerminal, followSets[i].values);
}

return 0;
}

DEPSTAR-CSE Page No. 14


CS450-Design of Language Processor 20DCS109
OUTPUT:

CONCLUSION:

In conclusion, the provided C program successfully calculates the FIRST and FOLLOW sets for
a given context-free grammar. It demonstrates the core concepts of parsing and analyzing
grammars using these sets to determine the possible first symbols and the symbols that can
follow non-terminals.

DEPSTAR-CSE Page No. 15


CS450-Design of Language Processor 20DCS109
PRACTICAL 7
AIM:
Write a program to remove the Left Recursion from a given grammar.

IMPLEMENTATION:
· gcc <newly created .c file> -o <file name for exe file>
· <filename of exe file>

CODE:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_PROD 10
#define MAX_LENGTH 10

struct Production {
char nonTerminal;
char body[MAX_LENGTH];
};

void removeLeftRecursion(struct Production productions[], int n, char nonTerminal) {


char newNonTerminal = nonTerminal + 1;
int count = n;

// Create new productions without left recursion


for (int i = 0; i < n; i++) {
struct Production production = productions[i];

if (production.nonTerminal == nonTerminal) {
// Create productions without left recursion
char temp[MAX_LENGTH];
strcpy(temp, production.body);
char* token = strtok(temp, "|");
while (token != NULL) {
struct Production newProduction;
newProduction.nonTerminal = newNonTerminal;
strcpy(newProduction.body, token);
productions[count++] = newProduction;
token = strtok(NULL, "|");
}
} else {
// Append newNonTerminal to productions
strcat(production.body, newNonTerminal);
productions[i] = production;
}
}

DEPSTAR-CSE Page No. 16


CS450-Design of Language Processor 20DCS109
// Add epsilon production
struct Production epsilonProduction;
epsilonProduction.nonTerminal = newNonTerminal;
strcpy(epsilonProduction.body, "e");
productions[count++] = epsilonProduction;

// Replace nonTerminal with epsilon in original productions


for (int i = 0; i < n; i++) {
struct Production production = productions[i];
if (production.nonTerminal == nonTerminal) {
strcpy(production.body, "");
productions[i] = production;
}
}
}

int main() {
struct Production productions[MAX_PROD];
int n;

// Example grammar with left recursion


n = 1;
productions[0].nonTerminal = 'A';
strcpy(productions[0].body, "Aa|b");

printf("Original Grammar:\n");
for (int i = 0; i < n; i++) {
printf("%c -> %s\n", productions[i].nonTerminal, productions[i].body);
}

char nonTerminal = 'A';


removeLeftRecursion(productions, n, nonTerminal);

printf("\nGrammar after Removing Left Recursion:\n");


for (int i = 0; i < n; i++) {
if (strlen(productions[i].body) > 0) {
printf("%c -> %s\n", productions[i].nonTerminal, productions[i].body);
}
}

return 0;
}

DEPSTAR-CSE Page No. 17


CS450-Design of Language Processor 20DCS109
OUTPUT:

CONCLUSION:

The program successfully removes left recursion from the given grammar and produces the
modified grammar as output. Left recursion removal is a crucial step in grammar transformation
for various parsing algorithms. This example demonstrates a simple approach to address left
recursion in a context-free grammar.

DEPSTAR-CSE Page No. 18


CS450-Design of Language Processor 20DCS109
PRACTICAL 8
AIM:
Implementation of Context Free Grammar.

IMPLEMENTATION:
 gcc <our .c file> -o <file name for exe file>
 <filename of exe file>
In this case, create a syntax.txt file as input for the executable which will contain following
statements.
S aBaA
S AB
A Bc
Bc

CODE:
//CFG

#include<stdio.h>
#include<string.h>
#include<conio.h>

int i,j,k,l,m,n=0,o,p,nv,z=0,t,x=0;
char str[10],temp[20],temp2[20],temp3[20];

struct prod
{
char lhs[10],rhs[10][10];
int n;
}pro[10];

void findter()
{
for(k=0;k<n;k++)
{
if(temp[i]==pro[k].lhs[0])
{
for(t=0;t<pro[k].n;t++)
{
for(l=0;l<20;l++)
temp2[l]='\0';
for(l=i+1;l<strlen(temp);l++)
temp2[l-i-1]=temp[l];
for(l=i;l<20;l++)
temp[l]='\0';
for(l=0;l<strlen(pro[k].rhs[t]);l++)
temp[i+l]=pro[k].rhs[t][l];
strcat(temp,temp2);
if(str[i]==temp[i])
DEPSTAR-CSE Page No. 19
CS450-Design of Language Processor 20DCS109
return;
else if(str[i]!=temp[i] && temp[i]>=65 && temp[i]<=90)
break;
}
break;
}
}
if(temp[i]>=65 && temp[i]<=90)
findter();
}

int main()
{
FILE *f;
// clrscr();

for(i=0;i<10;i++)
pro[i].n=0;

f=fopen("input.txt","r");
while(!feof(f))
{
fscanf(f,"%s",pro[n].lhs);
if(n>0)
{
if( strcmp(pro[n].lhs,pro[n-1].lhs) == 0 )
{
pro[n].lhs[0]='\0';
fscanf(f,"%s",pro[n-1].rhs[pro[n-1].n]);
pro[n-1].n++;
continue;
}
}
fscanf(f,"%s",pro[n].rhs[pro[n].n]);
pro[n].n++;
n++;
}
n--;

printf("\n\nTHE GRAMMAR IS AS FOLLOWS\n\n");


for(i=0;i<n;i++)
for(j=0;j<pro[i].n;j++)
printf("%s -> %s\n",pro[i].lhs,pro[i].rhs[j]);

while(1)
{
for(l=0;l<10;l++)
str[0]=NULL;

DEPSTAR-CSE Page No. 20


CS450-Design of Language Processor 20DCS109
printf("\n\nENTER ANY STRING ( 0 for EXIT ) : ");
scanf("%s",str);
if(str[0]=='0')
printf("Exit");
// exit(1);
for(j=0;j<pro[0].n;j++)
{
for(l=0;l<20;l++)
temp[l]=NULL;
strcpy(temp,pro[0].rhs[j]);
m=0;
for(i=0;i<strlen(str);i++)
{
if(str[i]==temp[i])
m++;
else if(str[i]!=temp[i] && temp[i]>=65 && temp[i]<=90)
{
findter();
if(str[i]==temp[i])
m++;
}
else if( str[i]!=temp[i] && (temp[i]<65 || temp[i]>90) )
break;
}

if(m==strlen(str) && strlen(str)==strlen(temp))


{
printf("\n\nTHE STRING can be PARSED !!!");
break;
}
}
if(j==pro[0].n)
printf("\n\nTHE STRING can NOT be PARSED !!!");
}
getch();
}

OUTPUT:
DEPSTAR-CSE Page No. 21
CS450-Design of Language Processor 20DCS109

CONCLUSION:

In this practical, we learnt about Context Free Grammar and implemented the concept using C.

DEPSTAR-CSE Page No. 22


CS450-Design of Language Processor 20DCS109
PRACTICAL 9
AIM:
Implementation of code generator.

IMPLEMENTATION:
 gcc <our .c file> -o <file name for exe file>
 <filename of exe file>

Content of Input1.txt:
a=b+c;
d=n+s;
p=q;

CODE:
// Pgm for Code generation by using simple code generation algorithm

#include<stdio.h>
#include<string.h>
struct table{
char op1[2];
char op2[2];
char opr[2];
char res[2];
}tbl[100];

void add(char *res,char *op1, char *op2,char *opr)


{
FILE *ft;
char string[20];
char sym[100];
ft=fopen("result.asm","a+");
if(ft==NULL)
ft=fopen("result.asm","w");
printf("\nUpdating Assembly Code for the Input File : File : Result.asm ; Status [ok]\n");
//sleep(2);
strcpy(string,"mov r0,");
strcat(string,op1);
if(strcmp(opr,"&")==0)
{
//do nothing
}
else
{
strcat(string,"\nmov r1,");
strcat(string,op2);
}
fputs(string,ft);
if(strcmp(opr,"+")==0)
DEPSTAR-CSE Page No. 23
CS450-Design of Language Processor 20DCS109
strcpy(string,"\nadd r0,r1\n");
else if(strcmp(opr,"-")==0)
strcpy(string,"\nsub r0,r1\n");
else if(strcmp(opr,"/")==0)
strcpy(string,"\ndiv r0,r1\n");
else if(strcmp(opr,"*")==0)
strcpy(string,"\nmul r0,r1\n");
else if(strcmp(opr,"&")==0)
strcpy(string,"\n");
else
strcpy(string,"\noperation r0,r1\n");
fputs(string,ft);
strcpy(string,"mov ");
strcat(string,res);
strcat(string,", r0\n");
fputs(string,ft);
fclose(ft);
string[0]='\0';
sym[0]='\0';
}
main()
{
int res,op1,op2,i,j,opr;
FILE *fp;
char filename[50];
char s,s1[10];
system("clear");
remove("result.asm");
remove("result.sym");
res=0;op1=0;op2=0;i=0;j=0;opr=0;
printf("\n Enter the Input Filename with no white spaces:");
scanf("%s",filename);
fp=fopen(filename,"r");
if(fp==NULL)
{
printf("\n cannot open the input file !\n");
return(0);
}
else
{
while(!feof(fp))
{
s=fgetc(fp);
if(s=='=')
{
res=1;
op1=op2=opr=0;
s1[j]='\0';
strcpy(tbl[i].res,s1);
DEPSTAR-CSE Page No. 24
CS450-Design of Language Processor 20DCS109
j=0;
}
else if(s=='+'||s=='-'||s=='*'||s=='/')
{
op1=1;
opr=1;
s1[j]='\0';
tbl[i].opr[0]=s;
tbl[i].opr[1]='\0';
strcpy(tbl[i].op1,s1);
j=0;
}
else if(s==';')
{

if(opr) // for 3 operand format ex: a=b+c;


{
op2=1;
s1[j]='\0';
strcpy(tbl[i].op2,s1);
}
else if(!opr) // for 2 operand format ex: d=a;
{
op1=1;
op2=0;
s1[j]='\0';
strcpy(tbl[i].op1,s1);
strcpy(tbl[i].op2,"&"); // simplifying the expr
strcpy(tbl[i].opr,"&"); //-------"--"----------
}
add(tbl[i].res,tbl[i].op1,tbl[i].op2,tbl[i].opr);
i++;
j=0;
opr=op1=op2=res=0;
}
else
{
s1[j]=s;
j++;
}
}
system("clear");
}
return 0;
}

OUTPUT:
DEPSTAR-CSE Page No. 25
CS450-Design of Language Processor 20DCS109

CONCLUSION:
In this practical, we learnt about code generation and implemented the same using C.

DEPSTAR-CSE Page No. 26


CS450-Design of Language Processor 20DCS109
PRACTICAL 10
AIM:
Implementation of code optimization for Common sub-expression elimination, Loop invariant code
movement.

IMPLEMENTATION:
 gcc <our .c file> -o <file name for exe file>
 <filename of exe file>

CODE:
#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);
//n=5;
for (i = 0; i < n; i++)
{
printf("\t left: \t");

scanf(" %c", &op[i].l);


printf("\t right: \t");
scanf("%s", op[i].r);
}
/*for (i = 0; i < n; i++)
{
printf("\n right: \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);
}
DEPSTAR-CSE Page No. 27
CS450-Design of Language Processor 20DCS109
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("\n after dead code elimination \n");
for (k = 0; k < z; k++)
{
printf("%c = \t ",pr[k].l);
printf("%s \n",pr[k].r);
}
//sub expression elimination

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);
DEPSTAR-CSE Page No. 28
CS450-Design of Language Processor 20DCS109
printf("%s\n", pr[i].r);
}
// duplicate production elimination
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';
//pr[i].r = "NULL";
strcpy( pr[i].r , "NULL");
}
}
}
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:

CONCLUSION:
In this practical, we learnt about code optimization and implemented the same using C.

DEPSTAR-CSE Page No. 29

You might also like