1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
$Id: README,v 1.1.1.1 2004/07/23 19:22:41 tang Exp $
The example fickle code programs are based upon the lex examples found
within "lex & yacc" by John R. Levine, Tony Mason, and Doug Brown (by
O'Reilly & Associates, ISBN 1-56592-000-7). For more information on
using lex and yacc, see http://www.oreilly.com/catalog/lex/.
Run the Makefile to generate resulting Tcl code. Descriptions of
individual files are below. The reader is assumed to have a familiarity
with flex; if not consider purchasing the aforementioned book.
cat.fcl
-------
This is the simplest fickle example possible. It copies its input (from
stdin) to output (stdout), much like the cat(1) program does without any
arguments. Note that one must explicitly call yylex to run the lexer.
verbs.fcl
---------
This examples demonstrates a verbatim section (the text between '%{'
and '%}'). Also note how fickle specification files may have
Tcl-style comments embedded within. This program searches its input
for various English verbs and copies it to the output. The program
makes use of the variable $yytext (really just an upvar'ed version of
the global ::yytext variable) to print out the text that matched.
wc.fcl
------
This program will count the number of characters, words, and lines in
its input, much like wc(1). Called without any arguments, wc.tcl reads
from stdin; it reads from a file if given an argument. Unless otherwise
specified, 'yyin' points to stdin and 'yyout' to stdout. Overriding
these variables forces the lexer to read from another stream. This
program also uses $yyleng (an upvar'ed version of ::yyleng) which is
set to [string length $::yytext].
wc2.fcl
-------
This example supports multiple filenames. With more than one argument,
wc2 will print a report for each line and a summary line totalling all
metrics. No summary is displayed given zero or one argument.
wc2 handles multiple files by overriding the definition for yywrap.
yywrap returns 0 when additional files need to be processed.
The directive `%option noheaders' causes fickle to not include
comments about the autogenerated functions within wc2.tcl. Note the
difference in size between wc2.tcl and wc.tcl.
cl.fcl
------
This example demonstrates how to feed the lexer input from a source
other than a file -- in this case, the command line. One must rewrite
YY_INPUT to use the alternative source. The first parameter should be
'upvar'ed; it holds the next string to scan. 'result' should be the
size of the buffer, or zero to indicate an end of file; this too needs
to be 'upvar'ed. The final parameter indicates the maximum allowed
buffer size. By default this is 1024; use the `%option buffersize'
directive to change this amount.
Also note the use of `%option nodefault'. By default fickle will
write to yyout any unmatched input through the ECHO function. Use
`%option nodefault' to abort the program upon unmatched input; this is
useful during debugging sessions. One can also invoke this
suppression behavior with the `-s' flag on the fickle command line.
csa.fcl
-------
The next example is a C source analyzer. It takes a single C source
file as a parameter; it then counts the lines of code, comments, and
whitespace within.
This example demonstrates the start state feature of fickle, enabled
through the directive `%option stack'. fickle supports both exclusive
start states (as indicated by '%x') as well as regular start states
('%s', though not featured in this program). Start states specify
when a pattern is allowed. Switch states through calls to 'BEGIN',
'yy_push_state', and 'yy_pop_state'.
The initial state is called, not surprisingly, 'INITIAL'. Unlike flex,
'BEGIN 0' and 'BEGIN INITIAL' are not identical. To match all states,
prepend the pattern with '<*>'. Patterns that have no state listed are
defaulted to matching only INITIAL and any regular start state.[*]
Note that if multiple patterns match the input, the largest match takes
precedence. In case of a tie the pattern appearing earlier within the
specification file wins.
[*] Regular start states are a source of much confusion and are rarely
useful. Avoid them like the plague.
tsa.fcl
-------
In comparison to the above this program instead analyzes Tcl code.
It's not particularly foolproof but does get the job done.
|