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