3
FWEB version 1.62 (September 25, 1998)
5
Based on version 0.5 of S. Levy's CWEB [copyright (C) 1987 Princeton University]
7
@x-----------------------------------------------------------------------------
9
@* IMPLEMENTING the PRODUCTIONS. For the actual grammar implemented by
10
\FWEB, see \.{prod.web}. This was split off in order to shorten the length
13
More specifically, a scrap is a structure
14
consisting of a category |cat| and a |text_pointer| |trans|, which points
15
to the translation in |tok_start|. When \cee\ text is to be processed with
16
the grammar above, we form an array |scrap_info| containing the initial
17
scraps. Our production rules have the nice property that the right-hand
18
side is never longer than the left-hand side. Therefore it is convenient to
19
use sequential allocation for the current sequence of scraps. Five pointers
20
are used to manage the parsing:
22
\yskip\hang |pp| is a pointer into |scrap_info|. We will try to match the
23
category codes |pp->cat| |(pp+1)->cat|,\dots to the left-hand sides of
26
\yskip\hang |scrap_base|, |lo_ptr|, |hi_ptr|, and |scrap_ptr| are such that
27
the current sequence of scraps appears in positions |scrap_base| through
28
|lo_ptr| and |hi_ptr| through |scrap_ptr|, inclusive, in the |cat| and
29
|trans| arrays. Scraps located between |scrap_base| and |lo_ptr| have been
30
examined, while those in positions $\ge$~|hi_ptr| have not yet been looked at
31
by the parsing process.
33
\yskip\noindent Initially |scrap_ptr| is set to the position of the final
34
scrap to be parsed, and it doesn't change its value. The parsing process
35
makes sure that |lo_ptr>=pp+3|, since productions have as many as four
36
terms, by moving scraps from |hi_ptr| to |lo_ptr|. If there are fewer than
37
|pp+3| scraps left, the positions up to |pp+3| are filled with blanks that
38
will not match in any productions. Parsing stops when |pp=lo_ptr+1| and
41
Since the |scrap| structure will later be used for other purposes, we
42
declare its second element as unions.
48
eight_bits cat; /* Category. It would be nice to |enum| this, but
49
that would turn it into an |int|, which could be as much as four times
55
@<Rest of |trans_plus| union@>@;
59
typedef scrap HUGE *scrap_pointer;
62
@d trans trans_plus.Trans /* translation texts of scraps */
69
EXTERN long max_scraps; /* Length of the next array. */
70
EXTERN scrap HUGE *scrp_info; /* Dynamic memory array for scraps */
71
EXTERN scrap_pointer scrp_end; /* end of |scrap_info|. */
73
EXTERN scrap_pointer pp; /* current position for reducing productions */
74
EXTERN scrap_pointer scrp_base; /* beginning of the current scrap sequence */
75
EXTERN scrap_pointer scrp_ptr; /* ending of the current scrap sequence */
76
EXTERN scrap_pointer lo_ptr; /* last scrap that has been examined */
77
EXTERN scrap_pointer hi_ptr; /* first scrap that has not been examined */
79
EXTERN scrap_pointer mx_scr_ptr; /* largest value assumed by |scrap_ptr| */
81
@ Token lists in |@_tok_mem| are composed of the following kinds of
82
items for \TeX\ output.
84
\item ASCII codes and special codes like |force| and
85
|math_rel| represent themselves;
87
\item |id_flag+p| represents \.{\\\\\{{\rm identifier $p$}\}};
89
\item |res_flag+p| represents \.{\\\&\{{\rm identifier $p$}\}};
91
\item |mod_flag+p| represents module name |p|;
93
\item |tok_flag+p| represents token list number |p|;
95
\item |inner_tok_flag+p| represents token list number |p|, to be
96
translated without line-break controls. (This is used for code between
101
/* In the following, note
102
that the casts are absolutely essential on machines with sixteen-bit
104
@d id_flag ID_FLAG // Signifies an identifier.
105
@d res_flag 2*id_flag // Signifies a reserved word.
106
@d mod_flag ((sixteen_bits)(3*(sixteen_bits)id_flag))
107
// Signifies a module name.
108
@d tok_flag ((sixteen_bits)(4*(sixteen_bits)id_flag)) // signifies a token list.
109
@d inner_tok_flag ((sixteen_bits)(5*(sixteen_bits)id_flag))
110
// Signifies a token list in `\Cb'.
113
@ The `|freeze_text|' macro is used to give official status to a token
114
list. Before saying |freeze_text|, items are appended to the current token
115
list, and we know that the eventual number of this token list will be the
116
current value of |text_ptr|. But no list of that number really exists as
117
yet, because no ending point for the current list has been stored in the
118
|tok_start| array. After saying |freeze_text|, the old current token list
119
becomes legitimate, and its number is the current value of |text_ptr-1|
120
since |text_ptr| has been increased. The new current token list is empty
121
and ready to be appended to. Note that |freeze_text| does not check to see
122
that |text_ptr| hasn't gotten too large, since it is assumed that this test
125
@d freeze_text *(++text_ptr)=tok_ptr
127
@ If \.{WEAVE} is being run in debugging mode, the production numbers and
128
current stack categories will be printed out when |tracing| is set
129
to~|VERBOSE|; a sequence of two or more irreducible scraps will be printed
130
out when |tracing| is set to~|BRIEF|.