0% found this document useful (0 votes)
3 views37 pages

Lexical Analyzer and NFA Conversion in C

The document contains multiple C programs for automata theory, including a lexical analyzer, ε-closure computation for NFA, conversion of NFA with ε transitions to NFA without ε transitions, and conversion of NFA to DFA. Each program includes code snippets that demonstrate the implementation of the respective algorithms and their functionalities. The document also provides sample inputs and outputs for each program to illustrate their usage.
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)
3 views37 pages

Lexical Analyzer and NFA Conversion in C

The document contains multiple C programs for automata theory, including a lexical analyzer, ε-closure computation for NFA, conversion of NFA with ε transitions to NFA without ε transitions, and conversion of NFA to DFA. Each program includes code snippets that demonstrate the implementation of the respective algorithms and their functionalities. The document also provides sample inputs and outputs for each program to illustrate their usage.
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

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

You might also like