CD File Sem6
CD File Sem6
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);
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