0% found this document useful (0 votes)
10 views52 pages

160 PCD

The document outlines the record note and bonafide certificate for the Principles of Compiler Design Laboratory course for the academic year 2024-2025. It includes the department's vision, mission, program educational objectives, program outcomes, and program specific outcomes for Computer Science and Engineering. Additionally, it provides details on various experiments related to implementing a lexical analyzer and a recursive descent parser.

Uploaded by

malliprasaths
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)
10 views52 pages

160 PCD

The document outlines the record note and bonafide certificate for the Principles of Compiler Design Laboratory course for the academic year 2024-2025. It includes the department's vision, mission, program educational objectives, program outcomes, and program specific outcomes for Computer Science and Engineering. Additionally, it provides details on various experiments related to implementing a lexical analyzer and a recursive descent parser.

Uploaded by

malliprasaths
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/ 52

RECORD NOTE

Name:

Register No:

Year and Semester:

Branch and Section:

Course Code and Title: 21PD19 / Principles of Compiler Design Laboratory.

Academic Year: 2024 – 2025.


BONAFIDE CERTIFICATE

Register Number:

Certified that this is the Bonafide Record of work done by Mr. / Ms.

of III / VI (year/semester)

B.E/B.Tech Computer Science and Engineering (Branch) during the academic

year 2024-2025 in the 21PD19 / Principles of Compiler Design Laboratory.

Date: Faculty in-charge

Register Number:
Submitted for the End Semester Practical Examination held on

at Karpagam College of Engineering, Coimbatore.

Internal Examiner External Examiner


DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING

VISION

To create computer professionals with a strong academic and technical background to achieve special

distinction at the national and international arena and also to serve and lead the society.

MISSION

➢ Providing excellent learning opportunities for students in Computer Science and Engineering to meet the

needs of Nation as a whole.

➢ Establishing centers of research in areas of the immediate needs to the society.

➢ Develop ICT based solutions for the development of the nation.

PROGRAMME EDUCATIONAL OBJECTIVES (PEOs)

1. PEO1: Graduates will be able to comprehend mathematics, science, engineering fundamentals,

laboratory and work-based experiences to formulate and solve problems in Computer Science and

Engineering and other related domains and will develop proficiency in computer based engineering and

the use of computation tools.

2. PEO2: Graduates will be prepared to communicate and work effectively on the multidisciplinary

engineering projects practicing the ethics of their profession with a sense of social responsibility.

3. PEO3: Graduates will recognize the importance of lifelong learning to become experts either as

entrepreneurs or employees and to widen their knowledge in their domain.


PROGRAM OUTCOMES (POs)
● PO1: Engineering knowledge: Apply the knowledge of mathematics, science, engineering
fundamentals, and an engineering specialization to the solution of complex engineering problems.
● PO2: Problem analysis: Identify, formulate, review research literature, and analyze complex
engineering problems reaching substantiated conclusions using first principles of mathematics,
natural sciences, and engineering sciences.
● PO3: Design/development of solutions: Design solutions for complex engineering problems
and design system components or processes that meet the specified needs with appropriate
consideration for the public health and safety, and the cultural, societal, and environmental
considerations.
● PO4: Conduct investigations of complex problems: Use research-based knowledge and
research methods including design of experiments, analysis and interpretation of data, and
synthesis of the information to provide valid conclusions.
● PO5: Modern tool usage: Create, select, and apply appropriate techniques, resources, and
modern engineering and IT tools including prediction and modeling to complex engineering
activities with an understanding of the limitations.
● PO6: The engineer and society: Apply reasoning informed by the contextual knowledge to
assess societal, health, safety, legal and cultural issues and the consequent responsibilities
relevant to the professional engineering practice.
● PO7: Environment and sustainability: Understand the impact of the professional engineering
solutions in societal and environmental contexts, and demonstrate the knowledge of, and need for
sustainable development.
● PO8: Ethics: Apply ethical principles and commit to professional ethics and responsibilities and
norms of the engineering practice.
● PO9: Individual and team work: Function effectively as an individual, and as a member or
leader in diverse teams, and in multidisciplinary settings.
● PO10: Communication: Communicate effectively on complex engineering activities with the
engineering community and with society at large, such as, being able to comprehend and write
effective reports and design documentation, make effective presentations, and give and receive
clear instructions.
● PO11: Project management and finance: Demonstrate knowledge and understanding of the
engineering and management principles and apply these to one’s own work, as a member and
leader in a team, to manage projects and in multidisciplinary environments.
● PO12: Life-long learning: Recognize the need for, and have the preparation and ability to
engage in independent and life-long learning in the broadest context of technological change.
PROGRAM SPECIFIC OUTCOMES (PSOs)

