home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_07_03 / v7n3102a.txt < prev    next >
Text File  |  1989-03-17  |  3KB  |  161 lines

  1. #include "fsm.h"
  2.  
  3.  
  4. /* Preamble */
  5.  
  6.    #include <stdio.h>
  7.    /* action functions used by this machine */
  8.    void echo(void), skip(void), secho(void);
  9.    void markg(void), ngmark(void), zero(void);
  10.    void smarkg(void), tally(void);
  11.  
  12.    /* prototype for the scanner */
  13.    int next_token(void);
  14.    
  15.    static int lex_val;
  16.    static int count; /* how many spaces have I seen */
  17.  
  18. typedef int FSMTYPE;
  19.  
  20.  
  21. /*Defines for Symbol names*/
  22. #define empty 0
  23. #define cap 1
  24. #define space 2
  25. #define fend 3
  26. #define nl 4
  27. #define other 5
  28.  
  29.  
  30. /* Defines for State Names */
  31. #define start 0
  32. #define setext 1
  33. #define sespc 2
  34. #define secode 3
  35. #define lnewg 4
  36. #define ngmark 5
  37.  
  38.  
  39. /*Transition Table*/
  40. struct trans s_table[][6] = {
  41.  
  42.   { /*start*/ {forbid,fault}, {setext,echo}, {start,  skip}, {stop,skip}, {start,skip},  {setext, echo}},
  43.  
  44.   { /*setext*/{forbid,fault}, {setext,echo}, {sespc,  skip}, {stop,skip}, {lnewg,echo},  {setext, echo}},
  45.  
  46.   { /*sespc*/ {forbid,fault}, {setext,secho},{sespc,  skip}, {stop,skip}, {lnewg,echo},  {setext,secho}},
  47.  
  48.   { /*secode*/{forbid,fault}, {secode,echo}, {secode, echo}, {stop,skip}, {lnewg,echo},  {secode, echo}},
  49.  
  50.   { /*lnewg*/ {forbid,fault}, {setext,echo}, {ngmark,tally}, {stop,skip}, {ngmark,zero}, {setext, echo}},
  51.  
  52.   { /*ngmark*/{forbid,fault}, {setext,markg},{ngmark,tally}, {stop,skip}, {ngmark,zero}, {secode,smarkg}}
  53.  
  54.   };
  55.  
  56. static int state, token;
  57.  
  58. /* Code for main()*/
  59. FSMTYPE main()
  60. {
  61. state = start;
  62. token = EMPTY;
  63.  
  64. while (state != stop){
  65.   TRACE;
  66.   token = next_token();
  67.   (*s_table[state][token].act)();
  68.   state = s_table[state][token].nextstate;
  69.   }
  70. return 0;
  71. }
  72.  
  73.  
  74. /* Code Section */
  75.  
  76. /* a nasty kludge to get end of line markers */
  77. void putcr(c)
  78. int c;
  79. {
  80. switch (c){
  81.   case '\n': putchar(0x0d);
  82.              putchar(0x0a);
  83.              break;
  84.   case 0x0d: break;
  85.   default:   putchar(c);
  86.   }
  87. }
  88.  
  89. int next_token()
  90. {
  91. do {
  92.    switch (lex_val=getchar()){
  93.      case '-':  return cap;
  94.      case ' ':  return space;
  95.      case 0x0a: lex_val = '\n';
  96.                 return nl;
  97.      case 0x0d: break; 
  98.         /*avoids 0d 0d 0a output */
  99.      case EOF:  lex_val = 0x1a;
  100.                 return fend;
  101.      default:   if (toupper(lex_val) == lex_val) return cap;
  102.                 else return other;
  103.      }
  104.    } while (lex_val == 0x0d);
  105. return forbid;
  106. }
  107.  
  108.  
  109. void skip()
  110. { return; }
  111.  
  112. void echo()
  113. {
  114. #ifdef DEBUG
  115. if ((lex_val < ' ') || (lex_val > 'z')) putchar ('.');
  116. else putchar(lex_val);
  117. printf(" %2.2x",lex_val);
  118. #endif
  119. putcr(lex_val );
  120. count = 0;
  121. }
  122.  
  123. void tally()
  124. {
  125. count += 1;
  126. }
  127.  
  128. void markg()
  129. {
  130. putcr('\n' );
  131. putchar(lex_val );
  132. count = 0;
  133. }
  134.  
  135. void smarkg()
  136. {
  137. putcr('\n' );
  138. while(count--) putchar(' ' );
  139. putchar(lex_val );
  140. count = 0;
  141. }
  142.  
  143. void zero()
  144. {
  145. count = 0;
  146. }
  147.  
  148.  
  149. void secho()
  150. {
  151. putchar(' ' );
  152. putcr(lex_val );
  153.  
  154. #ifdef DEBUG
  155. printf(" %x", lex_val);
  156. #endif
  157.  
  158. count = 0;
  159. }
  160.  
  161.