summaryrefslogtreecommitdiff
path: root/support/splint/cweb/fo.w
diff options
context:
space:
mode:
Diffstat (limited to 'support/splint/cweb/fo.w')
-rw-r--r--support/splint/cweb/fo.w185
1 files changed, 147 insertions, 38 deletions
diff --git a/support/splint/cweb/fo.w b/support/splint/cweb/fo.w
index 81694024c3..d34ca57d96 100644
--- a/support/splint/cweb/fo.w
+++ b/support/splint/cweb/fo.w
@@ -30,14 +30,23 @@
@q PURPOSE. @>
@**The \ifbootstrapmode flex \else\flex\ \fi parser stack.
-\ifbootstrapmode % this is a bootstrap run to generate the tables
+\ifbootstrapmode % this is a bootstrap run to generate the token references
\input limbo.sty
\def\optimization{5}
\input yy.sty
+ \def\bstrapparser{dyytab.tex}% use the full prologue parser
+ \def\bstraptokens{bo.tok}% for which we will need token equivalences
\modebootstrap
\else % otherwise set up the pretty printing of tokens
\let\hostparsernamespace\flexnamespace
\fi
+% we can get away with the setup above because the minimal lexer
+% used for bootstrapping does not know about the \prodstyle{\%left}
+% token so in the declarations list below, the two tokens,
+% \prodstyle{CCL_OP_DIFF} and \prodstyle{CCL_OP_UNION} become
+% part of the previous \prodstyle{\%token} declaration which is a
+% legal declaration syntax; see ldman.w and ldlex.w and ldgram.w for
+% a more elaborate setup;
The scanner generator, \flex, uses \bison\ to produce a parser for its
input language. Its lexer is output by \flex\ itself so both are
reused to generate the parser and the scanner for pretty printing
@@ -69,7 +78,7 @@ any custom adjustments to the lexer state to operate correctly.
@g
@ The selection of options for \bison\ parsers suitable for \splint\
-have been discussed
+has been discussed
\ifbootstrapmode\else\locallink{bison.options}earlier \endlink\fi so we
list them here without further comments.
@<Options for \flex\ parser@>=
@@ -157,7 +166,7 @@ point of recognition, while the typesetting parser needs to be aware of them.
@G
%token TOP_OP POINTER_OP ARRAY_OP DEF_OP RE_DEF OPT_OTHER OPT_DEPRECATED
-@ {\em \POSIX\ and \.{AT\&T} \lex\ place the
+@ \namedspot{flex braces}{\em \POSIX\ and \.{AT\&T} \lex\ place the
precedence of the repeat operator, \.{\{\}}, below that of concatenation.
Thus, \.{ab\{3\}} is\/ \.{ababab}. Most other \POSIX\ utilities use an {\rm Extended
Regular Expression (ERE)} precedence that has the repeat operator
@@ -166,8 +175,8 @@ higher than concatenation. This causes \.{ab\{3\}} to yield\/ \.{abbb}.
In order to support the \POSIX\ and \.{AT\&T} precedence and the \flex\
precedence we define two token sets for the begin and end tokens of
the repeat operator, \prodstyle{BEGIN_REPEAT_POSIX} and\/ \prodstyle{END_REPEAT_POSIX}. The lexical scanner chooses
-which tokens to return based on whether {\let\it\itbold\prodstyle{posix\_compat} or \prodstyle{lex\_compat}
-are specified. Specifying either \prodstyle{posix\_compat} or \prodstyle{lex\_compat}} will
+which tokens to return based on whether {\let\it\itbold\prodstyle{posix_compat} or \prodstyle{lex_compat}
+are specified. Specifying either \prodstyle{posix_compat} or \prodstyle{lex_compat}} will
cause \flex\ to parse scanner files as per the \.{AT\&T} and \POSIX-mandated behavior.}
@<Token definitions for \flex\ input parser@>=
@G
@@ -186,6 +195,7 @@ explanation). We can nevertheless get away with an empty \Cee\ preamble.
@ @<Productions for \flex\ parser@>=
@G
+@t}\vb{\insertraw{\beginfoldedsections}}{@>
@t}\vb{\inline\flatten}{@>
goal:
initlex sect1 sect1end
@@ -202,12 +212,15 @@ initlex:
@g
@ @<Assemble a \flex\ input file@>=
- @[TeX_( "/yy0{/the/yy(2)/the/yy(4)}" );@]@;
+ @[TeX_( "/finishlist{/the/yy(4)}" );@]@;
+ @[TeX_( "/yy0{/the/yy(2)/nx/executelist{/the/yy(4)}}" );@]@;
@ @<Productions for \flex\ parser@>=
@<Productions for \flex\ section~1 parser@>@;
@<Productions for \flex\ section~2 parser@>@;
+@t}\endfoldedsections{@>
+
@ @<Exclusive productions for \flex\ section~1 parser@>=
@G
@t}\vb{\inline\flatten}{@>
@@ -220,6 +233,7 @@ goal:
@ @<Productions for \flex\ section~1 parser@>=
@G
+@t}\vb{\insertraw{\beginfoldedsections}}{@>
sect1:
sect1 startconddecl namelist1 {@> @<Add start condition declarations@> @=}
| sect1 options {@> @<Add options to section~1@> @=}
@@ -266,8 +280,11 @@ namelist1:
@ @<Report an error in \prodstylens{namelist1}{\flexnamespace} and quit@>=
@[TeX_( "/yyerror" );@]@;
+@t}\endfoldedsections{@>
+
@ @<Productions for \flex\ section~1 parser@>=
@G
+@t}\vb{\insertraw{\beginfoldedsections}}{@>
options:
OPTION_OP optionlist {@> @<Start an options list@> @=}
| POINTER_OP {@> @<Add a pointer option@> @=}
@@ -338,15 +355,19 @@ option:
@ @<Output a deprecated option@>=
@[TeX_( "/yy0{/nx/flopt{deprecated}/the/yy(1)}" );@]@;
+@t}\endfoldedsections{@>
+
@ @<Special \flex\ section~2 parser productions@>=
@G
+@t}\vb{\inline\flatten}{@>
goal:
sect2 {@> @<Output section~2@> @=}
;
@g
@ @<Output section~2@>=
- @[TeX_( "/table/yy(1)" );@]@;
+ @[TeX_( "/finishlist{/the/yy(1)}" );@]@;
+ @[TeX_( "/table/expandafter{/expandafter/executelist/expandafter{/the/yy(1)}}" );@]@;
@ This portion of the grammar was changed to make it possible to read the
action code.
@@ -364,25 +385,54 @@ initforrule:
;
@g
-@ @<Add a rule to section~2@>=
+@ The production below describes the most typical way a regular expression is
+assigned an action. The redundant term \prodstyle{initforrule} is a standard
+\bison\ trick to make sure that the appropriate initializations happen at
+the right time.
+\smallskip
+\thisrulereference{\nx\inline\nx\flatten}
+\smallskip\noindent
+The original production has been modified so that the pretty printing parser has a chance
+to consume the action code. The second \prodstyle{'\\n'} is output by the action
+processing code.
+@<Add a rule to section~2@>=
@[TeX_( "/ifflcontinued@@action" );@]@;
@[TeX_( " /toksb{/flactionc}" );@]@;
@[TeX_( "/else" );@]@;
@[TeX_( " /toksb{/flaction}" );@]@;
@[TeX_( "/fi" );@]@;
@[TeX_( "/toksa/expandafter{/astformat@@flaction}" );@]@; /* capture the formatting action */
- @[TeX_( "/yypushx{/the/yy(1)/the/toksb{/the/yy(2)}{/the/yy(4)}/the/yy(5)/the/yy(6){/the/toksa}}/on/astarray" );@]@;
- @[TeX_( "/yy0{/astarraylastcs}" );@]@;
+ @[TeX_( "/yy0{/the/yy(1)}" );@]@;
+ @[TeX_( "/appendtolistx{/the/yy(1)}{/the/toksb{/the/yy(2)}{/the/yy(4)}/the/yy(5)/the/yy(6){/the/toksa}}" );@]@;
@[TeX_( "/let/astformat@@flaction/empty" );@]@; /* reset the format */
-@ @<Add a group of rules to section~2@>=
- @[TeX_( "/yy0{/the/yy(1)/nx/flactiongroup{/the/yy(2)}/the/yy(3){/the/yy(4)}/the/yy(5)}" );@]@;
+@ For convenience, rules that are active in the same set of states may be grouped together.
+This pattern is the subject of the next production.
+\smallskip
+\thisrulereference{\nx\inline\nx\flatten}
+\smallskip\noindent
+The original parser ignores the braces while the pretty printing parser
+uses the pointers associated with the braces to collect and process the accumulated
+stash. This is how comments and \CWEB\ section references are typeset.
+@<Add a group of rules to section~2@>=
+ @[TeX_( "/yy0{/the/yy(1)}" );@]@;
+ @[TeX_( "/finishlist{/the/yy(4)}" );@]@;
+ @[TeX_( "/appendtolistx{/the/yy(1)}{/nx/flactiongroup{/the/yy(2)}/the/yy(3){/nx/executelist{/the/yy(4)}}/the/yy(5)}" );@]@;
-@ @<Start an empty section~2@>=
- @[TeX_( "/yy0{}" );@]@;
+@ Simple left recursive terms like~\prodstyle{sect2} are very suitable for being implemented as a list
+(see the macros in \.{yycommon.sty} for the details on the list implementation). The `type' of~\prodstyle{sect2}
+is a (symbolic pointer to a) list of items built up from an empty initial list. This production initializes
+the list (with the name identical to the terminal on the left hand side of the production)
+and updates the list name (rather the name's prefix) for future invocations of this action.
+
+@<Start an empty section~2@>=
+ @[TeX_( "/initlist{/secttwoprefix sect2}" );@]@;
+ @[TeX_( "/yy0{/secttwoprefix sect2}" );@]@;
+ @[TeX_( "/edef/secttwoprefix{/secttwoprefix.}" );@]@;
@ @<Add a bare action@>=
- @[TeX_( "/yy0{/the/yy(1)/nx/flbareaction/the/yy(2)}" );@]@;
+ @[TeX_( "/yy0{/the/yy(1)}" );@]@;
+ @[TeX_( "/appendtolistx{/the/yy(1)}{/nx/flbareaction/the/yy(2)}" );@]@;
@ @<Productions for \flex\ section~2 parser@>=
@G
@@ -400,14 +450,23 @@ scon:
namelist2:
namelist2 ',' sconname {@> @<Add a start condition to a list@> @=}
| sconname {@> @<Start a list with a start condition name@> @=}
- | error {@> @<Report an error compiling a start condition list@> @=}
+ | error {@> @<Report an error in a start condition list@> @=}
;
@t}\vb{\inline\flatten}{@>
sconname:
NAME {@> @<Make a \prodstylens{NAME}{\flexnamespace} into a start condition@> @=}
;
-@ @<Create a list of start conditions@>=
+@ Start conditions are just names. The data structure that is output has
+location pointers for the streams to enable interaction with \CWEB. These
+pointers are in turn the values of the angle bracket tokens that enclose the
+list of start conditions.
+
+Start condition lists may be collected in their own sections, while the list itself
+may be followed by a comment. The pointers mentioned above are used to typeset the comments
+and section references.
+\beginfoldedsectionshere
+@<Create a list of start conditions@>=
@[TeX_( "/yy0{/nx/flsconlist{/the/yy(1)}{/the/yy(3)}{/the/yy(4)}}" );@]@;
@ @<Create a universal start condition@>=
@@ -422,17 +481,24 @@ sconname:
@ @<Start a list with a start condition name@>=
@<Copy the value@>@;
-@ @<Report an error compiling a start condition list@>=
+@ @<Report an error in a start condition list@>=
@[TeX_( "/yyerror" );@]@;
@ @<Make a \prodstylens{NAME}{\flexnamespace} into a start condition@>=
@[TeX_( "/yy0{/nx/flname/the/yy(1)}" );@]@;
-@ @<Productions for \flex\ section~2 parser@>=
+@t}\endfoldedsections{@>
+
+@*1 The syntax of regular expressions. The productions in this section define the
+syntax of \flex\ regular expressions in detail. The same productions are used for
+parsing isolated regular expressions (e.g.\ to present example code). A few of these
+productions have been modified to suit the needs of the pretty printing parser.
+@<Productions for \flex\ section~2 parser@>=
@<Rules for \flex\ regular expressions@>@;
@ @<Special productions for regular expressions@>=
@G
+@t}\vb{\inline\flatten}{@>
goal:
flexrule {@> @<Output a regular expression@> @=}
;
@@ -446,33 +512,48 @@ ensures that all the changes are local to the parsing macro.
@<Output a regular expression@>=
@[TeX_( "/table/yy(1)" );@]@;
-@ @<Rules for \flex\ regular expressions@>=
+@ Regular expressions are parsed using the following productions. There are
+two major cases: rules active only at the beginning of the line, and the rest. From the
+typesetting parser's point of view, there is not much difference between the two
+(certainly not enough to justify singling out the rules at the beginning of the line into
+their own production) but it was decided to keep the original grammar rules
+for consistency.
+@<Rules for \flex\ regular expressions@>=
@G
+@t}\vb{\insertraw{\beginfoldedsections}}{@>
flexrule:
- '^' rule {@> @<Match a rule at the beginning of the line@> @=}
+ '^' rule {@> @<Match a rule at the start of the line@> @=}
| rule {@> @<Match an ordinary rule@> @=}
| EOF_OP {@> @<Match an end of file@> @=}
| error {@> @<Report an error and quit@> @=}
;
-@ @<Match a rule at the beginning of the line@>=
+@ @<Match a rule at the start of the line@>=
@[TeX_( "/toksa/expandafter{/astformat@@flrule}" );@]@;
@[TeX_( "/let/astformat@@flrule/empty" );@]@;
@[TeX_( "/yy0{/nx/flbolrule{/the/yy(2)}{/the/toksa}}" );@]@;
+@ @<Match an end of file@>=
+ @[TeX_( "/yy0{/nx/fleof/the/yy(1)}" );@]@;
+
@ @<Match an ordinary rule@>=
@[TeX_( "/toksa/expandafter{/astformat@@flrule}" );@]@;
@[TeX_( "/let/astformat@@flrule/empty" );@]@;
@[TeX_( "/yy0{/nx/flrule{/the/yy(1)}{/the/toksa}}" );@]@;
-@ @<Match an end of file@>=
- @[TeX_( "/yy0{/nx/fleof/the/yy(1)}" );@]@;
-
@ @<Report an error and quit@>=
@[TeX_( "/yyerror" );@]@;
-
-@ @<Rules for \flex\ regular expressions@>=
+
+@t}\endfoldedsections{@>
+
+@ Another broad overview of regular expression types before diving into the details
+of various operations. Note that the only trailing context that \splint\ output
+lexer can process is the end of line (\prodstyle{'\$'}) due to the way the
+scanner routine is written. It does not affect its ability to pretty print the appropriate
+rules (for a lexer that is produced by \flex\ itself, for example).
+@<Rules for \flex\ regular expressions@>=
@G
+@t}\vb{\insertraw{\beginfoldedsections}}{@>
rule:
re2 re {@> @<Match a regular expression with a trailing context@> @=}
| re2 re '$' {@> @<Disallow a repeated trailing context@> @=}
@@ -511,9 +592,22 @@ re2:
@ @<Prepare to match a trailing context@>=
@[TeX_( "/yy0{/nx/fltrail{/the/yy(1)}{/the/yy(2)}}" );@]@;
+
+ @t}\endfoldedsections{@>
-@ @<Rules for \flex\ regular expressions@>=
+@*2 Atoms. Every regular expression is assembled of atomic subexpressions, each
+of which may be modified by an repetition operator that establishes how many
+times a given pattern can repeat to stay part of the original atom. New atomic expressions
+(or \prodstyle{singleton}s as they are called below) can be formed the usual way, by
+enclosing a regular expression in parentheses.
+
+As explained \locallink{flex braces}above\endlink, braced repetition operators may
+have different binding strengths, depending on the options supplied to \flex. The pretty
+printing in both cases is identical as only the application scopes of the operator differ, and not
+its meaning.
+@<Rules for \flex\ regular expressions@>=
@G
+@t}\vb{\insertraw{\beginfoldedsections}}{@>
series:
series singleton {@> @<Extend a series by a singleton@> @=}
| singleton {@> @<Match a singleton@> @=}
@@ -540,9 +634,12 @@ series:
@ @<Match a series of exact length@>=
@<Create a series of exact length@>@;
-
+
+@t}\endfoldedsections{@>
+
@ @<Rules for \flex\ regular expressions@>=
@G
+@t}\vb{\insertraw{\beginfoldedsections}}{@>
singleton:
singleton '*' {@> @<Create a lazy series match@> @=}
| singleton '+' {@> @<Create a nonempty series match@> @=}
@@ -600,8 +697,15 @@ singleton:
@ @<Match a specific character@>=
@[TeX_( "/yy0{/nx/flchar/the/yy(1)}" );@]@;
-@ @<Rules for \flex\ regular expressions@>=
+@t}\endfoldedsections{@>
+
+@*2 Characters. Several facilities are available to specify sets of characters, including
+built-in characters classes such as {\em whitespace}, {\em printable characters},
+{\em alphanumerics}, etc. Some simple boolean operaions are also supported to make specifying
+character classes more efficient.
+@<Rules for \flex\ regular expressions@>=
@G
+@t}\vb{\insertraw{\beginfoldedsections}}{@>
fullccl:
fullccl CCL_OP_DIFF braceccl {@> @<Subtract a character class@> @=}
| fullccl CCL_OP_UNION braceccl {@> @<Create a union of character classes@> @=}
@@ -610,7 +714,7 @@ fullccl:
braceccl:
'[' ccl ']' {@> @<Create a character class@> @=}
- | '[' '^' ccl ']' {@> @<Create a complementary character class@> @=}
+ | '[' '^' ccl ']' {@> @<Complement a character class@> @=}
;
ccl:
@@ -633,11 +737,13 @@ ccl:
@ @<Create a character class@>=
@[TeX_( "/yy0{/nx/flbraceccl{/the/yy(1)}{/the/yy(2)}{/the/yy(3)}}" );@]@;
-@ @<Create a complementary character class@>=
- @[TeX_( "/yy0{/nx/flbracecclneg{/the/yy(1)}{/the/yy(3)}{/the/yy(4)}}" );@]@;
+@ @<Complement a character class@>=
+ @[TeXb( "/yy0{/nx/flbracecclneg" );@]@;
+ @[TeXfo( " {/the/yy(1)}{/the/yy(3)}{/the/yy(4)}}" );@]@;
@ @<Add a range to a character class@>=
- @[TeX_( "/yy0{/the/yy(1)/nx/flcclrnge{/nx/flchar/the/yy(2)}{/nx/flchar/the/yy(4)}}" );@]@;
+ @[TeXb( "/yy0{/the/yy(1)/nx/flcclrnge" );@]@;
+ @[TeXfo( " {/nx/flchar/the/yy(2)}{/nx/flchar/the/yy(4)}}" );@]@;
@ @<Add a character to a character class@>=
@[TeX_( "/yy0{/the/yy(1)/nx/flchar/the/yy(2)}" );@]@;
@@ -648,7 +754,12 @@ ccl:
@ @<Create an empty character class@>=
@[TeX_( "/yy0{}" );@]@;
-@ @<Rules for \flex\ regular expressions@>=
+@t}\endfoldedsections{@>
+
+@*3 Special character classes. Various character classes are predefined in \flex.
+These include alphabetic and alphanumeric characters, digits, blank characters, upper and lower
+case characters, etc.
+@<Rules for \flex\ regular expressions@>=
@G
ccl_expr:
@t}\vb{\flatten}{@>
@@ -696,7 +807,5 @@ string:
@ @<Make an empty regular expression string@>=
@[TeX_( "/yy0{}" );@]@;
-@ This is needed to get the |yytoknum| array. A trivial declaration suffices.
+@ The postamble is empty for now.
@<Postamble for \flex\ parser@>=
-#define YYPRINT(file, type, value) @[yyprint (file, type, value)@]
- static void yyprint (FILE *file, int type, YYSTYPE value){}