You are on page 1of 18

KANPUR INSTITUTE OF TECHNOLOGY

Compiler Design Lab


(KCS 552)
Submitted by:
Anivesh Pathak
Roll No:
2101650100022

B.TECH
CSE IIIrd year

Session 2023-24

Submitted to:
Mrs. Aparna Sharma
(Assistant Professor)
Department of Computer Science & Engineering

Vision and Mission of the Department


Vision
Computer Science Department at Kanpur Institute of Technology is
committed to empower its students with relevant and current technology so
that they are prepared to compute in this globalised technical world along
with being aware of their ethical responsibilities towards the world at large.

Mission
M1: To impart high quality education in the science of computing.
M2: To prepare educated and skilled computer professionals.
M3: To create excellence by providing comprehensive knowledge of the
latest tools and technologies in the domain of computer science, so that
students strive to become leaders.
M4: To inculcate ethical values in students so that they understand their
responsibility towards the nation with focus on upliftment of all sections of
society.
M5: To facilitate establishment of research centers and encourage students
to solve complex technological problems.
Program Educational Objectives
PEO1: Make valuable contributions to design, development and
production in the practice of computer science and engineering in related
engineering areas or application areas, and at the interface of computers
and physical systems.

PEO2: Promotes design, research and implementation of products through


strong communication skills, leadership and entrepreneurial skills.

PEO3: Engage in professional development or post-graduate education to


pursue flexible career paths amid future technological changes.

PEO4: Apply basic principles and practices of computing and science to


successfully complete software related projects to meet customer business
objectives and/or productively engage in research.

PEO5: To develop analytical, mathematical and scientific knowledge that


is used to analyze, formulate and solve any engineering problems.

Program specific outcomes (PSO’s):


PSO1: Ability to understand the mathematical methodology to cracks
problems using suitable data structure and mathematical approach.

PSO2: Ability to design and develop software for web based and mobiles
androids under real world environment.

PSO3: Ability to design the algorithm for machine learning, data


compression and IOT based application and also the successful career and
entrepreneurship.
INDEX

S. Name of Experiment Page Date Signatur


No No. e

1. WRITE A PROGRAM TO CONSTRUCT DFA


ACCEPTING THE LANGUAGE END WITH ‘01’

2. DESIGN A LEXICAL ANALYZER FOR GIVEN


LANGUAGE & LEXICAL ANALYZER
SHOULD IGNORE REDUNDANT SPACE, TABS
& NEW LINES.(identify tokens)
3. WRITE A PROGRAM TO FIND SIMULATE FIRST
AND FOLLOW OF ANY GRAMMER

4. CONSTRUCT A RECURSIVE DECENT PARSER


FOR AN EXPRESSION

5. CONSTRUCT SHIFT REDUCE PARSER FOR A


GIVEN LANGUAGE

6. IMPLEMENT INTERMEDIATE CODE


GENERATION OF A SIMPLE EXPRESSION
(W:a*b+c/d-e/f+g*h)

7.

8.

9
1.WRITE A PROGRAM TO CONSTRUCT DFA ACCEPTING THE
LANGUAGE END WITH ‘01’
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
int transition(int state, char symbol) {
switch(state) {
case 0:
if(symbol == '0')
return 0;
else if(symbol == '1')
return 1;
break;
case 1:
if(symbol == '0')
return 2;
else if(symbol == '1')
return 1;
break;
case 2:
if(symbol == '0')
return 0;
else if(symbol == '1')
return 1;
break;
}
return -1;
}

bool isAccepted(char *input) {


int state = 0;
int len = strlen(input);

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


state = transition(state, input[i]);
}

return state == 2;
}

