0% found this document useful (0 votes)
658 views16 pages

NFA2DFA C

C program for converting an NFA into equivalent DFA. Does not work for epsilon NFAs. Requires NFAparse.c for reading from the input file and NFA2DFA(.txt) -- input file.

Uploaded by

farhanhubble
Copyright
© Public Domain
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
658 views16 pages

NFA2DFA C

C program for converting an NFA into equivalent DFA. Does not work for epsilon NFAs. Requires NFAparse.c for reading from the input file and NFA2DFA(.txt) -- input file.

Uploaded by

farhanhubble
Copyright
© Public Domain
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 16

/* C program for NFA to DFA conversion */

/* Author: Ahmad Farhan <[email protected]> */


/* Date 2010-AUG-10 */
/* Versio 0.0 */
/* This program does not perform epsilon-NFA to DFA conversion */

/** Important:
Dependencies: requires NFA2DFA.c (this file) and NFAparse.c
Compilation: use gcc NFA2DFA.c -o <output_file_name> -std=c99
Input: file NFA2DFA.txt is required at runtime. This file holds t
he transition table,list of input sy
mbols and list of final states in a special format.
*/

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include"NFAparse.c"

int* _union(int* ,int* );


int candidateFinal(int *,int **,int);
int*** convert(int ***,int ***,int ,int *,char*);
void displayTable(int*** ,char *,int **,int , int);
int duplicate(int**,int,int*);
int exists(int *,int ,int);
int* getStateList(char* ,int* );
void Isort(int *);
void prt(int *);
int readNum(char *, int* );

int main(int argc, char** argv)


