int fsm_main(const char *s) { const char *p; enum { S0, S1, S2, S3, S4, S5 } state; state = S0; for (p = s; *p != '\0'; p++) { switch (state) { case S0: /* start */ switch ((unsigned char) *p) { case 'a': case 'z': state = S1; break; default: return -1; /* leaf */ } break; case S1: /* e.g. "a" */ switch ((unsigned char) *p) { case 'a': case 'z': break; case ' ': state = S2; break; case ',': state = S3; break; default: return -1; /* leaf */ } break; case S2: /* e.g. "a " */ switch ((unsigned char) *p) { case ' ': break; case ',': state = S3; break; default: return -1; /* leaf */ } break; case S3: /* e.g. "a," */ switch ((unsigned char) *p) { case 'a': case 'z': state = S4; break; default: return -1; /* leaf */ } break; case S4: /* e.g. "a,a" */ switch ((unsigned char) *p) { case ',': state = S3; break; case 'a': case 'z': break; case ' ': state = S5; break; default: return -1; /* leaf */ } break; case S5: /* e.g. "a,a " */ switch ((unsigned char) *p) { case ',': state = S3; break; case ' ': break; default: return -1; /* leaf */ } break; default: ; /* unreached */ } } /* end states */ switch (state) { case S4: return 0x1; /* "([az]+ *,)+[az]+ *" */ case S5: return 0x1; /* "([az]+ *,)+[az]+ *" */ default: return -1; /* unexpected EOT */ } }