After successful completion of the program, graduates of B.E (CSE) will:

PSO-1 Analyze, design, implement, test and evaluate computer programs in the areas related to
algorithms, networking, web design, cloud computing, IoT and data analytics of varying
complexity.

PSO-2 Develop innovative ideas to provide solutions for complex problems and apply advanced
knowledge of computer science domain to identify research challenges in Computer Science and
Engineering.
INDEX

Sl. Date Name of Experiment Page Marks Signature


No No. of the
faculty

10
21PD19-PRINCIPLES OF COMPILER DESIGN

Ex.No: 01
IMPLEMENTATION OF LEXICAL ANALYZER IN C
Date:

AIM:

To write a C program to implement a lexical analyzer.

Algorithm:

Step 1 Start the program.

Step 2: Input the string from the file.

Step 3:Check if the first character of the string is an alphabet.

a) If yes, then extract the string of alphabets in an array

b) elsego to step 4

Step 4:Compare the array with the predefined set of keywords. if the characters are

alphabets and

check for a match. a) If a match is found, then print "keyword"

b) else print "Identifier"

Step 5: If the character is not an alphabet compare it with the set of operator and

check for a match.

a) If yes, print the operator

b) else print "error".

Step 6:Stop the program

Program:

#include<stdio.h>

#include<conio.h>

#include<ctype.h>

#include<string.h>

void main()

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

FILE *fp;

int i,j;

char arr[100],k;

char kw[10][10]={"int","float","double","end","main","void","include","printf","scanf"};

char hf[2][10]={"stdio.h","conio.h"};

char op[5]={'+','-','*','/','%'};

char punc[6]={'(',')','{','}',','};

clrscr();

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

printf("InputProgram\n");

while(!feof(fp))

arr[0]=fgetc(fp);

printf("%c",arr[0]);

fclose(fp);

printf("\nSymboltable\n");

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

printf("\nKeywords");

while(!feof(fp))

arr[0]=fgetc(fp);

fscanf(fp,"%s",arr);

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

if(strcmp(arr,kw[i])==0)

printf("\t%s",arr);

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

}}}

fclose(fp);

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

printf("\nHeaderfiles");

while(!feof(fp))

arr[0]=fgetc(fp);

fscanf(fp,"%s",arr);

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

if(strcmp(arr,hf[i])==0)

printf("\t%s",arr);

}}}

fclose(fp);

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

printf("\nOperators");

while(!feof(fp))

arr[0]=fgetc(fp);

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

if(arr[0]==op[i])

printf("\t%c",arr[0]);

}}}

fclose(fp);

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

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

printf("\npunctuation");

while(!feof(fp))

arr[0]=fgetc(fp);

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

if(arr[0]==punc[i])

printf("\t%c",arr[0]);}}}

fclose(fp);

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

printf("\nConstants");

while(!feof(fp))

arr[0]=fgetc(fp);

if(isdigit(arr[0]))

printf(" %c ",arr[0]);}}

fclose(fp);

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

printf("\nidentifier ");

while(!feof(fp))

fscanf(fp,"%s",arr);

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

if(strcmp(arr,kw[i])==0)

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

fscanf(fp,"%s",arr);

j=0;

while(j<strlen(arr) && arr[j]!=';')

printf("%c",arr[j]);

j++;

}}}}

fclose(fp);

getch();

Input:

#include<stdio.h>

