dfa.c
DESCRIPTION
C program for simulating a DFA. The input DFA must be stored in the file "automata.txt". Download 'automata.txt' for correct format.TRANSCRIPT
/* C program for simulating a Deterministic Finite Automata *//* Author: Ahmad Farhan *//* Aug-04-2010 *//* See automata.txt for DFA table format */
#include<stdio.h>#include<stdlib.h>#include<string.h>
int readNum(char *,int *);int isFinal(int *,int ,int );int getNext(int **, char *,int ,int , char );
const int BUFSZ = 256;
int main(){
FILE *fp;const char *filename = "automata.txt";char *buffer = NULL;char *input = NULL;int **transition = NULL;int *final = NULL;char string[100];
fp = fopen(filename,"rb"); /* `binary` mode for compatibility with non-POSIX systems */
if(!fp){
perror(filename);exit(1);
}
/* Read `file` into `buffer` */
int count = 1;int nread;int nbytes = 0;
while(1){
buffer = (char*)realloc(buffer,sizeof(char)*BUFSZ*count);nread = fread(buffer+nbytes*sizeof(char),1,sizeof(char)*BUFSZ,fp);nbytes += nread;
if(feof(fp)) break;if(nread == 0) /* Error or end of file */{
if (ferror(fp)){
perror(filename);fclose(fp);exit(1);
}}
count++;
}
printf("\n%d bytes read from file %s in %d read(s).",nbytes,filename,count);puts("\n");puts("----Buffer Dump----");puts("\n");puts(buffer);puts("\n");puts("----End of Buffer Dump----");puts("\n");
fclose(fp);
/* Generate a DFA from the transition table */
/* Read all input symbols */
int nInput = 0;int flag = 0; int i = 0;
while(1){
switch(buffer[i]){
case EOF:{
printf("\nUnexpected end of file.");printf("\n");exit(1);
}
case '\n':{
flag = 1;break;
}
case ' ':{
break;}
case ',':{
break;}
default:{
input = (char*)realloc(input,sizeof(char)*(nInput+1));
input[nInput] = buffer[i];nInput++;
}}
if(flag){
break;}
i++;}
printf("%d Input symbols were found",nInput);
/* Read the entire transition table */flag = 0;int nState = 0;int to;
while(1){
switch(buffer[i]){
case '#':{
flag = 1;break;
}
case ':':{
transition = (int**)realloc(transition, sizeof(int*)*(nState+1));transition[nState] = (int*)malloc(sizeof(int)*nInput);nState++;to = 0;break;
}
case EOF:{
puts("\nUnexpected end of file while reading transition table");puts("\n");exit(1);
}
case ' ':{
break;}
case ',':{
break;}
case '\n':
{break;
}
default:{
transition[nState-1][to] = readNum(buffer,&i);to++;i--; /* Compensate for i++ below */
}
}
if(flag) break;i++;
}printf("\n%d State were found in the transition table",nState);
/* Read all final states */flag = 0;int nFinal = 0;
while(1){
switch(buffer[i]){
case '#':{
break;}
case ' ':{
break;}
case ',':{
break;}
case '\n':{
flag = 1;break;
}
case EOF:{
flag = 1;break;
}
default :{
final = (int*)realloc(final,sizeof(int)*(nFinal+1));final[nFinal] = readNum(buffer,&i);nFinal++;i--;
}}
if(flag) break;
i++;}
printf("\n%d final state were found",nFinal);
/* Print the DFA in tabular form */puts("\n\n");puts("***TRANSITION TABLE ***");for(int j =0;j<nInput;j++){
printf("%6c",input[j]);}
for(int j=0;j<nState;j++){
printf("\n%d:",j);
for(int k=0;k<nInput;k++){
printf("%6d",transition[j][k]);}
}
puts("\nFINAL STATE(S)");
for(int j =0 ;j<nFinal;j++){
printf(" %d ",final[j]);}
/* Parse the input string */
while(1){
int flag = 0;
for(;;){
puts("\n");puts("\n1. Continue");puts("\n2. Quit");
int ch;scanf("%d",&ch);if(ch == 1)break;
else if(ch==2){
flag = 1;break;
}}
if(flag){
break;}
printf("\nEnter a string to parse>>");scanf("%s",string);
int current = 0;int z=0;int next = -1;
for(z=0; string[z]!='\0'; z++){
next = getNext(transition,input,nInput,current,string[z]);
if(next == -1){
printf("Parsing failed for string[%d] = %c",z,string[z]);break;
}
else {
current = next;}
}
if(string[z] == '\0'){
if(isFinal(final,nFinal,current)){
printf("\nString Successfully parsed");}
else {
printf("\nParsing failed. Last state = %d",current);}
}
}
printf("\n");return (EXIT_SUCCESS);
}
int readNum(char *array,int *indexPtr){
int sign = 1;int magnitude;
/* Detect sign */if(array[*indexPtr] == '-'){
sign = -1;(*indexPtr)++;
}
/* Detect magnitude */
magnitude = array[*indexPtr] - 48;(*indexPtr)++;
while(array[*indexPtr] >= 48 && array[*indexPtr]<= 57){
magnitude = magnitude * 10 + array[*indexPtr] - 48;(*indexPtr)++;
}
return (sign*magnitude);}
int getNext(int **table, char *inputSet,int nInput,int currentState, char symbol){
int Index = -1;int next;
for(int i=0; i<nInput;i++){
if(inputSet[i] == symbol){
Index = i;break;
}}
/* String has invalid symbol */
if ( Index == -1){
next = -1;}
else{
next = table[currentState][Index];}
return next;}
int isFinal(int *final,int nFinal,int currentState){
for(int i =0 ;i<nFinal;i++){
if(final[i] == currentState){
return 1;}
}
return 0;}