home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / c-kermit / ckwart.txt < prev    next >
Text File  |  2020-01-01  |  5KB  |  111 lines

  1. WART
  2.  
  3. Wart is a program that implements a small subset of the Unix 'lex' lexical
  4. analyzer generator.  Unlike lex, wart may be distributed without requirement
  5. for a Unix license.  Wart was written in 1985 by Jeff Damens at the Columbia
  6. University Center of Computing Activities to facilitate development of Unix
  7. Kermit, and modified over the ensuing years by Frank da Cruz.
  8.  
  9. Wart is intended for production of state table switchers.  It allows a set of
  10. states to be defined, along with a function for getting input, and a table of
  11. state transitions.  A C program is generated which performs actions and
  12. switches states based on the current state and the input.
  13.  
  14. The following short program demonstrates some of the capabilities and
  15. limitations of Wart.  The program accepts from the command line a binary
  16. number, preceded by an optional minus sign, and optionally containing a
  17. fractional part.  It prints the decimal equivalent.
  18.  
  19. #include <stdio.h>
  20.  
  21. int state, s = 1, m = 0, d;
  22. float f;
  23. char *b;
  24.  
  25. /* Declare wart states */
  26. %states sign mantissa fraction
  27.  
  28. %%                        /* Begin state table */
  29. <sign>-      { s = -1; BEGIN mantissa; }    /* Look for sign */
  30. <sign>0      { m = 0;  BEGIN mantissa; }    /* Got digit, start mantissa */
  31. <sign>1      { m = 1;  BEGIN mantissa; }
  32. <sign>.      { fatal("bad input"); }        /* Detect bad format */
  33. <mantissa>0  { m *= 2; }            /* Accumulate mantissa */
  34. <mantissa>1  { m = 2 * m + 1; }
  35. <mantissa>$  { printf("%d\n", s * m); return; }
  36. <mantissa>.  { f = 0.0; d = 1; BEGIN fraction; }    /* Start fraction */
  37. <fraction>0  { d *= 2; }                    /* Accumulate fraction */
  38. <fraction>1  { d *= 2; f += 1.0 / d; }
  39. <fraction>$  { printf("%f\n", s * (m + f) ); return; }
  40. <fraction>.  { fatal("bad input"); }
  41. %%
  42.  
  43. input() {                    /* Define input() function */
  44.     int x;
  45.     return(((x = *b++) == '\0') ? '$' : x );
  46. }
  47.  
  48. fatal(s) char *s; {                /* Error exit */
  49.     fprintf(stderr,"fatal - %s\n",s);
  50.     exit(1);
  51. }
  52.  
  53. main(argc,argv) int argc; char **argv; {    /* Main program */
  54.     if (argc < 2) exit(1);
  55.     b = *++argv;
  56.     state = sign;                /* Initialize state */
  57.     wart();                    /* Invoke state switcher */
  58.     exit(0);                    /* Done */
  59. }
  60.  
  61. The wart program accepts as input a C program containing lines that start
  62. with "%" or a section delimited by "%%" (there can be only one such section).
  63. The directive "%states" declares the program's states.  The section enclosed
  64. by "%%" markers is the state table, with entries of the form
  65.  
  66.   <state>X { action }
  67.  
  68. which is read as "if in state <state> with input X perform { action }"
  69.  
  70. The optional <state> field tells the current state or states the program must
  71. be in to perform the indicated action.  If no state is specified, then it
  72. means the action will be performed regardless of the current state.  If more
  73. than one state is specified, then the action will be performed in any of the
  74. listed states.  Multiple states are separated by commas.
  75.  
  76. The required input field consists of a single literal printable 7-bit ASCII
  77. character (i.e. in the range 32 through 126).  Control characters and 8-bit
  78. characters are not allowed.  This is to prevent the state-table array (whose
  79. size is the product of the number of states and the number of possible input
  80. characters) small enough to be handled by any C compiler.
  81.  
  82. When in the indicated state, if the input is the specified character, then the
  83. associated action is performed.  The character '.' matches any input
  84. character.  No pattern matching or range notation is provided.  The input
  85. character is obtained from the input() function, which you must define.  It
  86. should be alphanumeric, or else one of the characters ".% -$@" (quotes not
  87. included).  Note that the program above recognizes the binary point '.'
  88. through a ruse.
  89.  
  90. The action is a series of zero or more C language statements, enclosed in
  91. curly braces (even if the action consists of only one statement).
  92.  
  93. The BEGIN macro is defined simply to be "state = ", as in lex.
  94.  
  95. The wart() function is generated by the wart program based on the state
  96. declarations and the state transition table.  It loops through calls to
  97. input(), using the result to index into a big case statement it has created
  98. from the state table.
  99.  
  100. The wart program is invoked as follows:
  101.  
  102.     wart          (Input from stdin, output to stdout)
  103.  
  104.     wart fn1      (Input from fn1, output to stdout)
  105.  
  106.     wart fn1 fn2  (Input from fn1, output to fn2.  Example:  wart a.w a.c)
  107.  
  108. Wart programs have the conventional filetype '.w'.
  109.  
  110. - F. da Cruz, Columbia University, November 1991
  111.