#include<conio.h>

void main()

int a,b,c;

a=10;

b=5;

c=a+b;

printf(“Thesumis %d”,c);

getch();

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

Output:

RESULT:
Thus,the program for developing a lexical analyzer to recognize a few
patterns in C has been executed successfully.

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

Ex.No:02
IMPLEMENTATION OF LEXICAL ANALYSER USING LEX TOOL
Date:

Aim:

To write a C program for implementing the lexical analyzer using LEX Tool.

Algorithm:

Step 1: Start the Program.

Step 2: Create a Lex Specification file using the Echo,YYLEX, YYTEXT, YYWRAPAP, YYIN.

Step 3: The Echo() function is used to emit the input as it is.

Step 4: The YYLEX() function encounters scanning the source program.

Step 5: The YYTEXT() function is used to store the Null Terminated string.

Step 6: The YYWRAP() function returns zero when the scanner continues scanning and returns 1
when the end of file is encountered.

Step 7: The YYIN() function is used to store the input source program.

Step 8: The main function first calls the yylex and yywrap() function and executes.

Step 9: Print the Pre-processor Directive, Keyword, function as in the source program.

Step10: Stop the Program

Program:

//Implementation of Lexical Analyzer using Lex tool

%{

int COMMENT=0;

%}

identifier [a-zA-Z][a-zA-Z0-9]*

%%

#.* {printf("\n%s is a preprocessor directive",yytext);}

int |

float |

char |

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

double |

while |

for |

struct |

typedef |

do |

if |

break|

continue |

void |

switch |

return |

else |

goto {printf("\n\t%s is a keyword",yytext);}

"/*" {COMMENT=1;}{printf("\n\t %s is a COMMENT",yytext);}

{identifier}\( {if(!COMMENT)printf("\nFUNCTION \n\t%s",yytext);}

\{ {if(!COMMENT)printf("\n BLOCK BEGINS");}

\} {if(!COMMENT)printf("BLOCK ENDS ");}

{identifier}(\[[0-9]*\])? {if(!COMMENT) printf("\n %s IDENTIFIER",yytext);}

\".*\" {if(!COMMENT)printf("\n\t %s is a STRING",yytext);}

[0-9]+ {if(!COMMENT) printf("\n %s is a NUMBER ",yytext);}

\)(\:)? {if(!COMMENT)printf("\n\t");ECHO;printf("\n");}

\( ECHO;

= {if(!COMMENT)printf("\n\t %s is an ASSIGNMENT OPERATOR",yytext);}

\<= |

\>= |

\< |

== |

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

\> {if(!COMMENT) printf("\n\t%s is a RELATIONAL OPERATOR",yytext);}

%%

int main(int argc, char **argv)

FILE *file;

file=fopen("var.c","r");

if(!file)

printf("couldnot open the file");

exit(0);

yyin=file;

yylex();

printf("\n");

return(0);

int yywrap()

return(1);

Input:

//var.c

#include<stdio.h>

#include<conio.h>

void main()

int a,b,c;

a=1;

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

b=2;

c=a+b;

printf("Sum:%d",c);

Output

RESULT:
Thus, the program for Implementation of a lexical analyzer using lex tool has been
executed successfully.

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

Ex.No:03 IMPLEMENTATION OFTHE RECURSIVE DECENT PARSER FOR AN


EXPRESSION GRAMMER THAT GENERATES ARITHMETIC EXPRESSIONS
Date: WITH DIGITS,+ AND *

Aim:

To write a C program to implement a recursive descent parser for an expression grammar that
generates arithmetic expression with digits + and *.

Algorithm:

Step 1: Start the program and get the input expression.

Step 2: Construct the parser tree virtuallyfor thefollowing grammar:

E->TE‟

E‟->+TE‟|€

T->FT‟

T‟->*FT‟ |€

F->I | (E)

Where each non-terminal has a defined function corresponding it.

Step 3: Call the function corresponding to the start symbol.

Step 4: For each non-terminal on the LHS of the production do,

a) If the RHS has a non-terminal, then call the function corresponding to it.

