four06% cat -n scan.c 1 /* scan.c: scanner implementation. 2 * Recognizes C-type comments 3 * Based on a finite-state automaton. 4 * Uses gotos for implementation. 5 */ 6 #include 7 #include 8 #include 9 #include "scan.h" 10 char * makestr(char ch); 11 void scan(char *s) 12 { 13 14 char ch; 15 strcpy(s, "/*"); 16 17 18 L0: ch = getchar(); 19 if (ch == '/') goto L1; 20 else goto L0; 21 L1: ch = getchar(); 22 if (ch == '*') goto L2; 23 else goto L0; 24 L2: ch = getchar(); 25 strcat(s, makestr(ch)); 26 if (ch == '*') goto L3; 27 else goto L2; 28 L3: ch = getchar(); 29 strcat(s, makestr(ch)); 30 if (ch == '*') goto L3; 31 else if (ch == '/') goto L4; 32 else goto L2; 33 L4: return; 34 } 35 36 37 /* makestr: convert a char to a string */ 38 char *makestr(char ch) 39 { 40 char *r = (char *) malloc(2); 41 r[0] = ch; 42 r[1] = '\0'; 43 return r; 44 } four06% cat -n scan.h 1 /* scan.h: scanner header file */ 2 void scan(char *s); four06% cat -n comment.c 1 /* comment.c: driver to test comment scanner */ 2 #include 3 #include 4 #include "scan.h" 5 void main(void) 6 { 7 char s[50]; 8 for ( ; ; ) { 9 scan(s); 10 printf("Next comment:\"%s\"\n", s); 11 if (strcmp(s, "/*quit*/") == 0) break; 12 } 13 } four06% cat -n scan2.c 1 /* scan2.c: scanner implementation. 2 * Recognizes C-type comments 3 * Based on a finite-state automaton. 4 * No gotos in this version, but state variable instead. 5 */ 6 #include 7 #include 8 #include 9 #include "scan.h" 10 char * makestr(char ch); 11 void scan(char *s) 12 { 13 int state = 0; 14 char ch; 15 strcpy(s, "/*"); 16 while (state != 4) { 17 switch (state) { 18 case 0: ch = getchar(); 19 if (ch == '/') state = 1; 20 else state = 0; break; 21 case 1: ch = getchar(); 22 if (ch == '*') state = 2; 23 else state = 0; break; 24 case 2: ch = getchar(); 25 strcat(s, makestr(ch)); 26 if (ch == '*') state = 3; 27 else state = 2; break; 28 case 3: ch = getchar(); 29 strcat(s, makestr(ch)); 30 if (ch == '*') state = 3; 31 else if (ch == '/') state = 4; 32 else state = 2; break; 33 case 4: return; break; 34 } /* end of switch */ 35 } /* end of while */ 36 } 37 /* makestr: convert a char to a string */ 38 char *makestr(char ch) 39 { 40 char *r = (char *) malloc(2); 41 r[0] = ch; 42 r[1] = '\0'; 43 return r; 44 } four06% cc -o comment2 comment.c scan2.c four06% cat comment.source x = 47 / 13 * 12; /**/ /***/ /****/ /*/ ?? * / */ /* abc; */ /* over two lines */ JUNK! 3.14159; /*quit*/ four06% comment2 < comment.source Next comment:"/**/" Next comment:"/***/" Next comment:"/****/" Next comment:"/*/ ?? * / */" Next comment:"/* abc; */" Next comment:"/* over two lines */" Next comment:"/*quit*/"