0% found this document useful (0 votes)
14 views25 pages

CD File Sem6

The document contains multiple experiments related to automata theory and programming, including DFA minimization, NFA to DFA conversion, and handling epsilon transitions in NFA. Each experiment includes an aim, theory, code implementation in C, and example inputs and outputs. The programs demonstrate various concepts such as state transitions, variable validation, and arithmetic expression parsing.

Uploaded by

Ansh Varshney
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views25 pages

CD File Sem6

The document contains multiple experiments related to automata theory and programming, including DFA minimization, NFA to DFA conversion, and handling epsilon transitions in NFA. Each experiment includes an aim, theory, code implementation in C, and example inputs and outputs. The programs demonstrate various concepts such as state transitions, variable validation, and arithmetic expression parsing.

Uploaded by

Ansh Varshney
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 25

EXPERIMENT – 07

AIM-Write program to minimize any given DFA.


THEORY- In automata theory, DFA minimization is the task of transforming a
given deterministic finite automaton into an equivalent DFA that has a minimum
number of states.
CODE-
#include <stdio.h>
#include <stdbool.h>
#define MAX 20
int n, sym, trans[MAX][MAX], final[MAX];
bool mark[MAX][MAX];
void input() {
printf("No. of states: ");
scanf("%d", &n);
printf("No. of symbols: ");
scanf("%d", &sym);
printf("Enter transition table (state x symbol):\n");
for (int i = 0; i < n; i++)
for (int j = 0; j < sym; j++)
scanf("%d", &trans[i][j]);
printf("Enter final states (1 if final else 0):\n");
for (int i = 0; i < n; i++)
scanf("%d", &final[i]);
}
void minimize() {
for (int i = 0; i < n; i++)
for (int j = 0; j < i; j++)
if (final[i] != final[j]) mark[i][j] = true;
bool changed;
do {
changed = false;
for (int i = 0; i < n; i++) {
for (int j = 0; j < i; j++) {
if (!mark[i][j]) {
for (int k = 0; k < sym; k++) {
int a = trans[i][k], b = trans[j][k];
if (a != b) {
if (a < b) { int tmp = a; a = b; b = tmp; }
if (mark[a][b]) { mark[i][j] = true; changed = true; break; }
}
}
}
}
}
} while (changed);
}
void display() {
int grp[MAX], g = 0;
for (int i = 0; i < n; i++) {
grp[i] = -1;
for (int j = 0; j < i; j++)
if (!mark[i][j]) { grp[i] = grp[j]; break; }
if (grp[i] == -1) grp[i] = g++;
}
printf("\nMinimized DFA Groups:\n");
for (int i = 0; i < n; i++)
printf("State %d -> Group %d\n", i, grp[i]);
}
int main() {
input();
minimize();
display();
return 0;
}

INPUT-
No. of states: 4
No. of symbols: 2
Enter transitions:
01
10
23
32
Final states:
0
1
0
1

