dfa.c

8
/* 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);

Upload: farhan-ahmad

Post on 10-Apr-2015

413 views

Category:

Documents


3 download

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

Page 1: DFA.c

/* 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);

Page 2: DFA.c

}}

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

Page 3: DFA.c

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':

Page 4: DFA.c

{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 :{

Page 5: DFA.c

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;

Page 6: DFA.c

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

}

Page 7: DFA.c

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

Page 8: DFA.c

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