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;
}