#include /* Define constants for the state of the automata */ #define START 0 #define A 1 #define B 2 #define C 3 #define ESC 4 #define F 5 #define ERROR 6 int main () { int state = START; /* We start at state START */ int c, count = 0; while (1) { /* Read the next character into an integer, c < 0 * means end of input (EOF) */ c = getchar(); count++; if (c < 0) break; /* First distinguish according to state */ switch (state) { case START: switch (c) { case '"': state = A; break; case '\'': state = B; break; default: /* Nothing */ break; } break; case A: switch (c) { case '%': state = F; break; case '\\': state = ESC; break; case '"': state = START; printf ("OK\n"); break; default: /* Nothing */ break; } break; case B: switch (c) { case '\'': state = START; break; case '\\': state = C; break; default: /* Nothing */ break; } break; case C: state = B; break; case ESC: switch (c) { case '"': case '\\': case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v': state = A; break; default: state = ERROR; break; } break; case F: switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* Nothing */ break; case 'd': case 'i': case 'u': case 'x': case 'X': case 'f': case 'e': case 'E': case 'g': case 'G': case 'c': case 'C': case 's': case 'S': case 'p': case 'n': case '\\': state = A; break; default: state = ERROR; break; } break; case ERROR: switch (c) { case '"': state = START; printf ("ERROR\n"); break; default: /* Nothing */ break; } break; default: fprintf (stderr, "Internal error\n"); return 1; } } if (state != START) { printf ("Unterminated\n"); } return 0; } /* Test cases Output ************************************************************************ * '\'' NOTHING * '"' NOTHING * "" OK * "\x" ERROR * "\a%G" OK * "\b%X%10909091901901901839847938745i" OK * "\b%X%3m\a" ERROR * "%m" ERROR * "%3m" ERROR * "% 4i" ERROR * "%4i" OK * "\\" OK * "\"" OK * "\"\\\a\b\f\n\r\t\v%20s" OK * "\"\\\a\b\f\n\r\t\v%a" ERROR * "%d%i%u%x%X%f%e%E%g%G%c%C%s%S%p%1n\v\v\v\v" OK * "%d%i%u%x%X%f%e%E%g%G%c%C%s%S%11111111p%1n\v\v\v\v" OK * "%d%i%u%x%X%f%e%E%g%G%c%C%s%S%11111111p%1n\n\n\n\c" ERROR * %d%i%u%x%X%f%e%E%g%G%c%C%s%S%11111111p%1n\n\n\n\c NOTHING * ""%d%i%u%x%X%f%e%E%g%G%c%C%s%S%11111111p%1n\n\n\n OK * "'"'"'"'"'"'"'" OK (3mal) */