In: Computer Science
Write a program to convert an NFA to an equivalent DFA. The NFA may contain ε transitions.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 100
char NFA_FILE[MAX_LEN];
char buffer[MAX_LEN];
int zz = 0;
// Structure to store DFA states and their
// status ( i.e new entry or already present)
struct DFA {
char
*states;
int
count;
} dfa;
int last_index = 0;
FILE *fp;
int symbols;
/* reset the hash map*/
void reset(int
ar[], int size) {
int i;
// reset all the values
of
// the mapping array to
zero
for (i = 0; i <
size; i++) {
ar[i] = 0;
}
}
// Check which States are present in the
e-closure
/* map the states of NFA to a hash set*/
void check(int
ar[], char S[]) {
int i, j;
// To parse the individual states
of NFA
int len =
strlen(S);
for (i = 0; i <
len; i++) {
// Set hash map for
the position
// of the states
which is found
j =
((int)(S[i]) - 65);
ar[j]++;
}
}
// To find new Closure States
void state(int
ar[], int size,
char S[]) {
int j, k =
0;
// Combine multiple states of
NFA
// to create new states of
DFA
for (j = 0; j <
size; j++) {
if
(ar[j] != 0)
S[k++] =
(char)(65 + j);
}
// mark the end of the
state
S[k] =
'\0';
}
// To pick the next closure from closure set
int closure(int
ar[], int size) {
int i;
// check new closure is present
or not
for (i = 0; i <
size; i++) {
if
(ar[i] == 1)
return
i;
}
return
(100);
}
// Check new DFA states can be
// entered in DFA table or not
int indexing(struct
DFA *dfa) {
int i;
for (i = 0; i <
last_index; i++) {
if
(dfa[i].count == 0)
return
1;
}
return
-1;
}
/* To Display epsilon closure*/
void Display_closure(int
states, int
closure_ar[],
char
*closure_table[],
char
*NFA_TABLE[][symbols + 1],
char
*DFA_TABLE[][symbols]) {
int i;
for (i = 0; i <
states; i++) {
reset(closure_ar,
states);
closure_ar[i] =
2;
// to neglect blank
entry
if
(strcmp(&NFA_TABLE[i][symbols],
"-") != 0) {
// copy
the NFA transition state to buffer
strcpy(buffer,
&NFA_TABLE[i][symbols]);
check(closure_ar,
buffer);
int
z = closure(closure_ar, states);
// till
closure get completely saturated
while
(z != 100)
{
if
(strcmp(&NFA_TABLE[z][symbols],
"-") != 0) {
strcpy(buffer,
&NFA_TABLE[z][symbols]);
//
call the check function
check(closure_ar,
buffer);
}
closure_ar[z]++;
z
= closure(closure_ar, states);
}
}
// print the e
closure for every states of NFA
printf("\n
e-Closure (%c) :\t",
(char)(65 + i));
bzero((void
*)buffer, MAX_LEN);
state(closure_ar,
states, buffer);
strcpy(&closure_table[i],
buffer);
printf("%s\n",
&closure_table[i]);
}
}
/* To check New States in DFA */
int new_states(struct
DFA *dfa, char S[]) {
int i;
// To check the current state is
already
// being used as a DFA state or
not in
// DFA transition
table
for (i = 0; i <
last_index; i++) {
if
(strcmp(&dfa[i].states, S) ==
0)
return
0;
}
// push the new
strcpy(&dfa[last_index++].states,
S);
// set the count for new states
entered
// to zero
dfa[last_index - 1].count =
0;
return 1;
}
// Transition function from NFA to DFA
// (generally union of closure operation )
void trans(char
S[], int M,
char *clsr_t[], int
st,
char
*NFT[][symbols + 1], char TB[])
{
int len =
strlen(S);
int i, j, k,
g;
int
arr[st];
int sz;
reset(arr, st);
char temp[MAX_LEN],
temp2[MAX_LEN];
char
*buff;
// Transition function from NFA
to DFA
for (i = 0; i <
len; i++) {
j =
((int)(S[i] - 65));
strcpy(temp,
&NFT[j][M]);
if
(strcmp(temp,
"-") != 0) {
sz
= strlen(temp);
g =
0;
while
(g < sz) {
k
= ((int)(temp[g] - 65));
strcpy(temp2,
&clsr_t[k]);
check(arr,
temp2);
g++;
}
}
}
bzero((void
*)temp, MAX_LEN);
state(arr, st, temp);
if (temp[0]
!= '\0') {
strcpy(TB,
temp);
} else
strcpy(TB,
"-");
}
/* Display DFA transition state table*/
void Display_DFA(int
last_index, struct DFA
*dfa_states,
char
*DFA_TABLE[][symbols]) {
int i, j;
printf("\n\n********************************************************\n\n");
printf("\t\t
DFA TRANSITION STATE TABLE \t\t \n\n");
printf("\n
STATES OF DFA :\t\t");
for (i = 1; i <
last_index; i++)
printf("%s,
", &dfa_states[i].states);
printf("\n");
printf("\n
GIVEN SYMBOLS FOR DFA: \t");
for (i = 0; i <
symbols; i++)
printf("%d,
", i);
printf("\n\n");
printf("STATES\t");
for (i = 0; i <
symbols; i++)
printf("|%d\t",
i);
printf("\n");
// display the DFA transition
state table
printf("--------+-----------------------\n");
for (i = 0; i <
zz; i++) {
printf("%s\t",
&dfa_states[i + 1].states);
for (j =
0; j < symbols; j++) {
printf("|%s
\t", &DFA_TABLE[i][j]);
}
printf("\n");
}
}
// Driver Code
int main() {
int i, j,
states;
char
T_buf[MAX_LEN];
// creating an array dfa
structures
struct DFA
*dfa_states = malloc(MAX_LEN *
(sizeof(dfa)));
states = 6, symbols =
2;
printf("\n
STATES OF NFA :\t\t");
for (i = 0; i <
states; i++)
printf("%c,
", (char)(65 +
i));
printf("\n");
printf("\n
GIVEN SYMBOLS FOR NFA: \t");
for (i = 0; i <
symbols; i++)
printf("%d,
", i);
printf("eps");
printf("\n\n");
char
*NFA_TABLE[states][symbols + 1];
// Hard coded input for NFA
table
char
*DFA_TABLE[MAX_LEN][symbols];
strcpy(&NFA_TABLE[0][0],
"FC");
strcpy(&NFA_TABLE[0][1],
"-");
strcpy(&NFA_TABLE[0][2],
"BF");
strcpy(&NFA_TABLE[1][0],
"-");
strcpy(&NFA_TABLE[1][1],
"C");
strcpy(&NFA_TABLE[1][2],
"-");
strcpy(&NFA_TABLE[2][0],
"-");
strcpy(&NFA_TABLE[2][1],
"-");
strcpy(&NFA_TABLE[2][2],
"D");
strcpy(&NFA_TABLE[3][0],
"E");
strcpy(&NFA_TABLE[3][1],
"A");
strcpy(&NFA_TABLE[3][2],
"-");
strcpy(&NFA_TABLE[4][0],
"A");
strcpy(&NFA_TABLE[4][1],
"-");
strcpy(&NFA_TABLE[4][2],
"BF");
strcpy(&NFA_TABLE[5][0],
"-");
strcpy(&NFA_TABLE[5][1],
"-");
strcpy(&NFA_TABLE[5][2],
"-");
printf("\n
NFA STATE TRANSITION TABLE \n\n\n");
printf("STATES\t");
for (i = 0; i <
symbols; i++)
printf("|%d\t",
i);
printf("eps\n");
// Displaying the matrix of NFA
transition table
printf("--------+------------------------------------\n");
for (i = 0; i <
states; i++) {
printf("%c\t",
(char)(65 + i));
for (j =
0; j <= symbols; j++) {
printf("|%s
\t", &NFA_TABLE[i][j]);
}
printf("\n");
}
int
closure_ar[states];
char
*closure_table[states];
Display_closure(states,
closure_ar, closure_table, NFA_TABLE, DFA_TABLE);
strcpy(&dfa_states[last_index++].states,
"-");
dfa_states[last_index - 1].count
= 1;
bzero((void
*)buffer, MAX_LEN);
strcpy(buffer,
&closure_table[0]);
strcpy(&dfa_states[last_index++].states,
buffer);
int Sm = 1, ind =
1;
int start_index =
1;
// Filling up the DFA table with
transition values
// Till new states can be entered
in DFA table
while (ind != -1)
{
dfa_states[start_index].count
= 1;
Sm = 0;
for (i =
0; i < symbols; i++) {
trans(buffer,
i, closure_table, states, NFA_TABLE, T_buf);
//
storing the new DFA state in buffer
strcpy(&DFA_TABLE[zz][i],
T_buf);
//
parameter to control new states
Sm = Sm +
new_states(dfa_states, T_buf);
}
ind =
indexing(dfa_states);
if (ind
!= -1)
strcpy(buffer,
&dfa_states[++start_index].states);
zz++;
}
// display the DFA
TABLE
Display_DFA(last_index,
dfa_states, DFA_TABLE);
return 0;
}