int main() {
char input[100];

printf("Enter a string: ");


scanf("%s", input);
if(isAccepted(input))
printf("Accepted\n");
else
printf("Not accepted\n");

return 0;
}
2.DESIGN A LEXICAL ANALYZER FOR GIVEN LANGUAGE &
LEXICAL ANALYZER SHOULD IGNORE REDUNDANT SPACE,
TABS & NEW LINES.(identify tokens)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#include <string.h>
typedef enum {
IDENTIFIER,
INTEGER,
OPERATOR,
KEYWORD,
DELIMITER,
ERROR,
END
} TokenType;
bool isDelimiter(char ch) {
char delimiters[] = " \t\n(),;{}[]";
for(int i = 0; delimiters[i] != '\0'; i++) {
if(ch == delimiters[i])
return true;
}
return false;
}
bool isOperator(char ch) {
char operators[] = "+-*/%=&|<>!";
for(int i = 0; operators[i] != '\0'; i++) {
if(ch == operators[i])
return true;
}
return false;
}
bool isKeyword(char *str) {
char keywords[][10] = {"if", "else", "while", "for", "int", "float", "char", "return"};
for(int i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {
if(strcmp(str, keywords[i]) == 0)
return true;
}
return false;
}
TokenType getToken(char *lexeme) {
if(isalpha(lexeme[0]) || lexeme[0] == '_') {
if(isKeyword(lexeme))
return KEYWORD;
else
return IDENTIFIER;
} else if(isdigit(lexeme[0])) {
for(int i = 1; lexeme[i] != '\0'; i++) {
if(!isdigit(lexeme[i]))
return ERROR; // Invalid token
}
return INTEGER;
} else if(isOperator(lexeme[0])) {
return OPERATOR;
} else if(isDelimiter(lexeme[0])) {
return DELIMITER;
} else {
return ERROR; // Invalid token
}
}

int main() {
char input[1000];
printf("Enter the input code (press Ctrl+D to end):\n");
while (fgets(input, sizeof(input), stdin)) {
char *token = strtok(input, " \t\n");
while(token != NULL) {
TokenType type = getToken(token);
if(type != ERROR)
printf("Token: %s, Type: %d\n", token, type);
token = strtok(NULL, " \t\n");
}
}
printf("End of input.\n");
return 0;
}
3.WRITE A PROGRAM TO FIND SIMULATE FIRST AND
FOLLOW OF ANY GRAMMER
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define MAX_PROD 10
#define MAX_LEN 10

char grammar[MAX_PROD][MAX_LEN];
int nProd;
char first[26][MAX_LEN];
char follow[26][MAX_LEN];
bool nullable[26];

bool isNonTerminal(char symbol) {


return symbol >= 'A' && symbol <= 'Z';
}

bool isTerminal(char symbol) {


return symbol >= 'a' && symbol <= 'z';
}

int findIndex(char symbol) {


return symbol - 'A';
}

void addChar(char *str, char ch) {


int len = strlen(str);
str[len] = ch;
str[len + 1] = '\0';
}

void computeFirst(char nonTerminal) {


int idx = findIndex(nonTerminal);
if(isTerminal(nonTerminal)) {
addChar(first[idx], nonTerminal);
return;
}
for(int i = 0; i < nProd; i++) {
if(grammar[i][0] == nonTerminal) {
if(isTerminal(grammar[i][2])) {
addChar(first[idx], grammar[i][2]);
} else {
computeFirst(grammar[i][2]);
int j = 0;
while(first[findIndex(grammar[i][2])][j] != '\0') {
addChar(first[idx], first[findIndex(grammar[i][2])][j]);
j++;
}
}
}
}
}

void computeFollow(char nonTerminal) {


int idx = findIndex(nonTerminal);
if(nonTerminal == grammar[0][0])
addChar(follow[idx], '$');
for(int i = 0; i < nProd; i++) {
for(int j = 2; j < strlen(grammar[i]); j++) {
if(grammar[i][j] == nonTerminal) {
if(j == strlen(grammar[i]) - 1) {
if(grammar[i][0] != nonTerminal) {
computeFollow(grammar[i][0]);
int k = 0;
while(follow[findIndex(grammar[i][0])][k] != '\0') {
addChar(follow[idx], follow[findIndex(grammar[i][0])][k]);
k++;
}
}
} else {
if(isTerminal(grammar[i][j+1])) {
addChar(follow[idx], grammar[i][j+1]);
} else {
int k = 0;
while(first[findIndex(grammar[i][j+1])][k] != '\0' &&
first[findIndex(grammar[i][j+1])][k] != '#') {
addChar(follow[idx], first[findIndex(grammar[i][j+1])][k]);
k++;
}
if(first[findIndex(grammar[i][j+1])][k] == '#' && grammar[i][0] != nonTerminal) {
computeFollow(grammar[i][0]);
k = 0;
while(follow[findIndex(grammar[i][0])][k] != '\0') {
addChar(follow[idx], follow[findIndex(grammar[i][0])][k]);
k++;
}
}
}
}
}
}
}
}

int main() {
printf("Enter the number of productions: ");
scanf("%d", &nProd);
printf("Enter the productions:\n");
for(int i = 0; i < nProd; i++) {
scanf("%s", grammar[i]);
}

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


first[i][0] = '\0';
follow[i][0] = '\0';
nullable[i] = false;
}

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


computeFirst(grammar[i][0]);
}

bool changes = true;


while(changes) {
changes = false;
for(int i = 0; i < nProd; i++) {
int idx = findIndex(grammar[i][0]);
if(isTerminal(grammar[i][2])) {
if(grammar[i][2] == '#') {
nullable[idx] = true;
changes = true;
}
} else {
int j = 2;
bool null = true;
while(grammar[i][j] != '\0') {
if(!nullable[findIndex(grammar[i][j])]) {
null = false;
break;
}
j++;
}
if(null && !nullable[idx]) {
nullable[idx] = true;
changes = true;
}
}
}
}

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


computeFollow(grammar[i][0]);
}

printf("\nFIRST sets:\n");
for(int i = 0; i < 26; i++) {
if(first[i][0] != '\0') {
printf("%c: %s\n", i + 'A', first[i]);
}
}
printf("\nFOLLOW sets:\n");
for(int i = 0; i < 26; i++) {
if(follow[i][0] != '\0') {
printf("%c: %s\n", i + 'A', follow[i]);
}
}