b) If the RHS has a terminal, then check if it matches with the input, else print error.

Step 5: Repeat the previous step until the given input string is completely parsed or an error is

encountered.

Step 6: Stoptheprogram.

Program:

#include<stdio.h>

#include<conio.h>

#include<string.h>

char input[100];

int i,l;

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

void main()

clrscr();

printf("\nRecursive descent parsing for the following grammar\n");

printf("\nE->TE'\nE'->+TE'/@\nT->FT'\nT'->*FT'/@\nF->(E)/ID\n");

printf("\nEnter the string to be checked:");

gets(input);

if(E())

if(input[i+1]=='\0')

printf("\nString is accepted");

else

printf("\nString is not accepted");

else

printf("\nString not accepted");

getch()

E()

{ if(T())

{ if(EP()

return(1);

else

return(0);

else

return(0);

EP()

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

if(input[i]=='+')

{ i+

+;

if(T())

{ if(EP()

return(1);

else

return(0);

else

return(0);

Else

return(1);

T()

{ if(F())

{ if(TP()

return(1);

else

return(0);

else

return(0);

TP()

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

if(input[i]=='*')

{ i+

+;

if(F())

{ if(TP()

return(1);

else

return(0);

else

return(0);

else

return(1);

F()

if(input[i]=='(')

{ i+

+;

if(E())

if(input[i]==')')

{ i+

+;

return(1);

else

return(0);

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

else
return(0);
}

else if(input[i]>='a'&&input[i]<='z'||input[i]>='A'&&input[i]<='Z')

{ i+
+;
return(1);

else
return(0);
}

Output:

RESULT:
Thus, the decent parser for an expression grammer for arithmetic expression with digits has
been executed successfully.

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

Ex.No:04
IMPLEMENTATION OF A PARSER FOR THE SAME GRAMMAR AS USING
Date: YACC AND LEX

Aim:

To write a LEX and YACC program to implement parser.

Algorithm:
Step 1: In parser.l give the LEX specification.

a) In the declaration section given the regular expression for an identifier and number.

b) Identify the tokens as keywords or variables or numbers or data types or relational operators and
return them to y.tab.h.
c) Skip the white spaces.

d) Increment the line number for every new line.

Step 2: In parser.y give the syntax specification.

a) Define tokens as specified in sample.l and the arithmetic operators as left associative.

b) Specify the productions i.e. the syntax for a program block, code, statement, condition. For example,
the syntax for program is PROGRAM: MAIN BLOCK; which means the program starts with main,
followed by a block.
c) Give the auxiliary code and initialize the parsing using yyparse().

d) Keep track of the error number to check if the program is error free or not. If error =0 then the
program is error free else it has errors.
Print the line number having the error and error no. is incremented for every error using yyerror().

Program:

%{
/* Definition section */
#include "y.tab.h"
%}
/* Rule Section */
%
[aA] {return A;}
[bB] {return B;}
\n {return NL;}
. {return yytext[0];}
%%
int yywrap()
{
return 1;
}

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

Parser Source Code :

%{
/* Definition section */
#include<stdio.h>
#include<stdlib.h>
%}
%token A B NL
/* Rule Section */
%%
stmt: S NL { printf("valid string\n");
exit(0); }
;
S: A S B |
;
%%
int yyerror(char *msg)
{
printf("invalid string\n");
exit(0);
}

//driver code

main()
{
printf("enter the string\n");
yyparse();
}

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

OUTPUT:

RESULT:
Thus the program for developing a Implementation of a parser for the same grammar in
yaac and lex has been executed successfully.

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

Ex.No:05 WRITE SEMANTIC RULES TO THE YACC PROGRAM AND IMPLEMENT A


CALCULATOR THAT TAKES AN EXPRESSION WITH DIGITS, + AND *
Date:

Aim:
To write a Yacc program for performing calculator functions like addition and multiplication.

Algorithm:

Step 1: In the declaration section, include the header files stdio.h and ctype.h.

Step 2: Define the tokens.

Step 3: Define the precedence and left associatively of the operators.

Step 4: In the rule section, give the productions for program, statement, expr.For example, expr may
be INTEGER, VARIABLE, EXPR ‟+ ”EXPR, EXPR ‟-” EXPR, EXPR ‟*” EXPR ‟/”
EXPR, (“EXPR‟).

Step 5: The evaluated value of the arithmetic expression is then stored in $$.

Program:

%{
/* Definition section */
#include<stdio.h>
#include "y.tab.h"
extern int yylval;
%}

/* Rule Section */
%%
[0-9]+ {
yylval=atoi(yytext);
return NUMBER;

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

[\t] ;
[\n] return 0;
. return yytext[0];

%%
int yywrap()
{
return 1;
}
Parser Source Code :

%{
/* Definition section */
#include<stdio.h>
int flag=0;
%}

%token NUMBER

%left '+' '-'

%left '*' '/' '%'

%left '(' ')'

/* Rule Section */
%%
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;}
;
%%

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

//driver code

void main()
{
printf("\nEnter Any Arithmetic Expression which
can have operations Addition,
Subtraction, Multiplication, Division,
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:

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

RESULT:

Thus the program for developing a semantic rules to the YAAC program and implement a
calculator that takes an expression with digits + and * has been executed successfully.

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

IMPLEMENTATION OF THE FRONT END OF A COMPILER THAT GENERATES


Ex.No:06 THE THREE ADDRESS CODE FOR A SIMPLE LANGUAGE WITH: ONE DATA
TYPE INTEGER, ARITHMETIC OPERATORS.
Date:

Aim:

To write a C program to implement the front end of a compiler that generates the three
addresses code for a simple language with one data type integer, arithmetic operators.

Algorithm:

Step 1: Start the program.

Step 2: Input the expression.

Step 3: Checks the expression for its validation.

Step 4: If it is invalid, return the error message, otherwise, for each computation
store the result in the three address statement. (store it in temporary variable
say t1,t2,t3 ,etc.,).

Step 5: Assign the final temporaryvalue to the variable in which the result has to be stored.

Step 6: Stop the Program.

PROGRAM:

#include <stdio.h>

#include <stdlib.h>

#include <ctype.h>

#define MAX_EXPR_LENGTH 100


typedef enum {

INTEGER,

PLUS,

MINUS,

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

MULTIPLY,

DIVIDE,

END

} TokenType;

typedef struct {

TokenType type;

int value;

} Token;

Token nextToken(char *expr, int *index)

{ Token token;

while (isspace(expr[*index])) (*index)++;

if (isdigit(expr[*index])) {

token.type = INTEGER;

token.value = atoi(&expr[*index]);

while (isdigit(expr[*index])) (*index)++;

} else {

switch (expr[(*index)++])

{ case '+':

token.type = PLUS;

break;

case '-':

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

token.type = MINUS;

break;

case '*':

token.type = MULTIPLY;

break;

case '/':

token.type = DIVIDE;

break;

case '\0':

token.type =END;

break;

default:

printf("Invalid character found in expression.\n");

exit(1);

return token;

void generateThreeAddressCode(char *expr)

{ int index = 0;

Token token;

token = nextToken(expr, &index);

while (token.type != END) {

switch (token.type)

{ case INTEGER:

printf("LOAD %d\n", token.value);

break;

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

case PLUS:

printf("ADD\n");

break;

case MINUS:

printf("SUBTRACT\n");

break;

case MULTIPLY:

printf("MULTIPLY\n");

break;

case DIVIDE:

printf("DIVIDE\n");

break;

default:

break;

token = nextToken(expr, &index);

int main() {

char expression[MAX_EXPR_LENGTH];

printf("Enter an arithmetic expression: ");

fgets(expression, MAX_EXPR_LENGTH, stdin);

generateThreeAddressCode(expression);

return 0;

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

OUTPUT:

RESULT:
Thus the program for developing arithmetic operators that generate three address
code for simple language in C has been executed successfully.

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

IMPLEMENTATION OF THE FRONT END OF A COMPILER THAT GENERATES


Ex.No:7 THE THREE ADDRESS CODE FOR A SIMPLE LANGUAGE WITH: RELATIONAL
OPERATORS, VARIABLE DECLARATION STATEMENT
Date:

Aim:
To write a C program to implement the front end of a compiler that generates the three
addresses code for a simple language with relational operators, variable declaration statement.

Algorithm:

Step1: Start the program.

Step2:Define structures for tokens, symbol table entries, and Three Address Code (TAC).

Step3:Implement lexical analysis to tokenize the input source code.


Step4:Implement a symbol table to store variable information.

Step5:Implement parsing logic to handle variabledeclaration statements and expressions


with relational operators.

Step6:Generate Three Address Code (TAC) for each expression encountered during
parsing.

Step7: Stop the program.

Program:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

#define MAX_CODE_LENGTH 1000

#define MAX_TOKEN_LENGTH 100

// Token types

#define IDENTIFIER 1

#define KEYWORD 2

#define OPERATOR 3

#define LITERAL 4

// Structure to represent a token

typedef struct {

int type; // Type of the token

char lexeme[MAX_TOKEN_LENGTH]; // Lexeme value

} Token;

// Function prototypes

Token* lexicalAnalysis(const char* input);

void syntaxAnalysis(Token* tokens);

void generateThreeAddressCode(Token* tokens);

int main() {

charinput[MAX_CODE_LENGTH];

printf("Enter code: ");

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

fgets(input, sizeof(input), stdin);

// Perform lexical analysis

Token* tokens = lexicalAnalysis(input);

// Perform syntax analysisand generate three-address code

syntaxAnalysis(tokens);

// Free dynamically allocated memory

free(tokens);

return 0;

Token* lexicalAnalysis(const char* input) {

Token* tokens = malloc(sizeof(Token) * MAX_CODE_LENGTH / 2); //


Assuming roughly half of input length for tokens

char* token;

charcopy[MAX_CODE_LENGTH];

strcpy(copy, input);

token = strtok(copy, " \t\n;"); // Tokenize based on whitespace and semicolon

int tokenCount = 0;

while (token != NULL) {

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

// Determinetoken type

int tokenType;

if (strcmp(token, "int") == 0)

{ tokenType = KEYWORD;

} else if (strcmp(token, "=") == 0 || strcmp(token, "==") == 0 || strcmp(token, "!=")


== 0 || strcmp(token, "<") == 0 || strcmp(token, ">") == 0) {

tokenType = OPERATOR;

} else if (token[0] >= '0' && token[0] <= '9')

{ tokenType = LITERAL;

} else {

tokenType = IDENTIFIER;

// Store token

tokens[tokenCount].type =tokenType;

strcpy(tokens[tokenCount].lexeme, token);

token = strtok(NULL, " \t\n;");

tokenCount++;

// Add an end marker

tokens[tokenCount].type = 0;

strcpy(tokens[tokenCount].lexeme, "");

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

return tokens;

void syntaxAnalysis(Token* tokens) {

// Dummysyntax analysis fordemonstration purposes

printf("Syntax Analysis:\n");

int i = 0;

while (tokens[i].type != 0) {

if (tokens[i].type == KEYWORD && strcmp(tokens[i].lexeme, "int") == 0)

{ printf("Found variable declaration for %s\n", tokens[i + 1].lexeme);

i++;

} else if (tokens[i].type == OPERATOR)

{ printf("Found operator: %s\n", tokens[i].lexeme);

i++;

printf("\n");

// Generate three-address code

generateThreeAddressCode(tokens);

void generateThreeAddressCode(Token* tokens) {

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

// Dummythree-address code generation for demonstration purposes

printf("Three-Address Code:\n");

int i = 0;

while (tokens[i].type != 0) {

if (tokens[i].type == KEYWORD && strcmp(tokens[i].lexeme, "int") == 0)

{ printf("t1 = 0\n"); // Assign initial value

printf("%s = t1\n", tokens[i +1].lexeme);

i++;

} else if (tokens[i].type == OPERATOR) {

printf("t2 = %s %s %s\n", tokens[i - 1].lexeme, tokens[i].lexeme, tokens[i +


1].lexeme);

i += 2;

i++;

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

OUTPUT:

RESULT:
Thus,the program for developing relational operators and variable declaration
statement that generate three address code for simple language in C has been executed
successfully.

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

IMPLEMENTATION OF THE FRONT END OF A COMPILER THAT GENERATES


Ex.No:8 THE THREE ADDRESS CODE FOR A SIMPLE LANGUAGE WITH:ONE
CONDITIONAL CONSTRUCT,ONE ITERATIVE CONSTRUCT AND ASSIGNMENT
STATEMENT
Date:

Aim:
To write a C program to implement the front end of a compiler that generates the three
addresses code for a simple language with one conditional construct,one iterative construct
statement.

Algorithm:

Step1: Start the program.

Step2: Lexical Analysis: Tokenize the input code to identify tokens such as identifiers,
keywords, operators, and literals.

Step3:Syntax Analysis: Implement a parser to ensure that the input code adheres to the
syntax rules of the simple language. This involves constructing a grammar for the language
and writing code to parse the input according to that grammar.

Step4:Symbol Table Management: Maintain a symbol table to keep track of declared


variables and their types.

Step5:Three-Address Code Generation: Translate parsed code into three-address


code instructions. For each valid statement, generate the appropriate three-
address code representation.

Step6: Stop the program.

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

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

// Structure to represent a token


typedef struct {

int type; // Type of the token

char lexeme[100]; // Lexeme value


} Token;

// Token types

#define IDENTIFIER 1
#define KEYWORD 2
#define OPERATOR 3

#define LITERAL 4

// Function to perform lexical analysis and return tokens


Token* lexicalAnalysis(char* input) {
// Dummyimplementation, should be replaced with a proper lexer

Token* tokens = malloc(sizeof(Token) * 100);


// Tokenize the input code
// For simplicity, let's assume the input is: "if (x > 5) { x = x - 1; } else { x = x + 1; }"
strcpy(tokens[0].lexeme, "if");
tokens[0].type = KEYWORD;
strcpy(tokens[1].lexeme, "(");
tokens[1].type = OPERATOR;
strcpy(tokens[2].lexeme, "x");
tokens[2].type = IDENTIFIER;
strcpy(tokens[3].lexeme, ">");
tokens[3].type = OPERATOR;
strcpy(tokens[4].lexeme, "5");
tokens[4].type = LITERAL;

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

strcpy(tokens[5].lexeme, ")");
tokens[5].type = OPERATOR;
strcpy(tokens[6].lexeme, "{");
tokens[6].type = OPERATOR;
strcpy(tokens[7].lexeme, "x");
tokens[7].type = IDENTIFIER;
strcpy(tokens[8].lexeme, "=");
tokens[8].type = OPERATOR;
strcpy(tokens[9].lexeme, "x");
tokens[9].type = IDENTIFIER;
strcpy(tokens[10].lexeme, "-");
tokens[10].type = OPERATOR;
strcpy(tokens[11].lexeme, "1");
tokens[11].type = LITERAL;
strcpy(tokens[12].lexeme, ";");
tokens[12].type = OPERATOR;
strcpy(tokens[13].lexeme, "}");
tokens[13].type = OPERATOR;
strcpy(tokens[14].lexeme,"else");
tokens[14].type = KEYWORD;
strcpy(tokens[15].lexeme, "{");
tokens[15].type = OPERATOR;
strcpy(tokens[16].lexeme, "x");
tokens[16].type = IDENTIFIER;
strcpy(tokens[17].lexeme, "=");
tokens[17].type = OPERATOR;
strcpy(tokens[18].lexeme, "x");
tokens[18].type = IDENTIFIER;
strcpy(tokens[19].lexeme, "+");

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

tokens[19].type = OPERATOR;
strcpy(tokens[20].lexeme, "1");
tokens[20].type = LITERAL;
strcpy(tokens[21].lexeme, ";");
tokens[21].type = OPERATOR;
strcpy(tokens[22].lexeme, "}");
tokens[22].type = OPERATOR;
return tokens;
}

// Function to perform syntax analysis and generate three-address code


void syntaxAnalysis(Token* tokens) {

// Dummy implementation, should be replaced with a proper parser


printf("Three-address code:\n");
printf("t1 = x > 5\n");
printf("ift1 goto L1\n");
printf("x = x - 1\n");
printf("goto L2\n");
printf("L1:\n");
printf("x = x + 1\n");
printf("L2:\n");
}

int main() {

char input[100];
printf("Enter code: ");
fgets(input, sizeof(input), stdin);

// Perform lexical analysis

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

Token* tokens = lexicalAnalysis(input);

// Perform syntax analysisand generate three-address code


syntaxAnalysis(tokens);

free(tokens);
return 0;
}

OUTPUT:

RESULT:
Thus the program for developing conditional construct,one iterative construct and
assignment statement that generate three address code for simple language in C has
been executed successfully.

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

Ex. No:9
IMPLEMENTATION OF A BACK END COMPILER USING C

Date:

Aim:

To write a c program to implement the back end of a compiler (code generator) for
the three address code.

Algorithm:

Step1: Start the program.

Step2: Get the three address code from user.

Step3: Check the length of the given input.

Step4: If the given length is greater than 5,then return the error message as invalid
expression.

Step5: Else, check the operator(+,-,*,/)and print the corresponding block of


mnemonic code of the operator.

Step6: Stop 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];

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

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

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

printf("\n\tMov R%d,%c", i, str[0]);

} while (strcmp(icode[++i], "exit") != 0);

getch();

OUTPUT:

RESULT:
Thus the program for developing back end of a compiler (code generator) that
generate three address code for simple language in C has been executed successfully.

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

Ex. No:10
STACK IMPLEMENTATION OF LR PARSER USING C
Date:

Aim:

To write a C program to perform stack implementation of LR parser.

Algorithm:

Step1: Get the input expression and store it in the input buffer.

Step 2: Read the data from the input buffer one at the time and convert into corresponding
Non Terminal using production rules available.

Step 3: Perform push & pop operation for LR parsing table construction.

Step 4: Display the result with conversion of corresponding input symbols to production
and production reduction to start symbol. No operation performed on the operator.

Program:

#include<stdio.h >

#include<stdio.h >

#include<conio.h>

#include <string.h >

char stack[30];

int top=-1;

void push(char c)

top++;

stack[top]=c;

char pop()

char c;

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

if(top!=-1)

c=stack[top];

top--;

return c;

return'x';

void printstat()

int i;

printf("\n\t\t\t $");

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

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

void main()

int i,j,k,l;

chars1[20],s2[20],ch1,ch2,ch3;

printf("\n\n\t\t LR PARSING");

printf("\n\t\t ENTER THE EXPRESSION \n\t\t");

scanf("%s",s1);

l=strlen(s1);

j=0;

printf("\n\t\t $");

for(i=0;i<sizeof(s1);i++)

if(s1[i]=='i' && s1[i+1]=='d')

s1[i]=' ';

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

s1[i+1]='E';

printstat(); printf("id");

push('E');

printstat();

else if(s1[i]=='+'||s1[i]=='-'||s1[i]=='*' ||s1[i]=='/' ||s1[i]=='d')

push(s1[i]);

printstat();

printstat();

l=strlen(s2);

while(l)

ch1=pop();

if(ch1=='x')

printf("\n\t\t\t $");

break;

if(ch1=='+'||ch1=='/'||ch1=='*'||ch1=='-')

ch3=pop();

if(ch3!='E')

printf("errror");

else

717822P160
21PD19-PRINCIPLES OF COMPILER DESIGN

push('E');

printstat();

ch2=ch1;

getch();

OUTPUT:

RESULT:
Thus the program for developing stack implementation of LR parser that
generate three address code for simple language in C has been executed
successfully.

717822P160

You might also like