OUTPUT-
Minimized DFA Groups:
State 0 -> Group 0
State 1 -> Group 0
State 2 -> Group 1
State 3 -> Group 1
32
Final states:
0
1
0
1
Identifier: y
Operator: =
Number: 3.14
Symbol: ;
Keyword: if
Symbol: (
Identifier: x
Operator: >
Identifier: y
Symbol: )
Symbol: {
Identifier: x
Operator: =
Identifier: x
Operator: +
Number: 1
Symbol: ;
Symbol: }
EXPERIMENT – 06
AIM- Write program to convert NFA to DFA
THEORY- An NFA can have zero, one or more than one move from a given state
on a given input symbol. An NFA can also have NULL moves. On the other
hand, DFA has one and only one move from a given state on a given input
symbol.
CODE-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 20
int n, sym;
int nfa[MAX][MAX], dfa[MAX][MAX];
int dfa_states[MAX][MAX], dfa_state_count = 0;
char symbols[MAX];
void input() {
printf("No. of NFA states: ");
scanf("%d", &n);
printf("No. of symbols: ");
scanf("%d", &sym);
printf("Enter symbols: ");
for (int i = 0; i < sym; i++)
scanf(" %c", &symbols[i]);
printf("Enter NFA transition table (-1 for no transition):\n");
for (int i = 0; i < n; i++)
for (int j = 0; j < sym; j++)
scanf("%d", &nfa[i][j]);
}
int exists(int *state) {
for (int i = 0; i < dfa_state_count; i++) {
if (memcmp(dfa_states[i], state, n * sizeof(int)) == 0)
return i;
}
return -1;
}
void build_dfa() {
int init[MAX] = {0};
init[0] = 1;
memcpy(dfa_states[dfa_state_count++], init, sizeof(init));
for (int i = 0; i < dfa_state_count; i++) {
for (int s = 0; s < sym; s++) {
int next[MAX] = {0};
for (int j = 0; j < n; j++) {
if (dfa_states[i][j] && nfa[j][s] != -1)
next[nfa[j][s]] = 1;
}
int idx = exists(next);
if (idx == -1) {
memcpy(dfa_states[dfa_state_count], next, sizeof(next));
dfa[i][s] = dfa_state_count;
dfa_state_count++;
} else {
dfa[i][s] = idx;
}
}
}
void display() {
printf("\nDFA Transition Table:\n");
for (int i = 0; i < dfa_state_count; i++) {
printf("State %d: ", i);
for (int j = 0; j < sym; j++)
printf("%c->%d ", symbols[j], dfa[i][j]);
printf("\n");
}
}
int main() {
input();
build_dfa();
display();
return 0;}

INPUT-
No. of NFA states: 3
No. of symbols: 2
Enter symbols: a b
Enter NFA transition table:
1 -1
2 -1
-1 2
turn num;

OUTPUT-
DFA Transition Table:
State 0: a->1 b->2
State 1: a->1 b->2
State 2: a->-1 b->2

EXPERIMENT – 05
AIM- Write program to convert NFA with ε transition to NFA without ε transition.
THEORY- In NFA, epsilon transitions are special transitions that allow the
automaton to change its state without consuming any input symbol. While ε-
transitions do not increase the computational power of NFAs they provide
flexibility in NFA design.
CODE-
#include <stdio.h>
#include <string.h>
#define MAX 20
int n, sym;
char symbols[MAX];
int nfa[MAX][MAX], new_nfa[MAX][MAX];
void input() {
printf("No. of states: ");
scanf("%d", &n);
printf("No. of symbols (including 'e' for epsilon): ");
scanf("%d", &sym);
printf("Enter symbols: ");
for (int i = 0; i < sym; i++) scanf(" %c", &symbols[i]);
printf("Enter NFA transition table (-1 for no transition):\n");
for (int i = 0; i < n; i++)
for (int j = 0; j < sym; j++)
scanf("%d", &nfa[i][j]);
}
void epsilon_closure(int state, int *closure) {
closure[state] = 1;
if (nfa[state][0] != -1 && !closure[nfa[state][0]])
epsilon_closure(nfa[state][0], closure);
}
void remove_epsilon() {
for (int i = 0; i < n; i++) {
int closure[MAX] = {0};
epsilon_closure(i, closure);
for (int j = 1; j < sym; j++) { // skip epsilon symbol
for (int k = 0; k < n; k++) {
if (closure[k] && nfa[k][j] != -1)
new_nfa[i][j] = nfa[k][j];
}
}
}
}
void display() {
printf("\nNFA without epsilon transitions:\n");
for (int i = 0; i < n; i++) {
printf("State %d: ", i);
for (int j = 1; j < sym; j++) // skip epsilon
printf("%c->%d ", symbols[j], new_nfa[i][j]);
printf("\n");
}
}
int main() {
input();
remove_epsilon();
display();
return 0;}

INPUT-
No. of states: 3
No. of symbols: 2
Enter symbols: e a
Enter NFA transition table:
1 -1
2 -1
-1 0

OUTPUT-
NFA without epsilon transitions:
State 0: a->-1
State 1: a->-1
State 2: a->-1
EXPERIMENT - 3(B)
AIM-Program to recognize a valid variable which starts with a letter followed by
any number of letters or digits
THEORY- The following program recognize a valid variable which starts with a
letter followed by any number of letters or digits.
CODE-
#include <stdio.h>
#include <ctype.h>
int isValidVariable(char *str) {
if (!isalpha(str[0])) // Check if first character is a letter
return 0;
for (int i = 1; str[i] != '\0'; i++) {
if (!isalnum(str[i])) // Check if the rest are letters or digits
return 0; }
return 1;}
int main() {
char var[100];
printf("Enter a variable name: ");
scanf("%s", var);
if (isValidVariable(var))
printf("Valid variable name\n");
else
printf("Invalid variable name\n");
return 0;}

INPUT-
myVar1

OUTPUT-
Valid variable name
EXPERIMENT – 3(C)
AIM- Implementation of Calculator using LEX and YACC.
THEORY-An open source program, yacc generates code for the parser in the C
programming language.
CODE-
%{
#include "y.tab.h"
%}
%%
{DIGIT} { yylval = atoi(yytext); return NUMBER; }
"+" { return PLUS; }
"-" { return MINUS; }
"*" { return MULT; }
"/" { return DIV; }
"(" { return LPAREN; }
")" { return RPAREN; }
[ \t\n]+ ; // Ignore spaces
%%
%{
#include <stdio.h>
%}
%token NUMBER PLUS MINUS MULT DIV LPAREN RPAREN
%left PLUS MINUS
%left MULT DIV
%%
expr: expr PLUS term { $$ = $1 + $3; }
| expr MINUS term { $$ = $1 - $3; }
| term;
term: term MULT factor { $$ = $1 * $3; }
| term DIV factor { $$ = $1 / $3; }
| factor;
factor: NUMBER | LPAREN expr RPAREN { $$ = $2; };
%%
int main() {
printf("Enter an arithmetic expression: ");
yyparse();
return 0;
}
int yyerror(char *s) {
printf("Syntax Error\n");
return 0;
}

Input:-
3+5*2

Output:-
Valid Expression
EXPERIMENT – 3(D)
AIM-Convert the BNF rules into YACC form and write code to generate abstract syntax tree
THEORY- The following program converts the BNF rules to YACC form.
CODE-
#include <stdio.h>
#include <stdlib.h>
typedef struct ASTNode {
enum { NUMBER, ADD, SUBTRACT, MULTIPLY, DIVIDE } type;
union {
int value; // for NUMBER nodes
struct {
struct ASTNode *left;
struct ASTNode *right;
} op; // for operator nodes
};
} ASTNode;
// Function to create a number node
ASTNode* createNumberNode(int value) {
ASTNode* node = (ASTNode*)malloc(sizeof(ASTNode));
node->type = NUMBER;
node->value = value;
return node;
}
// Function to create an operator node
ASTNode* createOpNode(int type, ASTNode* left, ASTNode* right) {
ASTNode* node = (ASTNode*)malloc(sizeof(ASTNode));
node->type = type;
node->op.left = left;
node->op.right = right;
return node;
}
// Function to print the AST (in-order traversal)
void printAST(ASTNode* node) {
if (node == NULL) return;
if (node->type == NUMBER) {
printf("%d", node->value);
} else {
printf("(");
printAST(node->op.left);
switch (node->type) {
case ADD: printf(" + "); break;
case SUBTRACT: printf(" - "); break;
case MULTIPLY: printf(" * "); break;
case DIVIDE: printf(" / "); break;
}
printAST(node->op.right);
printf(")");
}
}

INPUT-
3 + 5 * (2 - 8)

OUTPUT-
(3 + (5 * (2 - 8)))
EXPERIMENT – 04
AIM-Write program to find ε – closure of all states of any given NFA with ε transition.
THEORY-The epsilon closure E(q) of a state q in Q is the union of the set {q} with
the set of all states that can be reached from q via one or more ε transitions.
CODE-
#include <stdio.h>
#include <stdlib.h>
#define MAX_STATES 100
typedef struct {
int arr[MAX_STATES];
int top;
} Stack;
void initStack(Stack* stack) {
stack->top = -1;
}
int isEmpty(Stack* stack) {
return stack->top == -1;
}void push(Stack* stack, int value) {
stack->arr[++stack->top] = value;
}int pop(Stack* stack) {
if (!isEmpty(stack)) {
return stack->arr[stack->top--];}
return -1;}
void findEClosure(int state, int epsilonTransitions[MAX_STATES][MAX_STATES], int
numStates, int epsilonCount[MAX_STATES], int closure[MAX_STATES]) {
Stack stack;
initStack(&stack);
push(&stack, state);
while (!isEmpty(&stack)) {
int currentState = pop(&stack);
if (closure[currentState]) continue;
closure[currentState] = 1;
for (int i = 0; i < epsilonCount[currentState]; i++) {
int nextState = epsilonTransitions[currentState][i];
if (!closure[nextState]) {
push(&stack, nextState);
} }}
void computeEClosures(int numStates, int epsilonTransitions[MAX_STATES]
[MAX_STATES], int epsilonCount[MAX_STATES]) {
for (int state = 0; state < numStates; state++) {
int closure[MAX_STATES] = {0};
findEClosure(state, epsilonTransitions, numStates, epsilonCount, closure);
printf("ε-Closure of state %d = { ", state);
for (int i = 0; i < numStates; i++) {
if (closure[i]) {
printf("%d ", i);
} }
printf("}\n");
}}
int main() {
int numStates, numEpsilonTransitions;
printf("Enter number of states: ");
scanf("%d", &numStates);
int epsilonTransitions[MAX_STATES][MAX_STATES] = {0};
int epsilonCount[MAX_STATES] = {0};
printf("Enter number of ε-transitions: ");
scanf("%d", &numEpsilonTransitions);
printf("Enter ε-transitions (from state to state):\n");
for (int i = 0; i < numEpsilonTransitions; i++) {
int from, to;
scanf("%d %d", &from, &to);
epsilonTransitions[from][epsilonCount[from]++] = to;
computeEClosures(numStates, epsilonTransitions, epsilonCount);
return 0;
}
INPUT-
Enter number of states: 4
Enter number of ε-transitions: 4
Enter ε-transitions (from state to state):
01 12 23 33
OUTPUT-
ε-Closure of state 0 = { 0 1 2 3 }
ε-Closure of state 1 = { 1 2 3 }
ε-Closure of state 2 = { 2 3 }
ε-Closure of state 3 = { 3 }

EXPERIMENT – 05
AIM-Write program to convert NFA with ε transition to NFA without ε transition
THEORY- ε closure of any state means with the help of ε (0 length) from that
state, how many new state we can reach
CODE-
#include <stdio.h>
#include <stdlib.h>
#define MAX_STATES 100
#define MAX_ALPHABET 10
int numStates, numAlphabet;
char alphabet[MAX_ALPHABET];
int epsilonTransitions[MAX_STATES][MAX_STATES];
int transitions[MAX_STATES][MAX_ALPHABET][MAX_STATES];
int epsilonCount[MAX_STATES];
int transitionCount[MAX_STATES][MAX_ALPHABET];
// Stack structure for DFS
typedef struct {
int arr[MAX_STATES];
int top;
} Stack;
void initStack(Stack* stack) {
stack->top = -1;
}
void push(Stack* stack, int value) {
stack->arr[++stack->top] = value;
}
int pop(Stack* stack) {
return (stack->top == -1) ? -1 : stack->arr[stack->top--];
}
// Compute ε-closure of a state
void findEClosure(int state, int closure[MAX_STATES]) {
Stack stack;
initStack(&stack);
push(&stack, state);
while (stack.top != -1) {
int current = pop(&stack);
if (!closure[current]) {
closure[current] = 1;
for (int i = 0; i < epsilonCount[current]; i++) {
push(&stack, epsilonTransitions[current][i]);
}
}
}
}
// Convert NFA with ε to NFA without ε
void convertNFA() {
int newTransitions[MAX_STATES][MAX_ALPHABET][MAX_STATES] = {0};
int newTransitionCount[MAX_STATES][MAX_ALPHABET] = {0};
for (int state = 0; state < numStates; state++) {
int closure[MAX_STATES] = {0};
findEClosure(state, closure);
for (int i = 0; i < numAlphabet; i++) {
for (int q = 0; q < numStates; q++) {
if (closure[q]) {
for (int j = 0; j < transitionCount[q][i]; j++) {
int nextState = transitions[q][i][j];
scanf("%d", &numAlphabet);
printf("Enter input symbols: ");
for (int i = 0; i < numAlphabet; i++)
scanf(" %c", &alphabet[i]);
// Input ε-transitions
printf("Enter number of ε-transitions: ");
scanf("%d", &numEpsilonTransitions);

printf("Enter ε-transitions (from to):\n");


for (int i = 0; i < numEpsilonTransitions; i++) {
int from, to;
scanf("%d %d", &from, &to);
epsilonTransitions[from][epsilonCount[from]++] = to;
}
// Input regular transitions
printf("Enter number of regular transitions: ");
scanf("%d", &numRegularTransitions);

printf("Enter transitions (from symbol to):\n");


for (int i = 0; i < numRegularTransitions; i++) {
int from, to;
char symbol;
scanf("%d %c %d", &from, &symbol, &to);
int symbolIndex = -1;
for (int j = 0; j < numAlphabet; j++)
if (alphabet[j] == symbol)
symbolIndex = j;

if (symbolIndex != -1)
transitions[from][symbolIndex][transitionCount[from][symbolIndex]++] = to;
}
// Convert NFA with ε to NFA without ε
convertNFA();
return 0;
}

INPUT:-
Enter number of states: 3
Enter number of input symbols: 2
Enter input symbols: a b
Enter number of ε-transitions: 2
Enter ε-transitions (from to):
01
12
Enter number of regular transitions: 2
Enter transitions (from symbol to):
1a2
2b0

OUTPUT-
NFA Without ε-Transitions:
δ(0, a) -> { 2 }
δ(0, b) -> { 0 }
δ(1, a) -> { 2 }
δ(1, b) -> { 0 }
δ(2, a) -> { }
δ(2, b) -> { 0 }

EXPERIMENT - 06
AIM- Write program to convert NFA to DFA
THEORY- Deterministic Finite Automaton, is a mathematical model in computer
science. For each state and input symbol, there's only one possible next state
transition.
CODE-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STATES 10
#define MAX_ALPHABET 2
#define MAX_DFA_STATES (1 << MAX_STATES)
int nfaTransition[MAX_STATES][MAX_ALPHABET][MAX_STATES];
int nfaAcceptStates[MAX_STATES];
int nfaInitialState;
int dfaTransition[MAX_DFA_STATES][MAX_ALPHABET];
int dfaAcceptStates[MAX_DFA_STATES]; // Accepting states of the DFA
int dfaInitialState; // Initial state of the DFA
int isAcceptingState(int state) {
return nfaAcceptStates[state];
}void epsilonClosure(int states[], int closure[]) {
int stack[MAX_STATES];
int top = 0;
for (int i = 0; i < MAX_STATES; i++) {
closure[i] = 0;
}
for (int i = 0; states[i] != -1; i++) {
stack[top++] = states[i];
closure[states[i]] = 1;
}
while (top > 0) {
int state = stack[--top];
// Check epsilon transitions from the state
for (int i = 0; i < MAX_STATES; i++) {
if (nfaTransition[state][0][i] && !closure[i]) {
stack[top++] = i;
closure[i] = 1;}}}
void move(int states[], char symbol, int nextStates[]) {
int k = 0;
for (int i = 0; states[i] != -1; i++) {
int state = states[i];
int nextState = nfaTransition[state][symbol - 'a'][0]; // Assuming symbol is 'a' or 'b'
if (nextState != -1) {
nextStates[k++] = nextState;
}}
void nfaToDfa() {
for (int i = 0; i < MAX_DFA_STATES; i++) {
dfaAcceptStates[i] = 0;
for (int j = 0; j < MAX_ALPHABET; j++) {
dfaTransition[i][j] = -1;
}}
int initialState[] = { nfaInitialState, -1 }; // Initial state of DFA
int closure[MAX_STATES] = { 0 };
epsilonClosure(initialState, closure);
dfaInitialState = 0; // The DFA's initial state is 0
for (int i = 0; i < MAX_STATES; i++) {
if (closure[i]) {
dfaAcceptStates[dfaInitialState] = 1;
}}
for (int i = 0; i < MAX_DFA_STATES; i++) {
for (char symbol = 'a'; symbol <= 'b'; symbol++)
int nextStates[MAX_STATES];
move(closure, symbol, nextStates);
if (nextStates[0] != -1) {
int newDFAState = 0;
for (int j = 0; nextStates[j] != -1; j++) {
newDFAState |= (1 << nextStates[j]);
} dfaTransition[i][symbol - 'a'] = newDFAState;
}}}
void printDfa() {
printf("DFA Transition Table:\n");
printf("State\tSymbol a\tSymbol b\n");
for (int i = 0; i < MAX_DFA_STATES; i++) {
if (dfaTransition[i][0] != -1 || dfaTransition[i][1] != -1) {
printf("%d\t", i);
for (int j = 0; j < MAX_ALPHABET; j++) {
printf("%d\t", dfaTransition[i][j]);}

printf("\n");}}}
int main() {
nfaInitialState = 0; // Initial state is q0
nfaAcceptStates[1] = 1; // Accepting state q1
nfaAcceptStates[2] = 1; // Accepting state q2
nfaAcceptStates[3] = 0; // q3 is not accepting state
// NFA transitions (assuming symbols 'a' and 'b' for the alphabet)
nfaTransition[0][0][1] = 1; // q0 --a--> q1
nfaTransition[0][1][2] = 1; // q0 --b--> q2
nfaTransition[1][0][1] = 1; // q1 --a--> q1
nfaTransition[2][1][3] = 1; // q2 --b--> q3
// Convert NFA to DFA
nfaToDfa();
// Print the DFA's transition table
printDfa();
return 0;
}

INPUT-
Enter initial state::1
Solving according to DFA1-0-->0
1-1-->0
2-0-->6
2-1-->2
4-0-->0
4-1-->0

OUTPUT-
The total number of distinct states are::
STATE 0 1
q0 0 0
q0 0 0
q1 6 2
q2 0 0
q1 q2 0 0

You might also like