return 0;
}
4.CONSTRUCT A RECURSIVE DECENT PARSER FOR AN
EXPRESSION
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>

bool term(char *);


bool factor(char *);

void consumeWhitespace(char **input) {


while (**input == ' ') {
(*input)++;
}
}

bool factor(char *input) {


consumeWhitespace(&input);
if (isdigit(*input)) {
input++;
return true;
} else if (*input == '(') {
input++;
if (!expression(input)) {
return false;
}
if (*input == ')') {
input++;
return true;
}
return false;
}
return false;
}

bool term(char *input) {


if (!factor(input)) {
return false;
}
consumeWhitespace(&input);
while (*input == '*' || *input == '/') {
input++;
if (!factor(input)) {
return false;
}
consumeWhitespace(&input);
}
return true;
}

bool expression(char *input) {


if (!term(input)) {
return false;
}
consumeWhitespace(&input);
while (*input == '+' || *input == '-') {
input++;
if (!term(input)) {
return false;
}
consumeWhitespace(&input);
}
return true;
}

int main() {
char input[100];
printf("Enter an expression: ");
fgets(input, sizeof(input), stdin);
input[strlen(input) - 1] = '\0';

if (expression(input)) {
printf("Valid expression!\n");
} else {
printf("Invalid expression!\n");
}

return 0;
}
5.CONSTRUCT SHIFT REDUCE PARSER FOR A GIVEN
LANGUAGE
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
typedef enum {
NUM,
PLUS,
MINUS,
TIMES,
DIVIDE,
LPAREN,
RPAREN,
END
} TokenType;
typedef struct {
TokenType type;
int value;
} Token;
Token getNextToken(char **input);
bool parseExpression(char **input);
bool parseTerm(char **input);
bool parseFactor(char **input);
void consumeWhitespace(char **input) {
while (**input == ' ') {
(*input)++;
}
}
Token getNextToken(char **input) {
consumeWhitespace(input);
Token token;
switch (**input) {
case '+':
token.type = PLUS;
(*input)++;
break;
case '-':
token.type = MINUS;
(*input)++;
break;
case '*':
token.type = TIMES;
(*input)++;
break;
case '/':
token.type = DIVIDE;
(*input)++;
break;
case '(':
token.type = LPAREN;
(*input)++;
break;
case ')':
token.type = RPAREN;
(*input)++;
break;
case '\0':
token.type = END;
break;
default:
if (isdigit(**input)) {
token.type = NUM;
token.value = strtol(*input, input, 10);
} else {
printf("Invalid token\n");
exit(1);
}
}
return token;
}
bool parseFactor(char **input) {
Token token = getNextToken(input);
switch (token.type) {
case NUM:
return true;
case LPAREN:
if (!parseExpression(input)) {
return false;
}
token = getNextToken(input);
if (token.type != RPAREN) {
printf("Expected ')'\n");
return false;
}
return true;
default:
printf("Invalid factor\n");
return false;
}
}
bool parseTerm(char **input) {
if (!parseFactor(input)) {
return false;
}
while (true) {
Token token = getNextToken(input);
switch (token.type) {
case TIMES:
case DIVIDE:
if (!parseFactor(input)) {
return false;
}
break;
default:
(*input)--;
return true;
}}}
bool parseExpression(char **input) {
if (!parseTerm(input)) {
return false;
}
while (true) {
Token token = getNextToken(input);
switch (token.type) {
case PLUS:
case MINUS:
if (!parseTerm(input)) {
return false;
}
break;
default:
(*input)--;
return true;
}}}

int main() {
char input[100];
printf("Enter an expression: ");
fgets(input, sizeof(input), stdin);
if (parseExpression(&input)) {
printf("Valid expression!\n");
} else {
printf("Invalid expression!\n");
}
return 0; }
6.IMPLEMENT INTERMEDIATE CODE GENERATION OF A
SIMPLE EXPRESSION (W:a*b+c/d-e/f+g*h)
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char op; // Operator
char arg1; // Argument 1
char arg2; // Argument 2
char result; // Result
} Quadruple;
void generateIntermediateCode(char *expression) {
Quadruple quadruples[100]; // Array to store quadruples
int numQuadruples = 0; // Counter for number of quadruples
char result = 't'; // Temporary variable for results

for (int i = 0; expression[i] != '\0'; i++) {


if (expression[i] == ' ') {
continue; // Skip whitespace
} else if (expression[i] == '*' || expression[i] == '/' || expression[i] == '+' || expression[i] == '-') {
Quadruple quad;
quad.op = expression[i];
quad.arg1 = expression[i - 1];
quad.arg2 = expression[i + 1];
quad.result = result++;
quadruples[numQuadruples++] = quad;
}
}
printf("Intermediate Code:\n");
for (int i = 0; i < numQuadruples; i++) {
printf("%c = %c %c %c\n", quadruples[i].result, quadruples[i].arg1, quadruples[i].op,
quadruples[i].arg2);
}
}

int main() {
char expression[] = "a*b+c/d-e/f+g*h";
generateIntermediateCode(expression);
return 0;
}

You might also like