|
|
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.