1.
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>
char keywords[][10] = {"int", "float", "if", "else", "while", "return"};
int isKeyword(char *str) {
for (int i = 0; i < 6; i++) {
if (strcmp(str, keywords[i]) == 0)
return 1;
return 0;
}
void analyze(char *code) {
int i = 0;
char token[100];
while (code[i] != '\0') {
// Skip spaces, tabs, and newlines
if (isspace(code[i])) {
i++;
continue;
// Identifiers or Keywords
if (isalpha(code[i])) {
int j = 0;
while (isalnum(code[i])) {
token[j++] = code[i++];
token[j] = '\0';
if (isKeyword(token))
printf("Keyword: %s\n", token);
else
printf("Identifier: %s\n", token);
// Numbers
else if (isdigit(code[i])) {
int j = 0;
while (isdigit(code[i])) {
token[j++] = code[i++];
token[j] = '\0';
printf("Number: %s\n", token);
// Operators
else if (strchr("+-*/=", code[i])) {
printf("Operator: %c\n", code[i]);
i++;
// Special symbols
else if (strchr(";:,(){}", code[i])) {
printf("Special Symbol: %c\n", code[i]);
i++;
}
// Unknown character
else {
printf("Unknown Character: %c\n", code[i]);
i++;
int main() {
char code[1000];
printf("Enter source code (end with $):\n");
fgets(code, sizeof(code), stdin);
analyze(code);
return 0;
Output:-
Enter source code (end with $):
float d=8.9
Keyword: float
Identifier: d
Operator: =
Number: 8
Unknown Character: .
Number: 9
2. Write program to find ε – closure of all states of any given NFA with ε transition.
#include <stdio.h>
#include <stdlib.h>
#define MAX 20
int nfa[MAX][MAX]; // Adjacency matrix for ε-transitions
int closure[MAX][MAX]; // Stores ε-closure sets
int visited[MAX];
void resetVisited(int n) {
for (int i = 0; i < n; i++)
visited[i] = 0;
}
void epsilonClosureUtil(int state, int n, int currentClosure[], int *index) {
if (visited[state]) return;
visited[state] = 1;
currentClosure[(*index)++] = state;
for (int i = 0; i < n; i++) {
if (nfa[state][i] == 1) {
epsilonClosureUtil(i, n, currentClosure, index);
}
}
}
void computeEpsilonClosures(int n) {
for (int state = 0; state < n; state++) {
resetVisited(n);
int index = 0;
epsilonClosureUtil(state, n, closure[state], &index);
// Mark end with -1
closure[state][index] = -1;
}
}
void printEpsilonClosures(int n) {
for (int i = 0; i < n; i++) {
printf("ε-closure(q%d) = { ", i);
for (int j = 0; closure[i][j] != -1; j++) {
printf("q%d ", closure[i][j]);
}
printf("}\n");
}
}
int main() {
int n, trans;
printf("Enter the number of states in the NFA: ");
scanf("%d", &n);
// Initialize transition matrix to 0
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
nfa[i][j] = 0;
printf("Enter number of ε-transitions: ");
scanf("%d", &trans);
printf("Enter ε-transitions in format (from to):\n");
for (int i = 0; i < trans; i++) {
int from, to;
scanf("%d %d", &from, &to);
nfa[from][to] = 1;
}
computeEpsilonClosures(n);
printf("\n--- ε-CLOSURES ---\n");
printEpsilonClosures(n);
return 0;
}
Input:
Enter the number of states in the NFA: 4
Enter number of ε-transitions: 4
Enter ε-transitions in format (from to):
01
12
23
31
Output:
--- ε-CLOSURES ---
ε-closure(q0) = { q0 q1 q2 q3 }
ε-closure(q1) = { q1 q2 q3 }
ε-closure(q2) = { q2 q3 q1 }
ε-closure(q3) = { q3 q1 q2 }
3. Write program to convert NFA with ε transition to NFA without ε transition.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 10
int epsilon[MAX][MAX]; // epsilon transitions matrix
int transition[MAX][MAX][MAX]; // transition[state][symbol][list of states]
int nStates, nSymbols;
char symbols[MAX];
int closure[MAX][MAX]; // ε-closure of each state
int closureCount[MAX];
int newTransition[MAX][MAX][MAX];
int newTransCount[MAX][MAX];
void addToClosure(int state, int val) {
for (int i = 0; i < closureCount[state]; i++) {
if (closure[state][i] == val) return;
}
closure[state][closureCount[state]++] = val;
}
void computeEpsilonClosure() {
for (int s = 0; s < nStates; s++) {
int stack[MAX], top = -1;
int visited[MAX] = {0};
stack[++top] = s;
visited[s] = 1;
addToClosure(s, s);
while (top != -1) {
int curr = stack[top--];
for (int j = 0; j < nStates; j++) {
if (epsilon[curr][j] && !visited[j]) {
visited[j] = 1;
addToClosure(s, j);
stack[++top] = j;
}
}
}
}
}
void buildNewTransition() {
for (int state = 0; state < nStates; state++) {
for (int a = 0; a < nSymbols; a++) {
int result[MAX] = {0}, count = 0;
// For each state in ε-closure(state)
for (int i = 0; i < closureCount[state]; i++) {
int inter = closure[state][i];
// Look for transitions from inter on input symbol
for (int j = 0; transition[inter][a][j] != -1; j++) {
int target = transition[inter][a][j];
// Add ε-closure(target) to result
for (int k = 0; k < closureCount[target]; k++) {
int newState = closure[target][k];
int found = 0;
for (int m = 0; m < count; m++) {
if (result[m] == newState) {
found = 1;
break;
}
}
if (!found) result[count++] = newState;
}
}
}
// Save result as new transition
for (int i = 0; i < count; i++) {
newTransition[state][a][i] = result[i];
}
newTransCount[state][a] = count;
}
}
}
void printNFAWithoutEpsilon() {
printf("\nNFA Without ε-Transitions:\n");
for (int i = 0; i < nStates; i++) {
for (int a = 0; a < nSymbols; a++) {
printf("From q%d on %c: ", i, symbols[a]);
if (newTransCount[i][a] == 0) {
printf("None");
} else {
for (int j = 0; j < newTransCount[i][a]; j++) {
printf("q%d ", newTransition[i][a][j]);
}
}
printf("\n");
}
}
}
int main() {
int nTrans;
printf("Enter number of states: ");
scanf("%d", &nStates);
printf("Enter number of input symbols: ");
scanf("%d", &nSymbols);
printf("Enter the symbols (no ε here, only actual input symbols):\n");
for (int i = 0; i < nSymbols; i++) {
scanf(" %c", &symbols[i]);
}
// Initialize transitions
for (int i = 0; i < nStates; i++) {
for (int j = 0; j < nSymbols; j++) {
for (int k = 0; k < MAX; k++) {
transition[i][j][k] = -1;
}
}
}
printf("Enter number of transitions (excluding ε): ");
scanf("%d", &nTrans);
printf("Enter transitions in format: <from> <symbol> <to>\n");
for (int i = 0; i < nTrans; i++) {
int from, to;
char sym;
scanf("%d %c %d", &from, &sym, &to);
for (int s = 0; s < nSymbols; s++) {
if (symbols[s] == sym) {
int j = 0;
while (transition[from][s][j] != -1) j++;
transition[from][s][j] = to;
break;
}
}
}
printf("Enter number of ε-transitions: ");
scanf("%d", &nTrans);
printf("Enter ε-transitions in format: <from> <to>\n");
for (int i = 0; i < nTrans; i++) {
int from, to;
scanf("%d %d", &from, &to);
epsilon[from][to] = 1;
}
computeEpsilonClosure();
buildNewTransition();
printNFAWithoutEpsilon();
return 0;
}
Input-
Enter number of states: 3
Enter number of input symbols: 2
Enter the symbols (no ε here, only actual input symbols):
ab
Enter number of transitions (excluding ε): 2
Enter transitions in format: <from> <symbol> <to>
0a1
1 b2
Enter number of ε-transitions: 2
Enter ε-transitions in format: <from> <to>
02
21
Output-
NFA Without ε-Transitions:
From q0 on a: q1
From q0 on b: q2 q1
From q1 on a: None
From q1 on b: q2 q1
From q2 on a: None
From q2 on b: q2 q1
4. Write program to convert NFA to DFA.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 20
int nfa[MAX][MAX]; // NFA transition table
int nfaStates, nfaSymbols;
char symbols[MAX];
int dfa[MAX][MAX]; // DFA transition table
int dfaStates = 0;
int dfaStatesList[MAX][MAX]; // DFA states as sets of NFA states
int dfaMarked[MAX]; // 0 = unmarked, 1 = marked
int stateExists(int stateSet[], int size) {
for (int i = 0; i < dfaStates; i++) {
int count = 0;
for (int j = 0; j < size; j++) {
for (int k = 0; dfaStatesList[i][k] != -1; k++) {
if (dfaStatesList[i][k] == stateSet[j]) {
count++;
break;
}
}
}
if (count == size) return i;
}
return -1;
}
void sortSet(int set[], int size) {
for (int i = 0; i < size - 1; i++)
for (int j = i + 1; j < size; j++)
if (set[i] > set[j]) {
int temp = set[i];
set[i] = set[j];
set[j] = temp;
}
}
void addDFAState(int stateSet[], int size) {
sortSet(stateSet, size);
for (int i = 0; i < size; i++)
dfaStatesList[dfaStates][i] = stateSet[i];
dfaStatesList[dfaStates][size] = -1;
dfaMarked[dfaStates] = 0;
dfaStates++;
}
void getNextState(int stateSet[], int size, int symbol, int result[], int *resultSize) {
int visited[MAX] = {0};
*resultSize = 0;
for (int i = 0; i < size; i++) {
int state = stateSet[i];
for (int j = 0; j < nfaStates; j++) {
if (nfa[state * nfaSymbols + symbol][j] == 1 && !visited[j]) {
visited[j] = 1;
result[(*resultSize)++] = j;
}
}
}
}
void printStateSet(int stateSet[]) {
printf("{");
for (int i = 0; stateSet[i] != -1; i++) {
printf("q%d", stateSet[i]);
if (stateSet[i + 1] != -1)
printf(",");
}
printf("}");
}
void convertNFAtoDFA() {
int initialSet[1] = {0};
addDFAState(initialSet, 1);
for (int i = 0; i < dfaStates; i++) {
if (dfaMarked[i]) continue;
dfaMarked[i] = 1;
for (int sym = 0; sym < nfaSymbols; sym++) {
int result[MAX], resultSize = 0;
getNextState(dfaStatesList[i], MAX, sym, result, &resultSize);
if (resultSize == 0) continue;
sortSet(result, resultSize);
int existing = stateExists(result, resultSize);
if (existing == -1) {
addDFAState(result, resultSize);
existing = dfaStates - 1;
}
dfa[i][sym] = existing;
}
}
}
int main() {
printf("Enter number of NFA states: ");
scanf("%d", &nfaStates);
printf("Enter number of input symbols: ");
scanf("%d", &nfaSymbols);
printf("Enter the input symbols: ");
for (int i = 0; i < nfaSymbols; i++)
scanf(" %c", &symbols[i]);
printf("Enter the transition table (state symbol → states):\n");
printf("Enter number of transitions: ");
int transitions;
scanf("%d", &transitions);
for (int i = 0; i < nfaStates * nfaSymbols; i++)
for (int j = 0; j < nfaStates; j++)
nfa[i][j] = 0;
for (int i = 0; i < transitions; i++) {
int from, to;
char sym;
printf("Transition %d (from state symbol to state): ", i + 1);
scanf("%d %c %d", &from, &sym, &to);
for (int s = 0; s < nfaSymbols; s++) {
if (symbols[s] == sym) {
nfa[from * nfaSymbols + s][to] = 1;
break;
}
}
}
convertNFAtoDFA();
printf("\nDFA States and Transitions:\n");
for (int i = 0; i < dfaStates; i++) {
printf("State %d: ", i);
printStateSet(dfaStatesList[i]);
printf("\n");
for (int sym = 0; sym < nfaSymbols; sym++) {
int to = dfa[i][sym];
if (to >= 0) {
printf(" On '%c' -> State %d ", symbols[sym], to);
printStateSet(dfaStatesList[to]);
printf("\n");
}
}
}
return 0;
}
Input-
Enter number of NFA states: 3
Enter number of input symbols: 2
Enter the input symbols: a b
Enter the transition table (state symbol → states):
Enter number of transitions: 4
Transition 1 (from state symbol to state): 0 a 0
Transition 2 (from state symbol to state): 0 a 1
Transition 3 (from state symbol to state): 0 b 0
Transition 4 (from state symbol to state): 1 b 2
Output-
DFA States and Transitions:
State 0: {q0}
On 'a' -> State 1 {q0,q1}
On 'b' -> State 0 {q0}
State 1: {q0,q1}
On 'a' -> State 1 {q0,q1}
On 'b' -> State 2 {q0,q2}
State 2: {q0,q2}
On 'a' -> State 1 {q0,q1}
On 'b' -> State 0 {q0}
5. Write program to find Simulate First and Follow of any given grammar.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define SIZE 10
char prod[10][10]; // productions
char first[10][10];
char follow[10][10];
int n; // number of productions
void findFirst(char[], int, int);
void findFollow(char c);
void addToResultSet(char[], char);
int main() {
int i;
char ch;
printf("Enter number of productions: ");
scanf("%d", &n);
printf("Enter productions :\n");
for (i = 0; i < n; i++) {
scanf("%s", prod[i]);
for (i = 0; i < n; i++) {
findFirst(prod[i], 0, i);
printf("\nFIRST sets:\n");
for (i = 0; i < n; i++) {
printf("FIRST(%c) = { ", prod[i][0]);
for (int j = 0; first[i][j] != '\0'; j++)
printf("%c ", first[i][j]);
printf("}\n");
// Compute FOLLOW
for (i = 0; i < n; i++) {
follow[i][0] = '\0';
follow[0][0] = '$'; // $ is end of input
for (i = 0; i < n; i++) {
findFollow(prod[i][0]);
printf("\nFOLLOW sets:\n");
for (i = 0; i < n; i++) {
printf("FOLLOW(%c) = { ", prod[i][0]);
for (int j = 0; follow[i][j] != '\0'; j++)
printf("%c ", follow[i][j]);
printf("}\n");
return 0;
// Add symbol to result set if not already present
void addToResultSet(char result[], char val) {
int i;
for (i = 0; result[i] != '\0'; i++) {
if (result[i] == val)
return;
result[i] = val;
result[i + 1] = '\0';
void findFirst(char* result, int q1, int q2) {
char ch;
int k;
if (!(isupper(result[q1]))) {
addToResultSet(first[q2], result[q1]);
return;
for (k = 0; k < n; k++) {
if (prod[k][0] == result[q1]) {
if (prod[k][2] == '$') {
addToResultSet(first[q2], '$');
} else if (islower(prod[k][2])) {
addToResultSet(first[q2], prod[k][2]);
} else {
findFirst(prod[k], 2, q2);
}
void findFollow(char c) {
int i, j;
for (i = 0; i < n; i++) {
for (j = 2; j < strlen(prod[i]); j++) {
if (prod[i][j] == c) {
if (prod[i][j + 1] != '\0') {
if (islower(prod[i][j + 1])) {
addToResultSet(follow[i], prod[i][j + 1]);
} else {
// Add FIRST of next non-terminal
for (int k = 0; k < n; k++) {
if (prod[k][0] == prod[i][j + 1]) {
for (int l = 0; first[k][l] != '\0'; l++) {
if (first[k][l] != '$')
addToResultSet(follow[i], first[k][l]);
if (prod[i][j + 1] == '\0' || first[i][j + 1] == '$') {
if (c != prod[i][0]) {
findFollow(prod[i][0]);
for (int m = 0; m < n; m++) {
if (prod[m][0] == prod[i][0]) {
for (int l = 0; follow[m][l] != '\0'; l++)
addToResultSet(follow[i], follow[m][l]);
Input-
Enter number of productions: 4
Enter productions :
E->TR
R->+TR
R->$
T->id
Output-
FIRST sets:
FIRST(E) = { > }
FIRST(R) = { > }
FIRST(R) = { > }
FIRST(T) = { > }
FOLLOW sets:
FOLLOW(E) = { $ > }
FOLLOW(R) = { > }
FOLLOW(R) = { }
FOLLOW(T) = { }
6. WRITE A C PROGRAM TO RECOGNIZE STRING UNDER „a*‟,‟a*b+‟,‟abb‟.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
bool is_a_star(const char *str) {
for (int i = 0; str[i]; i++) {
if (str[i] != 'a')
return false;
}
return true;
}
bool is_a_star_b_plus(const char *str) {
int i = 0;
// zero or more 'a'
while (str[i] == 'a') i++;
// at least one 'b'
int b_count = 0;
while (str[i] == 'b') {
b_count++;
i++;
}
return (b_count >= 1 && str[i] == '\0');
}
bool is_abb(const char *str) {
return strcmp(str, "abb") == 0;
}
int main() {
char input[100];
printf("Enter a string: ");
scanf("%s", input);
if (is_abb(input)) {
printf("The string matches pattern: abb\n");
} else if (is_a_star_b_plus(input)) {
printf("The string matches pattern: a*b+\n");
} else if (is_a_star(input)) {
printf("The string matches pattern: a*\n");
} else {
printf("The string does not match any pattern.\n");
}
return 0;
}
Output-
Enter a string: abb
The string matches pattern: abb
7. Write program to minimize any given DFA.
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#define MAX 20
int states, symbols;
int transition[MAX][MAX];
int final_states[MAX], final_count;
bool distinguish[MAX][MAX];
void inputDFA() {
int i, j;
printf("Enter number of states: ");
scanf("%d", &states);
printf("Enter number of symbols: ");
scanf("%d", &symbols);
printf("Enter transition table (row: state, column: symbol):\n");
for (i = 0; i < states; i++) {
for (j = 0; j < symbols; j++) {
printf("δ(q%d, %c): ", i, 'a'+j);
scanf("%d", &transition[i][j]);
}
}
printf("Enter number of final states: ");
scanf("%d", &final_count);
printf("Enter final states (space separated): ");
for (i = 0; i < final_count; i++) {
scanf("%d", &final_states[i]);
}
}
bool isFinal(int state) {
for (int i = 0; i < final_count; i++) {
if (final_states[i] == state)
return true;
}
return false;
}
void minimizeDFA() {
memset(distinguish, false, sizeof(distinguish));
// Mark distinguishable pairs: one final, one non-final
for (int i = 0; i < states; i++) {
for (int j = 0; j < i; j++) {
if (isFinal(i) != isFinal(j)) {
distinguish[i][j] = true;
}
}
}
// Iteratively mark distinguishable pairs
bool updated;
do {
updated = false;
for (int i = 0; i < states; i++) {
for (int j = 0; j < i; j++) {
if (!distinguish[i][j]) {
for (int k = 0; k < symbols; k++) {
int ti = transition[i][k];
int tj = transition[j][k];
if (ti != tj && (ti > tj ? distinguish[ti][tj] : distinguish[tj][ti])) {
distinguish[i][j] = true;
updated = true;
break;
}
}
}
}
}
} while (updated);
// Print equivalent states
printf("\nMinimized DFA Equivalence Classes:\n");
bool printed[MAX] = {false};
for (int i = 0; i < states; i++) {
if (!printed[i]) {
printf("{ q%d", i);
for (int j = i + 1; j < states; j++) {
if (!distinguish[i > j ? i : j][i > j ? j : i]) {
printf(", q%d", j);
printed[j] = true;
}
}
printf(" }\n");
printed[i] = true;
}
}
}
int main() {
inputDFA();
minimizeDFA();
return 0;
}
Input-
Enter number of states: 4
Enter number of symbols: 2
Enter transition table (row: state, column: symbol):
δ(q0, a): 1
δ(q0, b): 2
δ(q1, a): 0
δ(q1, b): 3
δ(q2, a): 3
δ(q2, b): 0
δ(q3, a): 2
δ(q3, b): 1
Enter number of final states: 1
Enter final states (space separated): 3
Ouput-
Minimized DFA Equivalence Classes:
{ q0 }
{ q1 }
{ q2 }
{ q3 }
8. WRITE A PROGRAM TO CHEAK INPUT IDENTEFIER IS VALID OR NOT.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
// List of some reserved keywords
const char* keywords[] = {
"auto", "break", "case", "char", "const", "continue", "default", "do", "double",
"else", "enum", "extern", "float", "for", "goto", "if", "int", "long", "register",
"return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef",
"union", "unsigned", "void", "volatile", "while"
};
bool isKeyword(const char* str) {
int n = sizeof(keywords)/sizeof(keywords[0]);
for (int i = 0; i < n; i++) {
if (strcmp(str, keywords[i]) == 0)
return true;
}
return false;
}
bool isValidIdentifier(const char* str) {
if (!isalpha(str[0]) && str[0] != '_')
return false;
for (int i = 1; str[i] != '\0'; i++) {
if (!isalnum(str[i]) && str[i] != '_')
return false;
}
if (isKeyword(str))
return false;
return true;
}
int main() {
char input[100];
printf("Enter an identifier: ");
scanf("%s", input);
if (isValidIdentifier(input))
printf("'%s' is a valid identifier.\n", input);
else
printf("'%s' is NOT a valid identifier.\n", input);
return 0;
}
Output-
Enter an identifier: num1_value
'num1_value' is a valid identifier.
Enter an identifier: int
'int' is NOT a valid identifier.
9. Write a program to perform constant propagation.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 100
typedef struct {
char var[10];
int value;
int is_constant;
} Symbol;
Symbol table[MAX];
int symbol_count = 0;
int findSymbol(char *name) {
for (int i = 0; i < symbol_count; i++) {
if (strcmp(table[i].var, name) == 0)
return i;
}
return -1;
}
void addSymbol(char *name, int value, int is_constant) {
int idx = findSymbol(name);
if (idx == -1) {
strcpy(table[symbol_count].var, name);
table[symbol_count].value = value;
table[symbol_count].is_constant = is_constant;
symbol_count++;
} else {
table[idx].value = value;
table[idx].is_constant = is_constant;
}
}
int main() {
int n;
char lhs[10], op1[10], op[3], op2[10];
printf("Enter number of statements: ");
scanf("%d", &n);
printf("Enter assignments :\n");
for (int i = 0; i < n; i++) {
scanf("%s = %s", lhs, op1);
char ch = getchar();
if (ch == '\n') {
// Constant assignment: a = 5 or a = b
if (isdigit(op1[0])) {
addSymbol(lhs, atoi(op1), 1);
printf("%s = %d\n", lhs, atoi(op1));
} else {
int idx = findSymbol(op1);
if (idx != -1 && table[idx].is_constant) {
addSymbol(lhs, table[idx].value, 1);
printf("%s = %d\n", lhs, table[idx].value);
} else {
addSymbol(lhs, 0, 0); // not a constant
printf("%s = %s\n", lhs, op1);
}
}
} else {
// It's a binary operation: a = b + 3
scanf("%s %s", op, op2);
int v1, v2;
int const1 = 0, const2 = 0;
if (isdigit(op1[0])) {
v1 = atoi(op1);
const1 = 1;
} else {
int idx = findSymbol(op1);
if (idx != -1 && table[idx].is_constant) {
v1 = table[idx].value;
const1 = 1;
}
}
if (isdigit(op2[0])) {
v2 = atoi(op2);
const2 = 1;
} else {
int idx = findSymbol(op2);
if (idx != -1 && table[idx].is_constant) {
v2 = table[idx].value;
const2 = 1;
}
}
if (const1 && const2) {
int result = 0;
if (strcmp(op, "+") == 0) result = v1 + v2;
else if (strcmp(op, "-") == 0) result = v1 - v2;
else if (strcmp(op, "*") == 0) result = v1 * v2;
else if (strcmp(op, "/") == 0) result = v1 / v2;
addSymbol(lhs, result, 1);
printf("%s = %d\n", lhs, result);
} else {
addSymbol(lhs, 0, 0);
printf("%s = %s %s %s\n", lhs, op1, op, op2);
}
}
}
return 0;
}
Input-
Enter number of statements: 4
Enter assignments :
a=5
b = 10
c=a+b
d=c+2
Output-
a=5
b = 10
c = 15
d = 17
10. Implement Intermediate code generation for simple expressions.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
char expr[100];
int temp_var = 1;
// Function to generate new temp variable name
char* newTemp() {
static char temp[10];
sprintf(temp, "t%d", temp_var++);
return temp;
}
// Function to find operator based on precedence
int findOperator(char *exp, char op) {
for (int i = 0; exp[i]; i++) {
if (exp[i] == op)
return i;
}
return -1;
}
void generateTAC(char *exp) {
char left[100], right[100], result[10];
int pos;
// Operator precedence: *, / > +, -
while ((pos = findOperator(exp, '*')) != -1 ||
(pos = findOperator(exp, '/')) != -1 ||
(pos = findOperator(exp, '+')) != -1 ||
(pos = findOperator(exp, '-')) != -1) {
char op = exp[pos];
// Extract left operand
int i = pos - 1;
while (i >= 0 && isalnum(exp[i])) i--;
strncpy(left, &exp[i + 1], pos - i - 1);
left[pos - i - 1] = '\0';
// Extract right operand
int j = pos + 1;
while (exp[j] == ' ') j++; // skip spaces
int start = j;
while (isalnum(exp[j])) j++;
strncpy(right, &exp[start], j - start);
right[j - start] = '\0';
// Generate new temp
strcpy(result, newTemp());
printf("%s = %s %c %s\n", result, left, op, right);
// Replace subexpression with result in original string
char newExp[100];
strncpy(newExp, exp, i + 1);
newExp[i + 1] = '\0';
strcat(newExp, result);
strcat(newExp, &exp[j]);
strcpy(exp, newExp);
}
// Final assignment
printf("%s\n", exp);
}
int main() {
printf("Enter expression : ");
scanf("%s", expr);
// Split LHS and RHS
char *equal = strchr(expr, '=');
if (!equal) {
printf("Invalid expression.\n");
return 1;
}
char lhs[50], rhs[100];
strncpy(lhs, expr, equal - expr);
lhs[equal - expr] = '\0';
strcpy(rhs, equal + 1);
generateTAC(rhs);
printf("%s = %s\n", lhs, rhs);
return 0;
}
Output-
Enter expression : a=b+c*d
t1 = c * d
t2 = b + t1
t2
a = t2