{
const char filename[] = "NFA2DFA.txt";
char *buffer = NULL;
int ***transition = NULL; /* Function delata:(Q,si
gma) --> P(Q) ; P = powerset */
char *input = NULL; /* Set sigma */
int **final = NULL; /* Set F */
int **states = NULL; /* Set Q */
int nInput;
int nFinal;
int nState;
int nbytes,ntries;
buffer = readFile(filename,&nbytes,&ntries);

puts("\n");
printf("%d bytes read from file %s in %d reads.",nbytes,filename
,ntries);
puts("\n----------Buffer dump----------");
puts(buffer);
puts("\n----------End of dump----------");

/* Read the input symbols */


int i = 0;
nInput = 0;
int EOLflag = 0;
while(1)
{
switch(buffer[i])
{
case EOF:
{
printf("\nUnexpe
cted end of file at index %d\n",i);
exit(1);
}
case ' ':
{
break;
}
case ',':
{
break;
}
case '\n':
{
EOLflag = 1;
break;
}
default:
{
if(!isalpha(buff
er[i]))
{
printf("\nUnexpected character %c encoutered, while scanning for input symbols\n
",buffer[i]);
exit(1);
}
input = (char*)r
ealloc(input,sizeof(char)*(nInput +1 ));
input[nInput] =
buffer[i];
nInput++;
}
}
if(EOLflag)
{
break;
}
++i;
}

printf("\n%d input symbols found: ",nInput);

/* Print all input symbols */


for(int j=0;j<nInput;j++)
{
printf(" %c ",input[j]);
}
printf("\n");

/* read all transitions */


nState = 0;
int col;
int hashFlag = 0;
while(1)
{
/* printf(" %c ",buffer[i]); */
switch(buffer[i])
{
case EOF:
{
printf("\nUnexpe
cted end-of-file while reading transition table\n");
exit(1);
}
case '#':
{
hashFlag = 1;
break;
}
case ' ':
{
break;
}
case ',':
{
break;
}
case ':':
{
transition = (in
t***)realloc(transition,sizeof(int**)*(nState+1));
transition[nStat
e] = (int**)malloc(sizeof(int*)*(nInput));
col=0;
nState++;
break;
}
case '\n':
{
break;
}
default :
{
if( !(isdigit(bu
ffer[i]) || buffer[i] == '-' ) )
{
printf("\nUnexpected character %c ",buffer[i]);
exit(1);
}

/* Extract the l
ist of states */
transition[nStat
e-1][col] = getStateList(buffer,&i);
col++;
}

} /* End of switch() */
if(hashFlag)
{
break;
}
++i;
} /* End of while() */

/* Read list of final states */


int endFlag = 0;
nFinal = 0;
while(1)
{
switch(buffer[i])
{
case ' ':
{
break;
}
case ',':
{
break;
}
case '#':
{
break;
}
case '\n':
{
endFlag = 1;
break;
}
case EOF:
{
endFlag = 1;
break;
}
default:
{
if(!isdigit(buff
er[i]))
{
printf("\nWarning: Unexpected symbol %c",buffer[i]);
break;
}
final = (int**)r
ealloc(final,sizeof(int*)*(nFinal+1));
final[nFinal] =
(int*)malloc(sizeof(int)*2);
final[nFinal][0]
= 1;
final [nFinal][1
] = readNum(buffer,&i);
nFinal++;
}
}
if(endFlag)
{
break;
}
i++;
} /* end of while() */
printf("\nFinal state(s) ");
for(int i=0;i<nFinal;i++)
{
printf("[");
for(int j=1;j<=final[i][0];j++)
{
printf(" %d ",final[i][j]);
}
printf("]");
}
printf("\n");

/* Store all states present in the NFA, in a 2-D array


* Each row stores state(s), part of a single\multi-state.
* First element in each row is the count of states on that row.
* follwed by the member state(s) *
*/
states = (int**)realloc(states,sizeof(int*)*nState);
for(int i=0;i<nState;i++)
{
states[i] = (int*)malloc(sizeof(int)*2);
states[i][0] = 1;
states[i][1] = i;
}

/* Print the NFA transition table */


printf("--------------------------------");
printf("\n NFA Transition Table ");
printf("\n--------------------------------\n");
displayTable(transition,input,states,nInput,nState);

int tmp1 = nState;


/* Convert to DFA */
transition = convert(transition,&states,nInput,&nState,input);

/* Update list of final states */


int tmp2 = nFinal;
for(int i=tmp1;i<nState;i++)
{
if( candidateFinal(states[i],final,tmp2) )
{
final = (int**)realloc(final,siz
eof(int*)*(nFinal+1));
final[nFinal] = (int*)malloc(siz
eof(int)*states[i][0]);
for(int j=0;j<=states[i][0];j++)
{
final[nFinal][j]
= states[i][j];
}
nFinal++;
}
}

/* Print DFA transition table */


printf("--------------------------------");
printf("\n DFA Transition Table ");
printf("\n--------------------------------\n");
displayTable(transition,input,states,nInput,nState);
printf("\nFinal state(s) ");
for(int i=0;i<nFinal;i++)
{
printf("[");
for(int j=1;j<=final[i][0];j++)
{
printf(" %d ",final[i][j]);
}
printf("]");
}
printf("\n");
return 0;
}

/* Convert a list of '/' separated strings into signed numbers */


int *getStateList(char* buf,int *indexPtr)
{
int *returnVector = (int*)malloc(sizeof(int));
int count = 1;

while(1)
{
if( isdigit(buf[*indexPtr]) || buf[*indexPtr
] == '-' )
{
returnVector = (int*)realloc(
returnVector,sizeof(int)*(count+1) );
returnVector[count] = readNum(bu
f,indexPtr);
count++;
}
else if( buf[*indexPtr] == ' ' || buf[*in
dexPtr] == '\n' || buf[*indexPtr] == ',' )
{
(*indexPtr)--;
break;
}

else if( buf[*indexPtr] == '/' )


{
/* Skip over any forward slashes
*/
}
else
{
printf("\nWarning. getStateList(
):Unexpected character %c will be skipped\n",buf[*indexPtr]);
}
(*indexPtr)++;
}
/* Store number of states as first element */
returnVector[0] = count-1;

#ifdef __DEBUG
printf("\n%d states are ",count-1);
for(int i =1;i<count;i++)
{
printf (" %d ",returnVector[i]);
}
printf("\n");
#endif
return returnVector;
}

/* Converts a string to signed integer */


int readNum(char *array,int *indexPtr)
{
int sign = 1;
int magnitude;
/* Detect sign */
if(array[*indexPtr] == '-')
{
sign = -1;
(*indexPtr)++;

}
/* Detect magnitude */
magnitude = 0;
while(array[*indexPtr] >= 48 && array[*indexPtr]<= 57)
{
magnitude = magnitude * 10 + array[*indexPtr] - 48;
(*indexPtr)++;
}
(*indexPtr)--; /* Unget last character read from buffer */

return (sign*magnitude);
}

/* Print transition table */


void displayTable(int ***table,char *symArray,int **states,int ncols, int nrows)
{
for(int i=0;i<ncols;i++)
{
printf("\t %c",symArray[i]);
}
printf("\n");
int count;
for(int i=0;i<nrows;i++)
{
for(int o=1;o<=states[i][0];o++)
{
printf("%d ",states[i][o]);
}
for(int j=0;j<ncols;j++)
{
count = table[i][j][0];

printf("\t");
for(int k=1;k<=count;k++)
{
printf(" %d ",ta
ble[i][j][k]);
}

}
printf("\n");
}
}
/* Convert an NFA to equivalent DFA */
int*** convert(int ***table,int ***ptrStates,int nsymbol,int *ptrNstate,char *in
)
{
int i,j,k;
int *uarray ;
int a;
int b;

for(i=0;i<*ptrNstate;i++)
{
for(j=0;j<nsymbol;j++)
{
/* If a multi-state is found */
int count = table[i][j][0];
if( count > 1
)
{
if(duplicate(*pt
rStates,*ptrNstate,table[i][j])) continue;
/* Add a row to
transition table and state list */
table = (int***)
realloc( table,sizeof(int**)*(*ptrNstate + 1));
table[*ptrNstate
] = (int**)malloc(sizeof(int*)*(nsymbol));
(*ptrStates) = (
int**)realloc ( (*ptrStates),sizeof(int*)*(*ptrNstate + 1));
(*ptrStates)[*pt
rNstate] = (int*)malloc(sizeof(int)*(*ptrNstate));

/*Copy multistat
e to state list */
for(k=0;k<=nsymb
ol;k++)
{
(*ptrStates)[*ptrNstate][k] = table[i][j][k];
}

/* Compute trans
itions for new multi-state */

for(a=0;a<nsymb
ol;a++) /* for every input symbol */
{
uarray = NULL;

for(b=1;b<=count;b++) /* for every state in this multi-state */


{
int s = (*ptrStates)[*ptrNstate][b];

#ifdef __DEBUG
printf("\n---------------------------------------");
printf("\nSending array 1>>>>");
prt(uarray);
printf("\n");
printf("Sending array 2>>>> ");
prt(table[s][a]);
printf("\n");
#endif

uarray = _union(uarray,table[s][a]);

#ifdef __DEBUG
printf("Got Union array>>>> ");
prt(uarray);
printf("\n-----------------------------------------\n");
#endif

Isort(uarray);
table[*ptrNstate][a] = uarray;
}

#ifdef __DEBUG
displayTable(tab
le,in,*ptrStates,nsymbol,*ptrNstate);
printf("\nPress
any key to continue");
getchar();
#endif
(*ptrNstate)++;
} /* end of if() */
} /* end of for() */
} /* end of far */

/* Update list of final states */

return table;
}

/* Perform union on two vectors*/


int *_union(int* arr1,int* arr2)
{
int *result;
if(arr1 == NULL)
{
result = (int*)malloc(sizeof(int)*(arr2[0]+1));
result[0] = arr2[0] ;
for(int i=1;i<=arr2[0];i++)
{
result[i] = arr2[i];
}
}
else if(arr2 == NULL)
{
result = (int*)malloc(sizeof(int)*(arr1[0]+1));
result[0] = arr1[0];
for(int i=1;i<=arr1[0];i++)
{
result[i] = arr1[i];
}
}

else
{
result = (int*)malloc(sizeof(int)*(arr1[0] + arr
2[0] + 1 ));
result[0] = arr1[0] + arr2[0];
int i;
/* copy all elements from arr1[] */
for(i=1;i<=arr1[0];i++)
{
result[i] = arr1[i];
}

/* copy elements from arr2[], not already copied


from arr1[] */
for(int j=1;j<=arr2[0];j++)
{
if(!exists(arr1,arr2[j],arr1[0])
)
{
result[i] = arr2
[j];
i++;
}
else
{
result[0]--;
}
}

if(result[0] > 1)
{
for(int c= result[1] ;c<=result[
0];c++)
{
if(result[c] ==
-1)
{
for(int d = c;d<result[0];d++)
{
result[d] = result[d+1];
}

result[0]--;
}
}
}

}
return result;
}

/* Look for a value in a vector */


int exists(int *a,int v,int max)
{
int r = 0;
for(int i=1;i<=max;i++)
{
if(a[i] == v)
{
r = 1;
break;
}
}
return r;
}

/* Print a vector */
void prt(int *a)
{
if(a==NULL) {
printf(" = NULL");
return;
}
int count = a[0];
int i = 1;
while(i<=count)
{
printf(" %d ",a[i]);
i++;
}
}

/* Look for state 'b' in list 'a' */


int duplicate(int **a,int max,int *b)
{
int ret = 0;
int i,j;
int diff;
for(i=0;i<max;i++)
{
diff = 0;
for(j=0;j<=a[i][0];j++)
{
if(a[i][j] != b[j])
{
diff = 1;
break;
}
}
if(diff == 0)
{
ret = 1 ;
break;
}
}
return ret;
}

/* Insertion sort a vector */


void Isort(int *l)
{
int i;
int j;
int k;
int count = l[0];
int tmp;

for(i=1;i<=count;i++)
{
tmp = l[i];
j=i-1;
while(l[j] > tmp && j>0 )
{
j--;
}
for(k=i-1;k>j;k--)
{
l[k+1] = l[k];
}
l[j+1] = tmp;

}
}

/* Test if a state is a valid final state */


int candidateFinal(int *testV,int **list,int max)
{
int ret = 0;
int i,j;
int lookfor;

for(i=0;i<max;i++)
{
lookfor = list[i][1]; /* The only element */
for(j=1;j<=testV[0];j++)
{
if(testV[j] == lookfor)
{
ret = 1;
break;
}
}
}
return ret;
}

You might also like