CD Lab Manual File
CD Lab Manual File
RecognizedbyAICTEandApprovedbyDr.APJAKTU, Lucknow
DEPARTMENTOFCOMPUTERSCIENCEAND ENGINNERING
SESSION(2024-2025)
NAME:-KULDEEP KUMAR
INDEX
COMPILER DESGIN
Program
No. ProgramName Date Signature
Design and implement a lexical analyzer for given language using C and the lexical analyzer should
ignore redundant spaces, tabs and new lines.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
// Define token types
typedef enum {
KEYWORD,
IDENTIFIER,
NUMBER,
OPERATOR,
UNKNOWN,
END_OF_FILE
} TokenType;
// Keywords list for simple language (example)
const char *keywords[] = {"int", "float", "if", "else", "while", "return"};
#define NUM_KEYWORDS 6
// Function to check if a string is a keyword
int is_keyword(const char *word) {
for (int i = 0; i < NUM_KEYWORDS; i++) {
if (strcmp(word, keywords[i]) == 0) {
return 1;
}
}
return 0;
}
// Function to check if a character is an operator
int is_operator(char c) {
return (c == '+' || c == '-' || c == '*' || c == '/' || c == '=' || c == '<' || c == '>');
}
// Function to handle identifier or keyword
TokenType handle_identifier_or_keyword(const char *word) {
if (is_keyword(word)) {
return KEYWORD;
} else {
return IDENTIFIER;
}
}
PRACTICALNo:-03
Implementation of Lexical Analyzer using Lex Tool
%{
#include <stdio.h>
#include <stdlib.h>
%}
%%
%%
int main() {
return 0;
int yywrap() {
return 1;
PRACTICALNo:-04
Generate YACC specification for a few syntactic categories.
a) Program to recognize a valid arithmetic expression that uses operator +, – , * and /.
b) Program to recognize a valid variable which starts with a letter followed by any number of
letters or digits.
c) Implementation of Calculator using LEX and YACC
YACC Code:-
%{
#include <stdio.h>
#include <stdlib.h>
%}
%%
input:
/* empty */
| input expr '\n' { printf("Result = %d\n", $2); }
;
expr:
expr PLUS expr { $$ = $1 + $3; }
| expr MINUS expr { $$ = $1 - $3; }
| expr MUL expr { $$ = $1 * $3; }
| expr DIV expr { $$ = $1 / $3; }
| LPAREN expr RPAREN { $$ = $2; }
| NUMBER { $$ = $1; }
;
%%
int main() {
printf("Enter an expression: ");
yyparse(); // Start parsing
return 0;
}
Lex Code:-
%{
#include "y.tab.h" // Include YACC header to use token definitions
%}
digit [0-9]
%%
%%
int yywrap() {
return 1;
}
PRACTICALNo:-05
Program to recognize a valid arithmetic expression that uses
operator +, – , * and /.c
%%
%%
%{
#include <stdio.h>
#include <stdlib.h>
%token NUMBER
%%
expr:
expr '+' expr
| expr '-' expr
| expr '*' expr
| expr '/' expr
| NUMBER
;
%%
int main() {
printf("Enter an arithmetic expression: ");
if (yyparse() == 0) {
printf("Valid expression\n");
}
return 0;
}
PRACTICALNo:-06
Write program to convert NFA with ε transition to NFA without ε
transition.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int transitions[MAX_STATES][MAX_SYMBOLS];
int start_state;
int accept_states[MAX_STATES];
int state_count;
int symbol_count;
} NFAWithoutEpsilon;
// Function to convert NFA with epsilon transitions to NFA without epsilon transitions
void convert_to_nfa_without_epsilon(NFAWithEpsilon *nfa, NFAWithoutEpsilon *new_nfa) {
int epsilon_closures[MAX_STATES][MAX_STATES] = {0}; // Stores epsilon closures
// Compute epsilon closures for all states
for (int state = 0; state < nfa->state_count; state++) {
epsilon_closure(nfa, state, epsilon_closures[state]);
}
new_nfa->state_count = nfa->state_count;
new_nfa->symbol_count = nfa->symbol_count;
new_nfa->start_state = nfa->start_state;
memset(new_nfa->accept_states, 0, sizeof(new_nfa->accept_states));
// New accept states are any state that has an accept state in its epsilon closure
for (int state = 0; state < nfa->state_count; state++) {
for (int closure_state = 0; closure_state < nfa->state_count; closure_state++) {
if (epsilon_closures[state][closure_state] && nfa->accept_states[closure_state]) {
new_nfa->accept_states[state] = 1;
break;
}
}
}
}
printf("Transitions:\n");
for (int state = 0; state < nfa->state_count; state++) {
for (int symbol = 0; symbol < nfa->symbol_count; symbol++) {
if (nfa->transitions[state][symbol]) {
printf("State %d on input %d -> ", state, symbol);
for (int next_state = 0; next_state < nfa->state_count; next_state++) {
if (nfa->transitions[state][symbol] & (1 << next_state)) {
printf("%d ", next_state);
}
}
printf("\n");
}
}
}
}
int main() {
NFAWithEpsilon nfa;
NFAWithoutEpsilon new_nfa;
return 0;
}
PRACTICALNo:-07
NFA to DFA Conversion Program in C.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STATES 10
#define MAX_SYMBOLS 2 // Assume 'a' and 'b'
void convert_nfa_to_dfa() {
int queue[1 << MAX_STATES], front = 0, rear = 0;
queue[rear++] = 1 << 0; // Start state is 0
visited[1 << 0] = 1;
dfa_num_states = rear;
}
void print_dfa() {
printf("\nDFA Transitions (state numbers represent NFA state sets in bitmask):\n");
for (int i = 0; i < (1 << nfa_num_states); i++) {
if (visited[i]) {
printf("From state %2d (", i);
for (int k = 0; k < nfa_num_states; k++)
if (i & (1 << k)) printf("%d", k);
printf("): ");
for (int j = 0; j < MAX_SYMBOLS; j++) {
printf(" on '%c' -> %2d (", 'a' + j, dfa[i][j]);
for (int k = 0; k < nfa_num_states; k++)
if (dfa[i][j] & (1 << k)) printf("%d", k);
printf(") ");
}
printf("\n");
}
}
}
int main() {
int num_transitions, from, to;
char symbol;
convert_nfa_to_dfa();
print_dfa();
return 0;
}
PRACTICALNo:-08
Write program to find Simulate First and Follow of any given
grammar
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX 20
char production[MAX][MAX];
char first[MAX][MAX], follow[MAX][MAX];
int numProductions;
char nonTerminals[MAX];
int numNonTerminals = 0;
int isNonTerminal(char c) {
return (c >= 'A' && c <= 'Z');
}
int isTerminal(char c) {
return (c >= 'a' && c <= 'z');
}
int indexOfNonTerminal(char c) {
for (int i = 0; i < numNonTerminals; i++) {
if (nonTerminals[i] == c)
return i;
}
return -1;
}
void addToSet(char *set, char c) {
if (strchr(set, c) == NULL) {
int len = strlen(set);
set[len] = c;
set[len + 1] = '\0';
}
}
if (!isNonTerminal(*prodBody)) {
addToSet(resultSet, *prodBody);
} else {
char tempSet[MAX] = "";
computeFirst(*prodBody, tempSet);
for (int i = 0; tempSet[i]; i++) {
if (tempSet[i] != '#')
addToSet(resultSet, tempSet[i]);
}
if (strchr(tempSet, '#')) {
firstOfProduction(prodBody + 1, resultSet);
}
}
}
if (strchr(tempSet, '#')) {
if (production[i][0] != symbol) {
computeFollow(production[i][0], resultSet);
}
}
} else if (production[i][0] != symbol) {
computeFollow(production[i][0], resultSet);
}
}
}
}
}
int main() {
printf("Enter number of productions: ");
scanf("%d", &numProductions);
getchar();
char nt = production[i][0];
if (indexOfNonTerminal(nt) == -1) {
nonTerminals[numNonTerminals++] = nt;
}
}
return 0;
}
PRACTICALNo:-09
Write a program to perform constant propagation.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct {
char var[20];
int value;
int isConstant;
} Symbol;
Symbol table[MAX];
int symbolCount = 0;
if (isNumber(left)) {
lval = atoi(left);
} else if (lidx != -1 && table[lidx].isConstant) {
lval = table[lidx].value;
} else {
return 0;
}
if (isNumber(right)) {
rval = atoi(right);
} else if (ridx != -1 && table[ridx].isConstant) {
rval = table[ridx].value;
} else {
return 0;
}
return 1;
}
while (1) {
fgets(line, sizeof(line), stdin);
if (strcmp(line, "\n") == 0) break;
propagateConstant(line);
}
return 0;
}
Input
a = 5;
b = a + 2;
c = b * 3;
Output
a = 5;
b = 7;
c = 21;
PRACTICALNo:-10
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int tempCount = 1;
while (expr[i] == ' ' || expr[i] == '=') i++; // skip = and whitespace
op1 = expr[i++];
int main() {
char expr[50];
printf("Enter an expression (e.g., a = b + c * d):\n");
fgets(expr, sizeof(expr), stdin);
generateIC(expr);
return 0;
}
Input
a=b+c*d
Output
t1 = c * d
t2 = b + t1
a = t2