summaryrefslogtreecommitdiff
path: root/support/splint/tex
diff options
context:
space:
mode:
Diffstat (limited to 'support/splint/tex')
-rw-r--r--support/splint/tex/btokenset.sty21
-rw-r--r--support/splint/tex/dcols.sty84
-rw-r--r--support/splint/tex/flex.sty683
-rw-r--r--support/splint/tex/fretokenset.sty21
-rw-r--r--support/splint/tex/ftokenset.sty72
-rw-r--r--support/splint/tex/gindex.sty522
-rw-r--r--support/splint/tex/grabstates.sty67
-rw-r--r--support/splint/tex/hext.sty346
-rw-r--r--support/splint/tex/limbo.sty1142
-rw-r--r--support/splint/tex/noweb.sty399
-rw-r--r--support/splint/tex/stokenset.sty25
-rw-r--r--support/splint/tex/trt1.sty4
-rw-r--r--support/splint/tex/xarithm.sty2
-rw-r--r--support/splint/tex/yxunion.sty2
-rw-r--r--support/splint/tex/yy.sty29
-rw-r--r--support/splint/tex/yybootstrap.sty69
-rw-r--r--support/splint/tex/yyboth.sty181
-rw-r--r--support/splint/tex/yycommon.sty522
-rw-r--r--support/splint/tex/yydebug.sty148
-rw-r--r--support/splint/tex/yyfaststack.sty52
-rw-r--r--support/splint/tex/yyinit.sty614
-rw-r--r--support/splint/tex/yyinput.sty121
-rw-r--r--support/splint/tex/yymisc.sty355
-rw-r--r--support/splint/tex/yynested.sty15
-rw-r--r--support/splint/tex/yyparse.sty68
-rw-r--r--support/splint/tex/yypretty.sty25
-rw-r--r--support/splint/tex/yystype.sty112
-rw-r--r--support/splint/tex/yytexlex.sty652
-rw-r--r--support/splint/tex/yyunion.sty2024
-rw-r--r--support/splint/tex/yyxunion.sty33
30 files changed, 6193 insertions, 2217 deletions
diff --git a/support/splint/tex/btokenset.sty b/support/splint/tex/btokenset.sty
index 07affb717e..72d3b3394f 100644
--- a/support/splint/tex/btokenset.sty
+++ b/support/splint/tex/btokenset.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2014, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -14,18 +14,21 @@
% You should have received a copy of the GNU General Public License
% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
-\prettywordpair{\%<flag>}{{$\langle\star\rangle$}}
-\prettywordpair{\%nondeterministic-parser}{{$\langle$non...ic-parser$\rangle$}}
-\prettywordpair{PERCENT_NONDETERMINISTIC_PARSER}{PER...NON...IC\_PARSER}
-\prettywordpair{semi}{{\tt;}}
+% definitions for typesetting tokens in \bison's grammar
+
+\prettywordpairwvis{\%<flag>}{{$\langle\star\rangle$}}{<*>}
+\prettywordpair{\%nondeterministic-parser}{{$\langle$nondet. parser$\rangle$}}
+\prettywordpair{PERCENT_NONDETERMINISTIC_PARSER}{{$\langle$nondet. parser$\rangle$}}
+\prettywordpairwvis{semi}{{\tt;}}{;}
\prettywordpair{TAG}{{{\tt<}{\it tag\/}{\tt>}}}
+\prettywordpair{$\ undefined}{{\tt\$undefined}}
\prettywordpair{<tag>}{{{\tt<}{\it tag\/}{\tt>}}}
-\prettywordpair{FLEX_OPTION}{{$\langle$\bf option$\rangle_{\rm f}$}}
-\prettywordpair{FLEX_STATE_X}{{$\langle$\bf state-x$\rangle_{\rm f}$}}
-\prettywordpair{FLEX_STATE_S}{{$\langle$\bf state-s$\rangle_{\rm f}$}}
+\prettywordpairwvis{FLEX_OPTION}{{$\langle$\bf option$\rangle_{\rm f}$}}{option_f}
+\prettywordpairwvis{FLEX_STATE_X}{{$\langle$\bf state-x$\rangle_{\rm f}$}}{state-x}
+\prettywordpairwvis{FLEX_STATE_S}{{$\langle$\bf state-s$\rangle_{\rm f}$}}{state-s}
\prettywordpair{ID}{{\cyr\lqq{\rm identifier}\rqq}}
\prettywordpair{ID_COLON}{{\cyr\lqq{\rm identifier: }\rqq}}
-\prettywordpair{NUL}{{$\Lambda$}}
+\prettywordpairwvis{NUL}{{$\Lambda$}}{Lambda}
\prettywordpair{INT}{{\bf int}}
\prettywordpair{CHAR}{{\bf char}}
\prettywordpair{STRING}{{\cyr\lqq{\tt string}\rqq}}
diff --git a/support/splint/tex/dcols.sty b/support/splint/tex/dcols.sty
index 2560495d45..71176efd14 100644
--- a/support/splint/tex/dcols.sty
+++ b/support/splint/tex/dcols.sty
@@ -1,4 +1,4 @@
-% Copyright 2004-2014, Alexander Shibakov
+% Copyright 2004-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -74,8 +74,9 @@
\footglue=1em plus.2em minus.1em
\adjskip=0pt plus 6pt
-\topskip=9pt
-
+%\topskip=9pt
+%\normalbottom % one of these must accompany the use of the macros below
+ % so that the columns are aligned
%
\def\setmcparams{%
@@ -231,7 +232,7 @@
\dsskip\smallskipamount
-\def\begindoublecols{\begingroup\r@ggedbottomfalse\parindent=0pt
+\def\begindoublecols{\begingroup\normalbottom\parindent=0pt
\count\footins=\@m \multiply\count\footins by\fnotesspan
\skip\footins=\fnotesspan\realfootins
\remaindergaps=\noofcolumns
@@ -718,7 +719,19 @@
% footnote counting macros
\let\footthenotes\empty
-\footline{\footthenotes}% so the footnotes know where to reset
+
+\footline{%
+ \footthenotes % so the footnotes know where to reset
+ \ifchapterhead
+ \vbox to 0pt{
+ \hbox to\pagewidth{\hfil
+ \mainfont\vrule width 0pt height 2pc\oldstyle\the\pageno
+ \hfil}
+ \vss
+ }%
+ \global\chapterheadfalse
+ \fi
+}
\def\fnmark#1{{%
\ifnum#1<\@M
@@ -741,20 +754,25 @@
% auxiliary file (we have to read it in whole because it will be
% rewritten as the document is being typeset); this opening has to be
% done carefully for the file might not be there yet; check for it first.
+% as a side note, one should not use the same stream number (at least the
+% one allocated by a \new... command) for both the input and the output
+% streams, since one might accidentally close a different stream that
+% happened to have the same index but allocated by a \new... command as a
+% stream of a different type.
-\newread\fnlabels
+\newread\tryfnlabels % to check if the file exists
\newwrite\fnlabels
\newcount\localfn % footnote count
\newcount\fniteration
\def\setupfootnotes{% this macro should be used at the beginning of the file, after a box (preferably)
- \def\footthenotes{\write\fnlabels{\noexpand\addpgendlabel}}%
- \openin\fnlabels=\jobname.ftn\relax
- \ifeof\fnlabels
- \closein\fnlabels\relax
+ \let\footthenotes\markbottomofpage
+ \openin\tryfnlabels=\jobname.ftn\relax
+ \ifeof\tryfnlabels
+ \closein\tryfnlabels\relax
\fniteration\z@
\else
- \closein\fnlabels\relax
+ \closein\tryfnlabels\relax
\input \jobname.ftn\relax
\fi
\edef\savedfnstream{\the\fnstream}%
@@ -764,30 +782,38 @@
\write\fnlabels{\noexpand\fniteration\the\fniteration\space}%
}
-\def\unsetfootnotes{% a clean(er) way to terminate footnote accounting
-% \let\footthenotes\footthenoteslast
- \def\footthenotes{\closeout\fnlabels\let\footthenotes\empty}%
+\def\markbottomofpage{%
+ \write\fnlabels{\noexpand\addpgendlabel}%
}
-% the control sequence below is not used, although the idea is clear;
-% unfortunately, this does not work, since \closeout\fnlabels is delayed
-% so \input \jobname.ftn is likely to import an empty file;
-% a more elaborate strategy is possible whereby all the macros inside
-% \jobname.ftn are made expandable and the test below (along with \input \jobname.ftn)
-% is put inside \write\m@ne{ ... } (so that the expansion of \input \jobname.ftn is
-% delayed) using string comparison macros defined elsewhere
-% but at the moment it seems excessive
-
-\def\footthenoteslast{% unused, see above
- \closeout\fnlabels
+\def\unsetfootnotes{%
+ \def\footthenotes{%
+ \write\fnlabels{\noexpand\endinput}%
+ \closeout\fnlabels
+ \global\let\footthenotes\checkfootnotestream%
+ % it is tempting to say \input \jobname.ftn
+ % at this point to use in the test below but this is not
+ % going to work: the \closeout will get invoked during the
+ % \shipout, which happens after the page is set and these
+ % macros are expanded.
+ % note that using another `stream' sequence for this purpose
+ % would not work either, since a footnote at the bottom of the
+ % page might `fire' but would be put on the next page by
+ % the epage builder.
+ }%
+}
+
+\def\checkfootnotestream{% this needs at least one extra page to work correctly ...
\fnstream{}%
- \input \jobname.ftn
+ \input\jobname.ftn
\edef\next{\the\fnstream}%
\ifx\next\savedfnstream
- \else
+ \message{Footnotes are stable ...}%
+ \else % this test is too strict, a better way would be to check that
+ % \next is a prefix in \savedfnstream and the remaining characters are all `|'
\message{Footnotes may be set incorrectly ...}%
\fi
- \let\footthenotes\relax
+ \global\let\footthenotes\empty
}
\def\setfnmark{{%
@@ -807,7 +833,7 @@
\def\splitfnstream{\edef\tempdefone{\the\fnstream}%
\ifx\tempdefone\empty
- \def\nexttok{?}\message{You need to recount the footnotes ...}%
+ \def\nexttok{?}\message{You may have to reposition the footnotes ...}%
\else
\expandafter\splitfnstre@m\tempdefone\end
\fi
diff --git a/support/splint/tex/flex.sty b/support/splint/tex/flex.sty
index da3aa7b0b7..59e23785b3 100644
--- a/support/splint/tex/flex.sty
+++ b/support/splint/tex/flex.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2014, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -14,10 +14,20 @@
% You should have received a copy of the GNU General Public License
% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
-\newtoks\tayybyte % throwaway token register
-\newcount\tayymarker % throwaway count register
-
-\chardef\EOL=`\^^J%
+% the implementation of (some part of) the \flex automata mechanisms;
+% note that a few important features have been omitted and some that
+% have been implemented may follow a (sometimes subtly) different
+% semantics (see \unput and \yyless below);
+% among the features that are missing are REJECT, ECHO and YYMORE;
+% another important missing feature is the lack of trailing
+% context matching; fixed length trailing context or fixed length
+% match with variable length context can be easily emulated with
+% regular rules and \yyless (or \unput); when both the match and
+% the context are variable length, different automaton code is
+% required; same code is required to implement REJECT; in addition,
+% the action code for the actions matching trailing context rules
+% must also be modified; while all of this may be implemented, it
+% is better not to (ab)use trailing context rules.
\def\yylex{%
\ifnum\yyg@yyinit=\z@ % if ( !yyg->yy_init ) {
@@ -29,6 +39,13 @@
\yylwhile
}
+\newif\ifyylessused
+\newtoks\yylesslastformat
+\newtoks\yylesslaststash
+\newcount\yylesslastfmark
+\newcount\yylesslastsmark
+\newcount\yylesslastchar
+
\def\yylwhile{%
% yy_cp = yyg->yy_c_buf_p;
% *yy_cp = yyg->yy_hold_char;
@@ -36,6 +53,14 @@
%
\yycurrentstate=\yyg@yystart % yy_current_state = yyg->yy_start;
\advance\yycurrentstate\YYATBOL % yy_current_state += YY_AT_BOL();
+ % save the format and stash streams for \yyless
+ \ifyylessused
+ \yylesslastformat\yyformat
+ \yylesslaststash\yystash
+ \yylesslastfmark\yyfmark
+ \yylesslastsmark\yysmark
+ \yylesslastchar\yytextlastchar
+ \fi
\yymatch
}
@@ -50,39 +75,46 @@
\fi
}
-\def\yyreinput{\expandafter\yyresetstreams\expandafter\yyinput\the\yytextseen}
+\def\yyreinput{\expandafter\yyresetstreams\expandafter\yyinput\the\yytext@seen}
\def\yyresetstreams{%
- \iftraceflexbuffers\ferrmessage{will rescan: \the\yytextseen}\fi
- \yytextseen{}%
- \yytextseenpure\yytextseen
- \yyformatseen\yytextseen
- \yystashseen\yytextseen
+ \iftraceflexbuffers\ferrmessage{will rescan: <\the\yytext@seen> (stash: \the\yystashseen)}\fi
+ \yytextseen{}\yytext@seen{}\yytextseenpure{}%
+ \yyformatseen{}\yystashseen{}%
\yytextbackupfalse
}
+% \yym@tch is the return point from the low-level input routine
+
\def\yym@tch{% do {
\yyc=\fgetelemof{yyec}\at\yycp@\relax % yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
\yyact=\fgetelemof{yyaccept}\at\yycurrentstate\relax
% ... ... reuse \yyact ( yy_act = yy_accept[yy_current_state] )
+ \ifyyflexdebug\ferrmessage{match action: \the\yyact\space(yytext: \the\yytext@:^^Jyytextseen: \the\yytext@seen>\the\yybyte)}\fi
\ifnum\yyact=\z@ % if ( yy_accept[yy_current_state] ) {
\else %
+ \ifyyflexdebug\ferrmessage{yym@tch: stash seen: \the\yystashseen^^Jsmark: \the\yysmarklast}\fi
\yyg@yylastacceptingstate=\yycurrentstate % yyg->yy_last_accepting_state = yy_current_state;
\concat\yytext\yytextseen % yyg->yy_last_accepting_cpos = yy_cp;
- \concat\yytextpure\yytextseenpure % ... ...
+ \concat\yytext@\yytext@seen % ... ...
+ \concat\yytextpure\yytextseenpure % ... ...
\concat\yyformat\yyformatseen % ... ...
\concat\yystash\yystashseen % ... ...
\yytextlastchar=\yytextseenlastchar %
\yyfmark=\yyfmarklast % ... ...
\yysmark=\yysmarklast % ... ...
- \yytextseen={}%
- \yytextseenpure\yytextseen
- \yyformatseen\yytextseen
- \yystashseen\yytextseen
+ \yyfmark@accept=\yyfmark
+ \yysmark@accept=\yysmark
+ \yytextseen={}\yytext@seen={}\yytextseenpure{}%
+ \yyformatseen{}\yystashseen{}%
\fi % }
\yyllwhile
}
+\let\yyreturn\yym@tch
+
+% \yyllwhile searches for an accepting of rejecting state
+
\def\yyllwhile{% ... yyllwhile:
\yyact=\fgetelemof{yybase}\at\yycurrentstate\relax % ... ... reusing \yyact ( yy_act = yy_base[yy_current_state] )
\advance\yyact\yyc % ... ... ( yy_act = yy_act + yy_c )
@@ -103,21 +135,27 @@
\def\yymatchtail{%
\yycurrentstate=\fgetelemof{yybase}\at\yycurrentstate\relax
\advance\yycurrentstate\yyc %
- \yycurrentstate=\fgetelemof{yynxt}\at\yycurrentstate\relax
+ \yycurrentstate=\fgetelemof{yynxt}\at\yycurrentstate\relax
+ \ifyyflexdebug\ferrmessage{yysubtext: (\the\yysubtext),^^Jyysbyte: (\the\yysbyte),^^Jyybyte: (\the\yybyte)}\fi
% yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
\concat\yytextseen\yybyte % ++yy_cp;
+ \concat\yytext@seen\yysubtext \yysubtext{}% % ...
+ \concat\yytext@seen\yybyte % ...
\concat\yytextseenpure\yybytepure % ...
- \concat\yyformatseen\yyfbyte\yyfbyte{}% % ...
- \concat\yystashseen\yysbyte\yysbyte{}% % ...
+ \concat\yyformatseen\yyfbyte \yyfbyte{}% % ...
+ \concat\yystashseen\yysbyte \yysbyte{}% % ...
\yytextseenlastchar=\yycp@ %
\yyfmarklast=\formatmarker % ...
\yysmarklast=\stashmarker % ...
\yyact=\fgetelemof{yybase}\at\yycurrentstate\relax % ... reusing \yyact ( yy_act = yy_base[yy_current_state] )
+ \ifyyflexdebug\ferrmessage{matching the rest: <\the\yytext@seen>^^J(stash: \the\yystash:^^J\the\yystashseen)}\fi
\ifnum\yyact=\YYBASEMAXENTRY\relax % } while ( yy_base[yy_current_state] != max( yy_base ) );
- \xskiptofi\yyfindaction % ... if ( yy_base[yy_current_state] == max( yy_base ) ) goto yy_find_action;
+ \ifyyflexdebug\ferrmessage{looking for the action}\fi
+ \yybreak\yyfindaction % ... if ( yy_base[yy_current_state] == max( yy_base ) ) goto yy_find_action;
\else % ... else goto yy_match;
- \xskiptofi\yymatch
- \fi
+ \ifyyflexdebug\ferrmessage{looking for more input}\fi
+ \yybreak\yymatch
+ \yycontinue
}
\newif\ifyyflexdebug
@@ -129,190 +167,38 @@
\yytextbackuptrue % yy_cp = yyg->yy_last_accepting_cpos;
\yycurrentstate=\yyg@yylastacceptingstate % yy_current_state = yyg->yy_last_accepting_state;
\yyact=\fgetelemof{yyaccept}\at\yycurrentstate\relax% yy_act = yy_accept[yy_current_state];
- \ifyyflexdebug\ferrmessage{backup: \the\yytext:\the\yytextseen}\fi
+ \formatmarker=\yyfmark@accept % ...
+ \stashmarker=\yysmark@accept % ...
+ \ifyyflexdebug\ferrmessage{backup: \the\yytext@:\the\yytext@seen^^J^^J%
+ from state: \the\yyg@yylastacceptingstate\space
+ stashmarker: \the\stashmarker}\fi
\else
- %
+ % note that at this point \yytextbackupfalse is already set
\concat\yytext\yytextseen
+ \concat\yytext@\yytext@seen
\concat\yytextpure\yytextseenpure
\concat\yyformat\yyformatseen
\concat\yystash\yystashseen
\yytextlastchar=\yytextseenlastchar
- \yyfmark=\yyfmarklast
- \yysmark=\yysmarklast
- \yytextseen{}%
- \yytextseenpure{}%
- \yyformatseen{}%
- \yystashseen{}%
+ \yyfmark=\yyfmarklast % == \formatmarker
+ \yysmark=\yysmarklast % == \stashmarker
+ \yytextseen{}\yytext@seen{}\yytextseenpure{}%
+ \yyformatseen{}\yystashseen{}%
%
\fi % }
-% \YYDOBEFOREACTION % YY_DO_BEFORE_ACTION;
+ \YYDOBEFOREACTION % YY_DO_BEFORE_ACTION;
\ifyyflexdebug
- \ferrmessage{action: \the\yyact, state: \the\yycurrentstate\space(\the\yytext)}%
+ \ferrmessage{action: \the\yyact,^^J%
+ state: \the\yycurrentstate\space(\the\yytext@:\the\yytext@seen)^^J%
+ stash: \the\yystash:\the\yystashseen^^J%
+ yysbyte: \the\yysbyte}%
\fi
\doaction
}
-\def\YYRULESETUP{% %#define YY_RULE_SETUP \
- \yytoksempty{\yytext}{}{% % if ( yyleng > 0 ) \
- \ifnum\EOL=\yytextlastchar % YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (yytext[yyleng - 1] == '\n'); \
- \YYATBOL=\@ne % YY_USER_ACTION
- \else %#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
- \YYATBOL=\z@
- \fi
- }%
-}
-
-%#define BEGIN yyg->yy_start = 1 + 2 *
-% should be:
-%#define BEGIN(state) yyg->yy_start = 1 + 2 * ( state )
-
-\newif\iftracestates
-
-\def\yylexstate#1{\csname flexstate\parsernamespace #1\endcsname}
-
-\def\yyBEGIN#1{%
- \yyg@yystart
- \expandafter\ifx\csname flexstate\parsernamespace #1\endcsname\relax
- #1 \iftracestates\ferrmessage{now in state: #1}\fi
- \else
- \csname flexstate\parsernamespace #1\endcsname\relax
- \iftracestates\ferrmessage{now in state: #1 (\number\csname flexstate\parsernamespace #1\endcsname)}\fi
- \fi
- \multiply\yyg@yystart\tw@
- \advance\yyg@yystart\@ne
-}
-
-\def\yyBEGINr#1{%
- \yyg@yystart#1%
- \iftracestates\ferrmessage{new state: \the\yyg@yystart}\fi
- \multiply\yyg@yystart\tw@
- \advance\yyg@yystart\@ne
-}
-
-%#define YY_START ((yyg->yy_start - 1) / 2)
-
-\def\YYSTART{%
- \expandafter\xdivbytwo\expandafter{\number
- \expandafter\xdecrement\expandafter{\number\yyg@yystart}}
-}
-
-\def\yypushstate#1{%
- \expandafter\yypush\expandafter{\number\YYSTART}\on\yystatestack
- \yyBEGIN{#1}%
-}
-
-\def\yypopstate{%
- \yypop\yystatestack\into{\expandafter\yyBEGIN\romannumeral0}%
- \iftracestates\message{new state (* 2 + 1 scrambled): \the\yyg@yystart}\fi
-}
-
-\def\yytopstate#1{%
- \yyreadstack\yystatestack\at\z@\to#1%
-}
-
-\let\yylexcontinue\yylwhile % complete the while loop (requires \yylexnext)
-\def\yylexcontinue{\yytext{}\yytextpure\yytext\yylwhile} % complete the while loop
-
-% \yylextail is the return point from the lexer
-
-\let\yyreturn\yym@tch % the return point from the low-level input
-
-\def\yylexreturnbootstrap#1{%
- \yytext{}\yytextpure\yytext
- \expandafter\ifx\csname token\parsernamespace #1\endcsname\relax
- % this token value is undefined
- \let\yylextail\yylex % so lex the next token
- \else
- \yychar\csname token\parsernamespace #1\endcsname\relax
- \let\yylextail\yyparsetail
- \fi
-}
-
-\def\yylexreturnregular#1{\yychar\csname token\parsernamespace #1\endcsname\relax\yytext{}\yytextpure{}\let\yylextail\yyparsetail}
-
-\def\yylexreturnval#1{% return value (yytext) only
- \yychar\csname token\parsernamespace #1\endcsname\relax
- \yylval\expandafter{\expandafter{\the\yytext}}%
- \yylval\expandafter\expandafter\expandafter{\expandafter\the\expandafter\yylval\expandafter{\the\yytextpure}}%
- % the above is an equivalent of
- % \edef\next{\yylval{{\the\yytext}{\the\yytextpure}}}\next
- % but does not `pollute' the definition of \next
- \yytext{}\yytextpure\yytext\let\yylextail\yyparsetail
-}
-
-\def\yylexreturnptr#1{% return stream pointers only
- \yylval\expandafter{\expandafter{\the\yyfmark}}%
- \yylval\expandafter\expandafter\expandafter{\expandafter\the\expandafter\yylval\expandafter{\the\yysmark}}%
- % the above is an equivalent of
- % \edef\next{\yylval{{\the\yyfmark}{\the\yysmark}}}\next
- % but does not `pollute' the definition of \next
- \yylexreturn{#1}%
-}
+\newif\iftraceactioncode
-\def\yylexreturntext{\yylexreturnptr{\the\yytextpure}}
-
-\def\yylexreturnraw#1{% return the character value
- \yychar`#1\relax
- \yytext{}\yytextpure{}\let\yylextail\yyparsetail
-}
-
-\def\yylexreturnchar{%
- \expandafter\yylexreturnraw\the\yytextpure
-}
-
-\def\yylexnext{\yytext{}\yytextpure{}} % use this with a trivial \yylexcontinue
-\let\yylexnext\empty
-
-\def\yyterminate{\yychar\YYEOF\yylval{}\yytext{}\yytextpure{}\let\yylextail\yyparsetail}
-
-\def\yyerrterminate{\yylexreturn{$undefined}} %$
-
-\def\ferrmessage#1{\immediate\write16{#1}}
-
-% \yyless is slow and the macros below have not been tested in their current
-% form: avoid them
-
-\def\yyless#1{%
- \ifnum#1=\z@
- \ROLLBACKCURRENTTOKEN
- \else
- \let\oldyyreturn\yyreturn
- \edef\yyreturn{\noexpand\yyskipnchars{\number#1}}%
- \expandafter\yyinput\the\yytext\yyeof
- \fi
-}
-
-\def\yyskipnchars#1{%
- \ifnum\yycp@=\YYENDOFBUFFERCHAR % read \yyeof
- \yycomplain{yyless buffer overflow: #1 characters too many}%
- \else
- \ifnum#1=\@ne % skipped the required number of tokens
- \yybreak@\yyl@ss
- \else
- \edef\yyreturn{\noexpand\yyskipnchars{\xdecrement{#1}}}%
- \yybreak@\yyinput
- \fi
- \yycontinue
-}
-
-\def\yyl@ss#1\yyeof{%
- \yytext{#1}%
- \concatl\yytext\yytextseen
- \yytext{}\yytextpure{}%
- \yytextbackuptrue
- \let\yyreturn\oldyyreturn
-}
-
-%#define ROLLBACK_CURRENT_TOKEN \
-% do { \
-% scanner_cursor.column -= mbsnwidth (yytext, yyleng, 0); \
-% yyless (0); \
-% } while (0)
-
-\def\ROLLBACKCURRENTTOKEN{%
- \concatl\yytext\yytextseen
- \yytext{}\yytextpure{}%
- \yytextbackuptrue
+\def\YYDOBEFOREACTION{%
}
% \yytext---current yytext
@@ -332,6 +218,13 @@
% yyg->yy_c_buf_p = yy_cp;
\def\doaction{%
+ \iftraceactioncode
+ {%
+ \expandafter\toksa
+ \expandafter\expandafter\expandafter{\csname doflexaction\number\yyact\parsernamespace\endcsname}%
+ \ferrmessage{action code (\the\yyact):^^J\the\toksa}%
+ }%
+ \fi
\yydoactionswitch\yyact
}
@@ -344,10 +237,14 @@
% another;
\def\yylexeofaction{%
+ \ifyyflexdebug
+ \ferrmessage{eof action: .\the\yytext@>>\the\yytext@seen(\the\yytext)}%
+ \fi
\yygetnextbuffer
\ifYYEOBLASTMATCH
\yygetpreviousstate
- \ifyyflexdebug\ferrmessage{found previous state: \the\yycurrentstatelocal\space matched text: \the\yytext>>\the\yytextseen(\the\yybyte))}\fi
+ \ifyyflexdebug\ferrmessage{found previous state: \the\yycurrentstatelocal\space
+ matched text: \the\yytext@>>\the\yytext@seen(\the\yybyte)}\fi
\yycurrentstate\yycurrentstatelocal
\let\yylextail\yyfind@ction
\YYEOBLASTMATCHfalse
@@ -356,55 +253,60 @@
\advance\yyact\YYSTART
\advance\yyact\@ne % yy_act = YY_STATE_EOF(YY_START);
\let\yylextail\doaction % goto do_action;
- \appendl\yytextseen{\the\yytext}\yytextbackuptrue % in case the scanner gets called again
- \ifyyflexdebug
+ \concatl\yytext\yytext@seen \yytextbackuptrue % in case the scanner gets called again
\yytoksempty{\yytext}%
{\errmessage{internal error: matched nothing in eob state}}%
- {\yyisthiscsr\yytext\yyeof{}{\errmessage{internal error: matched more that a single eob}}}%
- \ferrmessage{eob in user state: \the\yyact\space matched text: \the\yytext(\the\yytextpure)\space
- to read: \the\yytextseen}%
+ {\yyisthiscsr\yytext\yyeof{}{\errmessage{internal error: matched more than a single eob: (\the\yytext)}}}%
+ \ifyyflexdebug
+ \ferrmessage{eob in user state: \the\yyact\space matched text: \the\yytext@(\the\yytext)\space
+ to read: \the\yytext@seen}%
\fi
- \yytext{}%
+ \yytext{}\yytext@{}%
\fi
}
\def\yygetnextbuffer{%
\yytoksempty{\yytext}{\errmessage{internal error: empty matched text in eob state}}%
- {%
- \expandafter\expandafter\expandafter
- \yystringempty % we have matched exactly one token
- \expandafter\expandafter\expandafter{\expandafter\eatone\the\yytext}%
- {\YYEOBLASTMATCHfalse}{\YYEOBLASTMATCHtrue}%
+ {% this somewhat complicated definition is needed in case the last character is an ordinary
+ % space character
+ \expandafter\yystartsinspace\expandafter{\the\yytext}{%
+ \expandafter\expandafter\expandafter
+ \yystringempty % we have matched exactly one token (space)
+ \expandafter\expandafter\expandafter{\expandafter\eattospace\the\yytext}%
+ {\YYEOBLASTMATCHfalse}{\YYEOBLASTMATCHtrue}%
+ }{%
+ \expandafter\expandafter\expandafter
+ \yystringempty % we have matched exactly one token
+ \expandafter\expandafter\expandafter{\expandafter\eatone\the\yytext}%
+ {\YYEOBLASTMATCHfalse}{\YYEOBLASTMATCHtrue}%
+ }%
}%
}
-\def\yyeofcontainer{\yyeof}
-
\newif\ifYYEOBLASTMATCH
\def\yygetpreviousstate{%
\yycurrentstatelocal=\yyg@yystart
\advance\yycurrentstatelocal\YYATBOL
+ \ifyyflexdebug\ferrmessage{state setup.: start(\the\yyg@yystart), bol(\number\YYATBOL)}\fi
%
\yytoksempty{\yytext}{\errmessage{internal error: empty matched text in eob state}}{}%
- \expandafter\yysplitoff\expandafter.\the\yytext\yyeof\end
- \appendl\yytextseen{\noexpand\yyeof}\yytextbackuptrue
- \ifyyflexdebug\ferrmessage{searching for last match in text: \the\yytext}\fi % TODO: delete
+ % move the scanned \yyeof to the buffer of seen characters
+ \expandafter\yysplitoff\expandafter.\the\yytext\yyeof\end\yytext
+ \expandafter\yysplitoff\expandafter.\the\yytext@\yyeof\end\yytext@
+ \appendlnx\yytextseen\yyeof
+ \appendlnx\yytext@seen\yyeof \yytextbackuptrue
+ \ifyyflexdebug\ferrmessage{searching for last match in text: \the\yytext@}\fi
\yytoksempty{\yytext}{}{% yyg->yytext_ptr >= yyg->yy_c_buf_p /* do not enter the for loop */
- \yytextpure{}%
- \yyfutureyytext\yytextseen % to be reinserted in yyfind@action
- \yytextseen{}\yytextseenpure{}%
- \expandafter\yytext\expandafter
- {\expandafter}\expandafter
- \yygetpreviousstatefor\the\yytext\splitoffend % at least one iteration of the for loop
- }%
+ \expandafter\yygetpreviousstatefor\the\yytext@\splitoffend % at least one iteration of the for loop
+ }%
}
-\def\yysplitoff#1\yyeof#2\end{%
+\def\yysplitoff#1\yyeof#2\end#3{%
\yystringempty{#2}{%
- \errmessage{internal error: something other than \noexpand\yyeof\space triggered eob action}%
+ \errmessage{internal error: something other than \noexpand\yyeof\space triggered eob action: <\the\yytext@>}%
}{%
- \yytext\expandafter{\eatone#1}% to remove the `.' at the beginning
+ #3\expandafter{\eatone#1}% to remove the `.' at the beginning
}%
}
@@ -413,46 +315,41 @@
% to be restored on exit from the `for' loop
% i.e.~when the \splitoff token is read
\let\currentyyreturn\yyreturn
-%
- \let\currentyyfbyte\yyfbyte
- \let\currentyysbyte\yysbyte
- \let\currentstashmarker\stashmarker
- \let\currentformatmarker\formatmarker
-%
- \let\yyfbyte\tayybyte
- \let\yysbyte\tayybyte
- \let\stashmarker\tayymarker
- \let\formatmarker\tayymarker
-%
+ \yyfutureyytext\yytext@seen % to be reinserted in yyfind@action
+ \yytext{}\yytext@{}\yytextpure{}%
+ \yytextseen{}\yytext@seen{}\yytextseenpure{}%
+ \formatmarker=\yyfmark@accept
+ \stashmarker=\yysmark@accept
+ \yyfmarklast=\formatmarker
+ \yysmarklast=\stashmarker
+ \yyformatseen{}\yystashseen{}%
\let\yyreturn\yygetpreviousstatef@r
\yyinput
}
\def\yygetpreviousstatef@r{%
\let\default\yygetpreviousstatedefault
- \ifyyflexdebug\ferrmessage{just read: \the\yybyte}\fi % TODO: delete
+ \ifyyflexdebug\ferrmessage{just read: \the\yybyte (so far: \the\yytext@><\the\yytext@seen)}\fi % TODO: delete
\switchon{\expandafter\getfirsttoken\expandafter{\the\yybyte}}\in\yygetpreviousstateswitch
}
\def\yygetpreviousstateswitch{%
- \yyeof {% scanned a NUL
+ \yyeof {% scanned a NUL: currently NUL transitions are not implemented
+ % (so one cannot use NUL's in the input) so this state is never used
\yyclocal\YYECMAGIC\relax % the constant extracted from yy_get_next_state
+ \edef\yycurrentstatelocal@prejam{\the\yycurrentstatelocal}%
\yygetpreviousstat@f@r
- }
+ }%
\splitoffend {% yyg->yytext_ptr >= yyg->yy_c_buf_p /* exit the for loop */
% this is not an actual character but a marker for the end of the `for' loop
- \let\yyfbyte\currentyyfbyte
- \let\yysbyte\currentyysbyte
- \let\stashmarker\currentstashmarker
- \let\formatmarker\currentformatmarker
\yycp@=\YYENDOFBUFFERCHAR\relax % this is not necessary
\yybyte{}\yybytepure{}%
%
\let\yyreturn\currentyyreturn
- }
+ }%
\endparse \endparseinput {%
\errmessage{internal error.: reading past the end of the input buffer}%
- }
+ }%
}
\def\yygetpreviousstatedefault{%
@@ -465,20 +362,41 @@
\ifnum\fgetelemof{yyaccept}\at\yycurrentstatelocal=\z@
% if ( yy_accept[yy_current_state] ) {
\concat\yytextseen\yybyte
+ \concat\yytext@seen\yysubtext \yysubtext{}%
+ \concat\yytext@seen\yybyte
\concat\yytextseenpure\yybytepure
- \yybyte{}\yybytepure\yybyte
+ \yybyte{}\yybytepure{}%
+ \yyfmarklast=\formatmarker
+ \yysmarklast=\stashmarker
+ \concat\yyformatseen\yyfbyte \yyfbyte{}%
+ \concat\yystashseen\yysbyte \yysbyte{}%
\else %
- \ifyyflexdebug\ferrmessage{possible accepting state: \the\yycurrentstatelocal:%
- \fgetelemof{yyaccept}\at\yycurrentstatelocal}\fi % TODO: delete
+ \ifyyflexdebug
+ \ferrmessage{possible accepting state.: \the\yycurrentstatelocal:%
+ \fgetelemof{yyaccept}\at\yycurrentstatelocal}%
+ \fi
\yyg@yylastacceptingstate=\yycurrentstatelocal
% yyg->yy_last_accepting_state = yy_current_state;
\concat\yytext\yytextseen % yyg->yy_last_accepting_cpos = yy_cp; TODO:?????????
- \concat\yytextpure\yytextseenpure % ... ...
- \yytextseen=\yybyte
- \yytextseenpure=\yybytepure
+ \concat\yytext@\yytext@seen % ...
+ \concat\yytextpure\yytextseenpure % ...
+ \yytextseen=\yybyte % ...
+ \yytext@seen=\yysubtext \yysubtext{}% % ...
+ \concat\yytext@seen\yybyte \yybyte{}% % ...
+ \yytextseenpure=\yybytepure\yybytepure{}% %
\yytextbackuptrue
- \yybyte{}\yybytepure\yybyte
\yytextlastchar=\yytextseenlastchar %
+ %
+ \yyfmark=\yyfmarklast % ... ...
+ \yysmark=\yysmarklast % ... ...
+ \yyfmark@accept=\yyfmark
+ \yysmark@accept=\yysmark
+ \yyfmarklast=\formatmarker
+ \yysmarklast=\stashmarker
+ \concat\yyformat\yyformatseen
+ \concat\yystash\yystashseen
+ \yyformatseen\yyfbyte\yyfbyte{}%
+ \yystashseen\yysbyte\yysbyte{}%
\fi
\yygpswhile
}
@@ -501,11 +419,26 @@
\yycontinue % }
}
-\def\yygpsfornext{%
+\newif\ifyyflexisjammed
+
+\def\yygpsfornext{% this combines yy_get_previous_state() and yy_get_NUL_trans()
+ \ifyyflexdebug\ferrmessage{starting in state.: \the\yycurrentstatelocal}\fi % TODO: delete
\yycurrentstatelocal=\fgetelemof{yybase}\at\yycurrentstatelocal\relax
\advance\yycurrentstatelocal\yyclocal
\yycurrentstatelocal=\fgetelemof{yynxt}\at\yycurrentstatelocal\relax
- \ifyyflexdebug\ferrmessage{switching to state: \the\yycurrentstatelocal}\fi % TODO: delete
+ % yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ % currently, we do not allow NULs in the input so the code below is not used
+ % when NUL transitions are implemented, this code will come into play
+ \ifnum\yycurrentstatelocal=\YYMAXREALCHAR\relax
+ \yycurrentstatelocal=\yycurrentstatelocal@prejam\relax
+ \ifyyflexdebug\ferrmessage{jammed, switching to \yycurrentstatelocal@prejam}\fi
+ \yyflexisjammedtrue
+ \else
+ \yyflexisjammedfalse
+ \fi
+ %yy_is_jam = (yy_current_state == ...);
+ %return yy_is_jam ? 0 : yy_current_state;
+ \ifyyflexdebug\ferrmessage{switching to state.: \the\yycurrentstatelocal\space on char \the\yyclocal}\fi % TODO: delete
\yyinput
}
@@ -518,30 +451,266 @@
% yy_cp = yyg->yy_last_accepting_cpos;
\yycurrentstate=\yyg@yylastacceptingstate % yy_current_state = yyg->yy_last_accepting_state;
\yyact=\fgetelemof{yyaccept}\at\yycurrentstate\relax% yy_act = yy_accept[yy_current_state];
+ \formatmarker=\yyfmark@accept % ...
+ \stashmarker=\yysmark@accept % ...
\ifyyflexdebug\ferrmessage{backup.: \the\yytext:\the\yytextseen}\fi
\else
%
\concat\yytext\yytextseen
- \concat\yytext\yybyte
- \yybyte{}%
- \yytextseen{}%
+ \concat\yytext@\yytext@seen
\concat\yytextpure\yytextseenpure
- \concat\yyformat\yyformatseen
- \concat\yystash\yystashseen
+ \concat\yytext\yybyte
+ \concat\yytext@\yysubtext \yysubtext{}%
+ \concat\yytext@\yybyte
+ \concat\yytextpure\yybytepure
+ \yybyte{}\yybytepure{}%
+ \yytextseen{}\yytext@seen{}\yytextseenpure{}%
+ \concat\yyformat\yyformatseen\yyformatseen{}%
+ \concat\yystash\yystashseen\yystashseen{}%
\yytextlastchar=\yytextseenlastchar
\yyfmark=\yyfmarklast
\yysmark=\yysmarklast
- \yyformatseen{}%
- \yystashseen{}%
%
\fi % }
- \concat\yytextseen\yyfutureyytext % ... reinsert the tokens seen by the lexer before
+ \concat\yytext@seen\yyfutureyytext % ... reinsert the tokens seen by the lexer before
% ... \yygetpreviousaction got rolling
\yyfutureyytext{}%
\yytextbackuptrue
-% \YYDOBEFOREACTION % YY_DO_BEFORE_ACTION;
+ \YYDOBEFOREACTION % YY_DO_BEFORE_ACTION;
\ifyyflexdebug
\ferrmessage{action.: \the\yyact, state: \the\yycurrentstate\space(\the\yytext) \parsernamespace}%
\fi
\doaction
}
+
+\def\YYRULESETUP{% %#define YY_RULE_SETUP \
+ \yytoksempty{\yytext}{}{% % if ( yyleng > 0 ) \
+ \ifnum\n=\yytextlastchar % YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (yytext[yyleng - 1] == '\n'); \
+ \YYATBOL=\@ne % YY_USER_ACTION
+ \else %#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+ \YYATBOL=\z@
+ \ifyyflexdebug\ferrmessage{YYATBOL: 0}\fi
+ \fi
+ }%
+}
+
+%#define yy_set_bol(at_bol) \
+% { \
+% if ( ! YY_CURRENT_BUFFER ){\
+% yyensure_buffer_stack (); \
+% YY_CURRENT_BUFFER_LVALUE = \
+% yy_create_buffer(yyin,YY_BUF_SIZE ); \
+% } \
+% YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+% }
+
+\def\yysetbol#1{\YYATBOL=#1\relax} % we do not switch or create buffers
+
+%#define BEGIN yyg->yy_start = 1 + 2 *
+% should be:
+%#define BEGIN(state) yyg->yy_start = 1 + 2 * ( state )
+
+\newif\iftracestates
+
+\def\yylexstate#1{\csname flexstate\parsernamespace #1\endcsname}
+
+\def\yyBEGIN#1{%
+ \yyg@yystart
+ \expandafter\ifx\csname flexstate\parsernamespace #1\endcsname\relax
+ #1 \iftracestates\ferrmessage{now in state: #1}\fi
+ \else
+ \csname flexstate\parsernamespace #1\endcsname\relax
+ \iftracestates\ferrmessage{now in state: #1 (\number\csname flexstate\parsernamespace #1\endcsname)}\fi
+ \fi
+ \multiply\yyg@yystart\tw@
+ \advance\yyg@yystart\@ne
+}
+
+\def\yyBEGINr#1{%
+ \yyg@yystart#1%
+ \iftracestates\ferrmessage{new state: \the\yyg@yystart}\fi
+ \multiply\yyg@yystart\tw@
+ \advance\yyg@yystart\@ne
+}
+
+%#define YY_START ((yyg->yy_start - 1) / 2)
+
+\def\YYSTART{%
+ \expandafter\xdivbytwo\expandafter{\number
+ \expandafter\xdecrement\expandafter{\number\yyg@yystart}}
+}
+
+\def\yypushstate#1{%
+ \expandafter\yypush\expandafter{\number\YYSTART}\on\yystatestack
+ \yyBEGIN{#1}%
+}
+
+\def\yypopstate{%
+ \yypop\yystatestack\into{\expandafter\yyBEGIN\romannumeral0}%
+ \iftracestates\ferrmessage{new state (* 2 + 1 scrambled): \the\yyg@yystart}\fi
+}
+
+\def\yytopstate#1{%
+ \yyreadstack\yystatestack\at\z@\to#1%
+}
+
+\let\yylexcontinue\yylwhile % complete the while loop (requires \yylexnext)
+\def\yylexcontinue{\yytext{}\yytextpure{}\yytext@{}\yylwhile} % complete the while loop
+
+% \yylextail is the return point from the lexer
+
+\def\yylexreturnbootstrap#1{%
+ \yytext{}\yytext@{}\yytextpure{}%
+ \expandafter\ifx\csname token\parsernamespace #1\endcsname\relax
+ % this token value is undefined
+ \let\yylextail\yylex % so lex the next token
+ \else
+ \yychar\csname token\parsernamespace #1\endcsname\relax
+ \let\yylextail\yyparsetail
+ \fi
+}
+
+\def\yylexreturnregular#1{%
+ \yychar\csname token\parsernamespace #1\endcsname\relax
+ \yytext{}\yytext@{}\yytextpure{}\let\yylextail\yyparsetail
+}
+
+\def\yylexreturnval#1{% return value (yytext) only
+ \yychar\csname token\parsernamespace #1\endcsname\relax
+ \yylval\expandafter{\expandafter{\the\yytext}}%
+ \yylval\expandafter\expandafter\expandafter{\expandafter\the\expandafter\yylval\expandafter{\the\yytextpure}}%
+ % the above is an equivalent of
+ % \edef\next{\yylval{{\the\yytext}{\the\yytextpure}}}\next
+ % but does not `pollute' the definition of \next
+ \yytext{}\yytext@{}\yytextpure{}\let\yylextail\yyparsetail
+}
+
+\def\yylexreturnptr#1{% return stream pointers only
+ \yylval\expandafter{\expandafter{\the\yyfmark}}%
+ \yylval\expandafter\expandafter\expandafter{\expandafter\the\expandafter\yylval\expandafter{\the\yysmark}}%
+ % the above is an equivalent of
+ % \edef\next{\yylval{{\the\yyfmark}{\the\yysmark}}}\next
+ % but does not `pollute' the definition of \next
+ \yylexreturn{#1}%
+}
+
+\def\yylexreturnsym#1{% return the value (yytext) followed by the pointers
+ \yychar\csname token\parsernamespace #1\endcsname\relax
+ \yylval\expandafter{\expandafter{\the\yytext}}%
+ \yylval\expandafter\expandafter\expandafter{\expandafter\the\expandafter\yylval\expandafter{\the\yytextpure}}%
+ \yylval\expandafter\expandafter\expandafter{\expandafter\the\expandafter\yylval\expandafter{\the\yyfmark}}%
+ \yylval\expandafter\expandafter\expandafter{\expandafter\the\expandafter\yylval\expandafter{\the\yysmark}}%
+ % the above is an equivalent of
+ % \edef\next{\yylval{{\the\yytext}{\the\yytextpure}{\the\yyfmark}{\the\yysmark}}}\next
+ % but does not `pollute' the definition of \next
+ \yytext{}\yytext@{}\yytextpure{}\let\yylextail\yyparsetail
+}
+
+\def\yylexreturntext{\yylexreturnptr{\the\yytextpure}}
+
+\def\yylexreturnraw#1{% return the character, pointers as the value
+ \yylval\expandafter{\expandafter{\the\yyfmark}}%
+ \yylval\expandafter\expandafter\expandafter{\expandafter\the\expandafter\yylval\expandafter{\the\yysmark}}%
+ \yychar`#1\relax
+ \yytext{}\yytext@{}\yytextpure{}\let\yylextail\yyparsetail
+}
+
+\def\yylexreturnchar{%
+ \expandafter\yylexreturnraw\the\yytextpure
+}
+
+\def\yylexreturnxchar#1{% return the numeric value, pointers as the value
+ \yylval\expandafter{\expandafter{\the\yyfmark}}%
+ \yylval\expandafter\expandafter\expandafter{\expandafter\the\expandafter\yylval\expandafter{\the\yysmark}}%
+ \yychar#1\relax
+ \yytext{}\yytext@{}\yytextpure{}\let\yylextail\yyparsetail
+}
+
+\def\yylexnext{\yytext{}\yytext@{}\yytextpure{}} % use this with a trivial \yylexcontinue
+\let\yylexnext\empty
+
+\def\yyterminate{\yychar\YYEOF\yylval{}\yytext{}\yytext@{}\yytextpure{}\let\yylextail\yyparsetail}
+
+\def\yyerrterminate{\yylexreturn{$undefined}} %$
+
+\def\yyfatal#1{\yycomplain{#1}\yyerrterminate}
+
+\def\yywarn#1{\yycomplain{#1}\yylexnext}
+
+% \yyless is slow and the macros below have not been tested in their current
+% form: avoid them
+
+\def\yyless#1{%
+ \yyless@backup
+ \ifnum#1=\z@
+ \yyfmark=\formatmarker
+ \yysmark=\stashmarker
+ \ROLLBACKCURRENTTOKEN
+ \else
+ \let\oldyyreturn\yyreturn
+ \edef\yyreturn{\noexpand\yyskipnchars{\number#1}}%
+ \expandafter\yyinput\the\yytext@\yyeof
+ \fi
+}
+
+\def\yyless@backup{%
+ \yyformat\yylesslastformat
+ \yystash\yylesslaststash
+ \yysbyte{}\yyfbyte{}%
+ \formatmarker\yylesslastfmark
+ \stashmarker\yylesslastsmark
+}
+
+\def\yyless@updatestreams{%
+ \concat\yyformat\yyfbyte\yyfbyte{}%
+ \concat\yystash\yysbyte\yysbyte{}%
+}
+
+\def\yyskipnchars#1{%
+ \ifnum\yycp@=\YYENDOFBUFFERCHAR % read \yyeof
+ \yycomplain{yyless buffer overflow: #1 characters too many}%
+ \else
+ \yyless@updatestreams
+ \ifnum#1=\@ne % skipped the required number of tokens
+ \yybreak@\yyl@ss
+ \else
+ \edef\yyreturn{\noexpand\yyskipnchars{\xdecrement{#1}}}%
+ \yybreak@\yyinput
+ \fi
+ \yycontinue
+}
+
+\def\yyl@ss#1\yyeof{%
+ \yyfmark=\formatmarker
+ \yysmark=\stashmarker
+ \yylesslaststash\yystash
+ \yylesslastformat\yyformat
+ \unput{#1}%
+ \let\yyreturn\oldyyreturn
+}
+
+% \unput has a slightly different semantics from \flex's unput() since
+% it puts back an arbitrary string rather than a character; it clobbers
+% the values of \yytext, \yytext@, and \yytextpure so these must be saved before
+% \unput is used
+
+\def\unput#1{%
+ \yytext@{#1}%
+ \concatl\yytext@\yytext@seen
+ \yytext{}\yytext@{}\yytextpure{}%
+% \yystringempty{#1}{}{\yytextbackuptrue}% TODO: just set \yytexbackuptrue
+ \yytextbackuptrue
+}
+
+%#define ROLLBACK_CURRENT_TOKEN \
+% do { \
+% scanner_cursor.column -= mbsnwidth (yytext, yyleng, 0); \
+% yyless (0); \
+% } while (0)
+
+\def\ROLLBACKCURRENTTOKEN{% this does not reset the streams
+ \concatl\yytext\yytextseen
+ \concatl\yytext\yytext@seen % do not rollback collected streams
+ \yytext{}\yytext@{}\yytextpure{}%
+ \yytextbackuptrue
+}
diff --git a/support/splint/tex/fretokenset.sty b/support/splint/tex/fretokenset.sty
new file mode 100644
index 0000000000..6dfba7ea58
--- /dev/null
+++ b/support/splint/tex/fretokenset.sty
@@ -0,0 +1,21 @@
+% Copyright 2012-2020, Alexander Shibakov
+% This file is part of SPLinT
+%
+% SPLinT is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% SPLinT is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
+
+% typesetting regular expression names in \flex's scanner
+
+\prettywordpairwvis{WS}{\.{\ }${}_+$}{ +}
+\prettywordpairwvis{NL}{\hbox{$\hookleftarrow$}}{\n}
+\prettywordpairwvis{OPTWS}{\.{\ }${}_*$}{ *}
diff --git a/support/splint/tex/ftokenset.sty b/support/splint/tex/ftokenset.sty
new file mode 100644
index 0000000000..9eb5fbd70d
--- /dev/null
+++ b/support/splint/tex/ftokenset.sty
@@ -0,0 +1,72 @@
+% Copyright 2012-2020, Alexander Shibakov
+% This file is part of SPLinT
+%
+% SPLinT is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% SPLinT is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
+
+% typesetting tokens in \flex's grammar
+
+\prettywordpairwvis{CHAR}{{\bf char}}{char}
+\prettywordpairwvis{NUMBER}{{\bf num}}{num}
+\prettywordpairwvis{NAME}{{\cyr\lqq{\rm name}\rqq}}{name}
+\prettywordpairwvis{OPTION_OP}{\hbox{$\langle\hbox{\.{option}}\rangle$}}{option}
+\prettywordpairwvis{EOF_OP}{\hbox{$\langle\hbox{\.{EOF}}\rangle$}}{EOF}
+
+\def\prettyccepairwvis#1#2{%
+ \prettywordpairwvis{#1}{\hbox{$\csname xccl@#1\endcsname$}}{#2}%
+ \prettyccep@irwvis#1.{#2}%
+}
+
+\def\prettyccep@irwvis CCE_#1.#2{%
+ \prettywordpairwvis{CCE_NEG_#1}{\hbox{$\csname xccl@CCE_NEG_#1\endcsname$}}{neg #2}%
+}
+
+\prettyccepairwvis{CCE_ALNUM}{alphan}
+\prettyccepairwvis{CCE_ALPHA}{alpha}
+\prettyccepairwvis{CCE_BLANK}{ .}
+\prettyccepairwvis{CCE_GRAPH}{beta}
+\prettyccepairwvis{CCE_DIGIT}{0}
+\prettyccepairwvis{CCE_XDIGIT}{0..Z}
+\prettyccepairwvis{CCE_SPACE}{ }
+\prettyccepairwvis{CCE_LOWER}{a..z}
+\prettyccepairwvis{CCE_UPPER}{A..Z}
+\prettyccepairwvis{CCE_PRINT}{zzz}
+\prettyccepairwvis{CCE_PUNCT}{.}
+\prettyccepairwvis{CCE_CNTRL}{->}
+%
+\prettywordpairwvis{BEGIN_REPEAT_POSIX}{{\.{\{}$_{\rm p}$}}{\lbchar p}
+\prettywordpairwvis{END_REPEAT_POSIX}{{\.{\}}$_{\rm p}$}}{\rbchar p}
+\prettywordpairwvis{BEGIN_REPEAT_FLEX}{{\.{\{}$_{\rm f}$}}{\lbchar f}
+\prettywordpairwvis{END_REPEAT_FLEX}{{\.{\}}$_{\rm f}$}}{\rbchar f}
+\prettywordpairwvis{CCL_OP_DIFF}{\hbox{$\setminus$}}{\benignescape}
+\prettywordpairwvis{CCL_OP_UNION}{\hbox{$\cup$}}{U}% see lstokenset.sty for setting up context-dependent indexing/display
+\prettywordpairwvis{OPT_OUTFILE}{\hbox{$\langle\hbox{\.{outfile}}\rangle$}}{outfile}
+\prettywordpairwvis{OPT_EXTRA_TYPE}{\hbox{$\langle\hbox{\.{extra type}}\rangle$}}{extra type}
+\prettywordpairwvis{OPT_PREFIX}{\hbox{$\langle\hbox{\.{prefix}}\rangle$}}{prefix}
+\prettywordpairwvis{OPT_YYCLASS}{\hbox{$\langle\hbox{\.{yyclass}}\rangle$}}{yyclass}
+\prettywordpairwvis{OPT_HEADER}{\hbox{$\langle\hbox{\.{header}}\rangle$}}{header}
+\prettywordpairwvis{OPT_TABLES}{\hbox{$\langle\hbox{\.{tables}}\rangle$}}{tables}
+
+\prettywordpairwvis{TOP_OP}{\hbox{$\langle\hbox{\.{top}}\rangle$}}{top_op}
+\prettywordpairwvis{POINTER_OP}{\hbox{$\langle\hbox{\.{pointer*}}\rangle$}}{pointer_op}
+\prettywordpairwvis{ARRAY_OP}{\hbox{$\langle\hbox{\.{array}}\rangle$}}{array_op}
+\prettywordpairwvis{DEF_OP}{\hbox{$\langle\hbox{\.{def}}\rangle$}}{def_op}
+\prettywordpairwvis{OPT_OTHER}{\hbox{$\langle\hbox{\.{other}}\rangle$}}{other_op}
+\prettywordpairwvis{OPT_DEPRECATED}{\hbox{$\langle\hbox{\.{deprecated}}\rangle$}}{deprecated_op}
+\prettywordpairwvis{RE_DEF}{\hbox{$\langle\hbox{\.{def}$_{\rm re}$}\rangle$}}{def_re}
+
+\prettywordpairwvis{SCDECL}{\hbox{$\langle\hbox{\bf state}\rangle$}}{state}
+\prettywordpairwvis{XSCDECL}{\hbox{$\langle\hbox{\bf xtate}\rangle$}}{xtate}
+\prettywordpairwvis{\\n}{\hbox{{\sixpoint\.{\\}}\.{n}}}{\benignescape n}
+\prettywordpairwvis{-}{\hbox{\rm--}}{--}
+
diff --git a/support/splint/tex/gindex.sty b/support/splint/tex/gindex.sty
new file mode 100644
index 0000000000..9d8ed2d334
--- /dev/null
+++ b/support/splint/tex/gindex.sty
@@ -0,0 +1,522 @@
+% Copyright 2012-2020, Alexander Shibakov
+% This file is part of SPLinT
+%
+% SPLinT is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% SPLinT is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
+
+% indexing macros
+
+% set up the list of unindexable terms
+
+\ifx\unindexable\UNDEFINED
+ \def\unindexable{{$\TeXx$}{$\TeXa$}{$\TeXb$}{$\TeXf$}{$\TeXao$}{$\TeXfo$}}%
+\else
+ \expandafter\def\expandafter\unindexable\expandafter
+ {\unindexable{$\TeXx$}{$\TeXa$}{$\TeXb$}{$\TeXf$}{$\TeXao$}{$\TeXfo$}}%
+\fi
+
+\def\TeXx{\hbox{\let\_\UL\tt\TeX\_}}
+\def\TeXa{\hbox{\tt\TeX\rm(a)}}
+\def\TeXb{\hbox{\tt\TeX\rm(b)}}
+\def\TeXf{\hbox{\tt\TeX\rm(f)}}
+\def\TeXao{\hbox{\tt\TeX\rm(ao)}}
+\def\TeXfo{\hbox{\tt\TeX\rm(fo)}}
+
+% macros to determine if the current term is indexable
+
+\newif\ifindexverbose
+
+\def\yyifindexable#1{%
+ {%
+ \def\n@xt{#1}%
+ \expandafter\s@tindexable\unindexable\relax\end % the \relax is to preserve the braces
+ % in the last list element
+ }%
+}
+
+\def\s@tindexable#1#2\end{%
+ {%
+ \def\next{#1}%
+ \ifx\next\n@xt % match found, stop
+ \yybreak{\aftergroup\s@t@ndexable}%
+ \else
+ \yybreak{%
+ \yystringempty{#2}{% unindexable sequence list has been exhausted, stop
+ \aftergroup\s@t@nd@xable
+ }{% no match yet, continue
+ \aftergroup\s@tindexable
+ }%
+ }%
+ \yycontinue
+ }%
+ #2\end
+}
+
+\def\s@t@ndexable#1\end{\aftergroup\yysecondoftwo}
+
+\def\s@t@nd@xable#1\end{\aftergroup\yyfirstoftwo}
+
+% \Cee\ index entry (produced by \CWEAVE\ and typeset directly from the file)
+
+\def\I#1, #2.{%
+ \makeoneindexentry{#1}{#1}{#2}{\setxreflistplain}{\filterxrefsplain}%
+}
+
+% other language index entries (produced by \GI, \FI, and \HI macros)
+
+% the standard reference format (no page number references)
+
+\def\Ji#1#2, #3.{% #1 is the `visible key', #2 and #3 are similar to #1 and #2 in \I above
+ \makeoneindexentry{#1}{#2}{#3}{\setxreflistplain}{\filterxrefsplain}%
+}%
+
+% the `fine' reference format
+
+\def\Fi#1#2, #3.{% #1 is the `visible key', #2 and #3 are similar to #1 and #2 in \I above
+ \makeoneindexentry{#1}{#2}{#3}{\setxreflist}{\filterxrefs}%
+}%
+
+% special index entries: redirects, etc. (generated by bindx.pl)
+
+\def\Jk#1#2, #3.{%
+ \makeoneindexentry{#1}{#2}{#3}{\yyid}{\eatone}%
+}%
+
+\def\makeoneindexentry#1#2#3#4#5{% #1 is the `visible key'
+ % #2 is the term (including typesetting)
+ % #3 is the list of references
+ % #4 is the command to process #3
+ % #5 is the command to filter and process #3
+ \yyifindexable{#1}{\oneindexentry{#2}{#3}{#4}}{%
+ \ifindexverbose{\toksa{#1}\message{filtering term: \the\toksa}}\fi
+ \oneindexentryfiltered{#2}{#3}{#5}%
+ }%
+}
+
+% insert the original control sequence name after the `graphic' version (\thisnamex
+% is set by yytexlex.sty macros
+
+\def\defypostambleshowcs{{ \rm(}\hbox{\sixpoint\tt\char`\\}\.{\thisnamex}{\rm)}}%
+
+% let the author set the format for a cross reference list.
+
+\def\setxreflistplain#1{%
+ \ifacro\pdfnote#1.\else#1.\fi
+}
+
+\def\oneindexentry#1#2#3{%
+ \checkforninecs#1\9\end{%
+ \the\toksg\toksg{}% set the index section header
+ \let\defypreamble\empty
+ \let\defypostamble\defypostambleshowcs
+ \hangindent\inxhangindent\noindent\strut#1:%
+ \hskip0pt plus2em\penalty1000\hskip0pt plus-2em\relax\kern\inxaiskip
+ #3{#2}%
+ \par
+ }{%
+ \toksg{#1}%
+ }%
+}
+
+\def\filterxrefsplain#1{\setxrefsplain{\f@lterdefsplain}{#1}}
+
+\def\filterxrefs#1{\setxrefs{\f@lterdefs}{#1}}
+
+\def\oneindexentryfiltered#1#2#3{%
+ \the\toksg\toksg{}% set the index section header
+ \let\defypreamble\empty
+ \let\defypostamble\defypostambleshowcs
+ \hangindent\inxhangindent\noindent\strut#1:%
+ \hskip0pt plus2em\penalty1000\hskip0pt plus-2em\relax\kern\inxaiskip
+ #3{#2}%
+ \par
+}
+
+\def\checkforninecs#1\9#2\end{%
+ \yystringempty{#2}{\yyfirstoftwo}{\yysecondoftwo}%
+}
+
+\def\filterdefs#1#2{%
+ #1{}{}, #2, \[]{}% the last empty braces are not necessary but this way
+ % both \f@lterdefs and \f@lterdefsplain can be defined
+}
+
+\def\f@lterdefsplain#1#2#3, \[#4]{%
+ \yystringempty{#4}{ {#1}{#2}}{%
+ \yystringempty{#1}{%
+ \f@lterdefsplain{\[#4]}{#2#3}%
+ }{%
+ \f@lterdefsplain{#1, \[#4]}{#2#3}%
+ }%
+ }%
+}
+
+\def\f@lterdefs#1#2#3, \[#4]#5{%
+ \yystringempty{#4}{ {#1}{#2}}{%
+ \yystringempty{#1}{%
+ \f@lterdefs{\[#4]{#5}}{#2#3}%
+ }{%
+ \f@lterdefs{#1, \[#4]{#5}}{#2#3}%
+ }%
+ }%
+}
+
+\def\setxrefs#1#2{% typeset filtered references (with page references)
+ \expandafter\s@txrefs\romannumeral0\filterdefs{#1}{#2}%
+}
+
+\def\s@txrefs#1#2{%
+ \yystringempty{#1}{%
+ several refs.%
+ }{%
+ \setxreflist{#1}%
+ \yystringempty{#2}{}{, other refs.}%
+ }%
+}
+
+\def\setxrefsplain#1#2{% typeset filtered references (without page references)
+ \expandafter\s@txrefsplain\romannumeral0\filterdefs{#1}{#2}%
+}
+
+\def\s@txrefsplain#1#2{%
+ \yystringempty{#1}{%
+ several refs.%
+ }{%
+ \ifacro\pdfnote#1.\else#1.\fi
+ \yystringempty{#2}{}{, other refs.}%
+ }%
+}
+
+\def\setxreflist#1{%
+ \yystringempty{#1}{}{%
+ \grabfinexrefs{}, #1, {}{}%
+ }%
+}
+
+\def\grabfinexrefs#1, #2#3#{% collect (and process) fine references (i.e. references like lnnnr{p1, p2, ... }
+ \yystringempty{#2#3}{% this is the last reference, clean up (the last empty group is left unchanged)
+ \expandafter\relax\eatacomma#1%
+ }{%
+ \ifcat\noexpand#20% this is a bare number
+ \yybreak{\consumeonexref{{}{}{#1}}{#2#3}}%
+ \else % this is a qualified number
+ \yybreak{\stripxrefdelims{{#2}{#1}}{}#3}%
+ \yycontinue
+ }%
+}
+
+\def\eatacomma, {}
+
+% get the right delimeter; we assume that at least one token is present
+
+\def\stripxrefdelims#1#2#3{%
+ \ifnum`#3<`0
+ \yybreak{\consumeonexref{{#3}#1}{#2}}% this is a delimeter
+ \else
+ \ifnum`#3>`9
+ \yybreak@{\consumeonexref{{#3}#1}{#2}}% this is a delimeter
+ \else % `0<=`#4<=`9
+ \yybreak@{\stripxrefdelims{#1}{#2#3}}% keep looking for the next digit
+ \fi
+ \yycontinue
+}
+
+\ifx\consumeonexref\UNDEFINED
+ \def\consumeonexref#1#2#3{% #1 is the accumulated references
+ % #2 is the section number
+ % #3 is the list of pages
+ \addnewpair#1{#2}%
+ }
+\fi
+
+% ignore paging information
+
+\def\addnewpair#1#2#3#4{% #1 is the right delimeter
+ % #2 is the left delimeter
+ % #3 is the list of references
+ % #4 is the section number
+ \grabfinexrefs{#3, #2\compoundlink{#4}{#4}#1}%
+}
+
+
+\def\compoundlink#1#2{%
+ \ifacro
+ \pdflink{#1}{#2}%
+ \else
+ #2%
+ \fi
+}
+
+\def\pagelink#1{%
+ \ifacro
+ \pdfpagelink{#1}% use the section number
+ \else
+ #1%
+ \fi
+}
+
+% indexing macros for grammar terms
+
+\def\termidstring#1{% processed name in italics
+ \numberstocharsandspaces#1\end
+ \let\optstrextra\optstrextraesc
+ \expandafter\nameproc\expandafter{\the\toksa}\with\parsebin
+ \def\idxentry{{\it\the\toksa}}%
+}%
+
+\def\termvstring#1{% processed name in typewriter style
+ \numberstochars#1\end
+ \let\optstrextra\optstrextraesc
+ \expandafter\nameproc\expandafter{\the\toksa}\with\parsebin
+ \def\idxentry{{\tt\def\_{\char`\_}\the\toksa}}%
+}%
+
+\def\termttstring#1{% straightforward typewriter text
+ \numberstocharsandspaces#1\end
+ \def\idxentry{{\tt\the\toksa}}%
+}%
+
+\def\termhostidstring#1{% processed name in italics (using the host name parser)
+ \numberstocharsandspaces#1\end
+ \let\optstrextra\optstrextraesc
+ {%
+ \expandafter\let\expandafter\tosmallparser
+ \csname to\stripbrackets\hostparsernamespace parser\endcsname
+ \expandafter\nameproc\expandafter{\the\toksa}\with\parsebin
+ \aftergroup\toksa
+ \expandafter
+ }\expandafter{\the\toksa}%
+ \def\idxentry{{\it\the\toksa}}%
+}%
+
+\def\termhostvstring#1{% processed name in typewriter style (using the host name parser)
+ \numberstocharsandspaces#1\end
+ \let\optstrextra\optstrextraesc
+ {%
+ \expandafter\let\expandafter\tosmallparser
+ \csname to\stripbrackets\hostparsernamespace parser\endcsname
+ \expandafter\nameproc\expandafter{\the\toksa}\with\parsebin
+ \aftergroup\toksa
+ \expandafter
+ }\expandafter{\the\toksa}%
+ \def\idxentry{{\tt\def\_{\char`\_}\the\toksa}}%
+}%
+
+\def\termostring#1{% options (e.g. \flex\ and \bison\)
+ \numberstocharsandspaces#1\end
+ \def\idxentry{{$\langle$\bf\the\toksa$\rangle$}}%
+}%
+
+\def\termfsrestring#1{% flex regular expression definition names
+ \numberstocharsandspaces#1\end
+ \let\optstrextra\optstrextraesc
+ \expandafter\nameproc\expandafter{\the\toksa}\with\parsebin
+ \def\idxentry{{\def\_{\char`\_}\flexrendisplay{\the\toksa}}}%
+}%
+
+\def\termfsopstring#1{% flex option names
+ \numberstocharsandspaces#1\end
+ \let\optstrextra\optstrextraesc
+ \expandafter\nameproc\expandafter{\the\toksa}\with\parsebin
+ \def\idxentry{{\def\_{\char`\_}\hbox{\tt$\langle$\the\toksa$\rangle_{\rm f}$}}}%
+}%
+
+\def\termstring#1{%
+ \numberstocharsandspaces#1\end
+ \let\optstrextra\optstrextraesc
+ \expandafter\nameproc\expandafter{\the\toksa}\with\parsebin
+ \def\idxentry{{\tt"\the\toksa"}}%
+}%
+
+\def\termexception#1{% special names
+ \numberstocharsandspaces#1\end
+ \toksc\toksa
+ \expandafter\nameproc\expandafter{\the\toksa}\with\parsebin
+ \ifyyparsefail
+ \expandafter\ifx\csname\prettynamecs\hostparsernamespace{\the\toksa}\endcsname\relax
+ \errmessage{The name \the\toksc\space is exceptional but is not defined.}%
+ \else
+ \def\idxentry{{\it\csname\prettynamecs\hostparsernamespace{\the\toksa}\endcsname{#1}}}%
+ \fi
+ \else
+ \errmessage{The name \the\toksc\space is not exceptional.}%
+ \fi
+}%
+
+% \TeX\ conrol sequence output
+\def\texcsstring#1{%
+ \numberstocharsandspaces#1\end
+ \def\idxentry{%
+ \let\texnspace\hostparsernamespace
+ \def\getcescape{% an \ seen is really an \, and will not go through C string processing
+ \def\next{escape}%
+ \switchon\next\in\currentstate
+ }%
+ \termindexfalse\expandafter\inlineTeXx\expandafter{\expandafter/\the\toksa}%
+ }%
+}%
+
+\expandafter\def\csname acharswitch:index\endcsname{% correct reserved \TeX\ characters a la CWEB verbatim
+ %$\%\\ % unaffected
+ %\#\ % these never appear
+ _{%
+ \yybyte\expandafter{\csname \the\yybyte\endcsname}%
+ \expandafter\yycp@\expandafter`\the\yybyte\relax
+ \mkpurebyte
+ \yyreturn
+ }
+}%
+
+\expandafter\setspecialcharsfrom\csname acharswitch:index\endcsname
+
+\def\texlexerindex{% now that all character codes are 12
+ \let\default\yygetchar
+ \let\next\yycp@
+ \ifnum\yycp@>"3F %
+ \ifnum\yycp@<"5B % an uppercase letter or @
+ \def\next{letter}%
+ \fi
+ \fi
+ \ifnum\yycp@>"60 %
+ \ifnum\yycp@<"7B %
+ \def\next{letter}%
+ \fi
+ \fi
+ \switchonwithtype\next\in\currentstate
+}%
+
+\def\indexseparator#1#2{% generic separator
+ \vskip.5\baselineskip
+ \centerline{\dinkus}%
+ \vskip.5\baselineskip
+}
+
+\def\indexseparator#1#2{%
+ \vskip.3\baselineskip
+ \centerline{\csname index domain translation [#1]\endcsname}%
+ \vskip.3\baselineskip
+}
+
+\expandafter\def\csname index domain translation [F]\endcsname{{\sc FLEX INDEX}}
+\expandafter\def\csname index domain translation [T]\endcsname{{\sc\TeX\ INDEX}}
+
+\def\indexsection#1{%
+ \vskip.3\baselineskip
+ \penalty-1000
+ \hbox to \hsize{\strut\ssfbn #1\ \cdotfill}%
+ \penalty10000
+ \vskip.2\baselineskip
+}
+
+\def\9#1{%
+ \indexs@ction#1\end
+}
+
+\def\indexs@ction#1#2\end{
+ \indexsection{\uppercase{#1}}%
+}
+
+\def\otherlangindexseparator{%
+ \enddoublecols
+ \vskip.8\baselineskip
+ \centerline{B{\sc ISON}, F{\sc LEX, AND} \TeX\ {\sc INDICES}}%
+ \vskip.5\baselineskip
+ \begindoublecols
+}
+
+% general index entries (generated by bindx.pl)
+
+\def\GI#1#2#3#4.{% raw index entries (standard format, with no page references)
+ {%
+ \edef\hostparsernamespace{\yysecondoftwo#1}%
+ \edef\currentrulecontext{\yyfirstoftwo#1}%
+ \toksa{}\numberstocharsandspaces#3\end
+ \edef\indexkeyseq{\the\toksa}%
+ \toksa{}#2{#3}%
+ \expandafter\Ji\expandafter{\indexkeyseq}{\idxentry}#4.%
+ }%
+}%
+
+\def\FI#1#2#3#4.{% raw index entries (fine format)
+ {%
+ \edef\hostparsernamespace{\yysecondoftwo#1}%
+ \edef\currentrulecontext{\yyfirstoftwo#1}%
+ \toksa{}\numberstocharsandspaces#3\end
+ \edef\indexkeyseq{\the\toksa}%
+ \toksa{}#2{#3}%
+ \expandafter\Fi\expandafter{\indexkeyseq}{\idxentry}#4.%
+ }%
+}%
+
+\def\HI#1#2#3#4{% special raw index entries
+ {%
+ \def\hostparsernamespace{#2}%
+ \let\defypreamble\empty
+ \let\defypostamble\empty
+ \toksa{}\numberstocharsandspaces#4\end
+ \edef\indexkeyseq{\the\toksa}%
+ \toksa{}#3{#4}%
+ \expandafter\Jk\expandafter{\indexkeyseq}{\idxentry}, see
+ {\tt\hbox{\sixpoint\tt\char`\\}\indexkeyseq}.%
+ }%
+}%
+
+% reference styles (ordinary terms are set in roman face)
+
+\def\[#1]{{\it#1}} % term definitions (such as lhs in productions)
+\def\(#1){$\underline{#1}$} % declarations (such as token declarations), underlined index item
+\def\(#1){{\bf #1}} % declarations, an alternative to the above
+\def\e#1e{#1{\sevenpoint$^\circ\!$}} % terms in examples
+\def\f#1f{{\it#1\/\kern.2ex}${}^\circ\!$} % lhs in examples (italic correction does not seem to be enough)
+\def\g#1g{$\underline{#1}^\circ\!$} % declarations in examples
+\def\g#1g{{\bf #1}$^\circ\!$} % declarations in examples, an alternative to the above
+
+\def\inxhangindent{1em}
+\def\inxaiskip{.5em}
+\def\inxicgap{5pt}
+
+\def\inxmod{% new indexing macro
+ \write\cont{} % ensure that the contents file isn't empty
+ \write\cont{\catcode `\noexpand\@=12\relax} % \makeatother
+ \closeout\cont % the contents information has been fully gathered
+ \message{Index:}
+ \medskip
+ \eightpoint\raggedright
+ \fnotesstart=2
+ \fnotesspan=1
+ \noofcolumns=3
+ \icgap=\inxicgap%
+ \linecount=3
+ \setmcparams
+ \dsskip=0pt%
+ \adjskip=0pt plus 9pt%
+ % \TeX\ conrol sequence output
+ \expandafter\let\expandafter\acharswitch\csname acharswitch:index\endcsname
+ \let\texlexer\texlexerindex
+ \let\*=\lapstar
+ \begindoublecols
+ \readindex
+ \otherlangindexseparator
+ \readgindex
+}
+
+\newread\trygindex
+
+\def\readgindex{%
+ \openin\trygindex=\jobname.gdy
+ \ifeof\trygindex
+ \else
+ \closein\trygindex
+ \input \jobname.gdy
+ \fi
+}
diff --git a/support/splint/tex/grabstates.sty b/support/splint/tex/grabstates.sty
index 6fa805168a..1024d99432 100644
--- a/support/splint/tex/grabstates.sty
+++ b/support/splint/tex/grabstates.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2015, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -18,15 +18,27 @@
\input yycommon.sty % general routines for stack and array access
\input yymisc.sty % helper macros (stack manipulation, table processing, value stack pointers)
+ % parser initialization, optimization
\input yyinput.sty % input functions
\input yyparse.sty % parser machinery
\input flex.sty % lexer functions
\input yyfaststack.sty % sped up stack access functions
-\input yyboth.sty % parser initialization, optimization
\input yyunion.sty
+\def\yycomplain#1{\immediate\write16{#1}} % lexer errors
+
+% modify the input routine to recognize \yyendgame; the somewhat verbose end of
+% the section is necessary to gracefully handle parser failures: the \endparse
+% control sequence must appear outside of any \vb block for \cleanupparse
+% to do its job; the \yyinput reads \vb blocks in pairs so the closing \vb{} is
+% necessary and is removed by \removefinalvb (see limbo.sty and brack.pl for
+% details).
+
+\expandafter\def\expandafter\multicharswitch\expandafter
+{\multicharswitch\yyendgame{\yyinput\yyeof\yyeof\endparseinput\removefinalvb}}
+
\genericparser
- name: main,
+ name: grabstates,
ptables: cweb/byytab.tex,
ltables: cweb/lstab.tex,
tokens: {},
@@ -35,35 +47,54 @@
rsetup: {},
optimization: \optimizeall;%
-\let\parsernamespace\mainnamespace
+\let\parsernamespace\grabstatesnamespace
\let\yylexreturn\yylexreturnregular
-% main section macro
+% stage two parsing macros
\let\nx\noexpand
-\expandafter\def\csname parserstack[b]\endcsname#1#2{%
- \basicparserinit\yyparse#1\yyeof\yyeof\endparseinput\endparse
- \ifyyparsefail % do nothing if parsing failed
- \yybreak{}%
- \else % Stage three, process the parsed table
- \yybreak{%
- \restorecslist{bootstrap}\yyunion
- \the\table\relax
- }%
- \yycontinue
+\def\preparsegrabstates{%
+ \let\postparse\postparsegrabstates
+ \basicparserinit
+ \yyparse
}
-\expandafter\def\csname parserstack[]\endcsname#1#2{%
- \basicparserinit\yyparse#1\yyeof\yyeof\endparseinput\endparse
+\def\postparsegrabstates{%
\ifyyparsefail % do nothing if parsing failed
\yybreak{}%
\else % Stage three, process the parsed table
\yybreak{%
- \restorecslist{bootstrap}\yyunion
+ \restorecslist{bootstrap}\yyunion % TODO: this will not work in fs1 sections
\the\table\relax
}%
\yycontinue
}
+\fillpstack{b}{%
+ \preparsegrabstates
+ \relax
+}
+
+\fillpstack{fs1}{%
+ \preparsegrabstates
+ \relax
+}
+
+% ignore in text production examples (there is no way or need to parse them anyway)
+
+\long\def\beginprod#1\endprod{}
+
+\let\begincprod\beginprod
+
+\def\nameproc#1\with#2{%
+ #2{}{}{}{}{}% pretend the name is empty
+}
+
+\def\frexproc#1\with#2{%
+ #2{}{}{}% pretend the regex is empty
+}
+
+\def\prodstyle#1{}
+
\newwrite\stlist
diff --git a/support/splint/tex/hext.sty b/support/splint/tex/hext.sty
new file mode 100644
index 0000000000..433d53ac5c
--- /dev/null
+++ b/support/splint/tex/hext.sty
@@ -0,0 +1,346 @@
+% macros to typeset hex values in customized form (useful when typesetting embedded code)
+
+% the line translator: take a sequence of tokens and translate it into another sequence
+% #1 is the sequence of tokens (will be expanded) to insert at the beginning
+% #2 is the sequence of tokens (will be expanded) to insert before every token in the sequence
+% #3 is the first sequence of tokens (will be expanded) to insert between tokens in the sequence
+% #4 is the second sequence of tokens (will be expanded) to insert between tokens in the sequence
+% #5 is the sequence of tokens (will be expanded) to insert at the end
+% #6 is the command to execute after each token
+% #7 is original sequence
+% #8 is the resulting sequence
+
+\def\linetranslator#1#2#3#4#5#6:#7>#8{%
+ \def\ins@rt{#2}\def\insert@{#3}\def\@insert{#4}%
+ \def\@nd{#5}\def\c@mmand{#6}\let\t@kens#8%
+ \edef\next{\t@kens{\the\t@kens#1}}\next
+ \expandafter\linetr@nslator\the#7\end}
+
+\def\linetr@nslator#1#2{%
+ \ifx#1\end
+ \let\next\relax % no more tokens left
+ \else
+ \ifx#2\end % #1 is the last token
+ \edef\next{\t@kens{\the\t@kens\ins@rt#1\@nd}}\next
+ \else
+ \edef\next{\t@kens{\the\t@kens\ins@rt#1\insert@\@insert}}\next
+ \c@mmand
+ \fi
+ \let\next\linetr@nslator
+ \fi\next#2
+}
+
+% the mask translator: take a sequence of pairs {length:number}{contents} and translate it into another sequence
+% #1 is the sequence of tokens (will be expanded) to insert at the beginning
+% #2 is the sequence of tokens (will be expanded) to insert before every pair in the sequence
+% #3 is the first sequence of tokens (will be expanded) to insert between pairs in the sequence
+% #4 is the second sequence of tokens (will be expanded) to insert between pairs in the sequence
+% #5 is the sequence of tokens (will be expanded) to insert at the end
+% #6 is the command to execute after each pair
+% #7 is original sequence
+% #8 is the resulting sequence
+
+\def\masktranslator#1#2#3#4#5#6:#7>#8{%
+ \def\ins@rt{#2}\def\insert@{#3}\def\@insert{#4}%
+ \def\@nd{#5}\def\c@mmand{#6}\let\t@kens#8%
+ \edef\next{\t@kens{\the\t@kens#1}}\next
+ \m@sktranslator#7{"40000000}\relax\relax}
+
+\def\m@sktranslator#1#2#3{%
+ \ifnum#1<"40000000 % only happens when there are no pairs
+ \ifnum#3<"40000000 % not the last pair
+ \edef\next{\t@kens{\the\t@kens\ins@rt{#1}{#2}\insert@\@insert}}\next
+ \c@mmand
+ \let\next\m@sktranslator
+ \else
+ \edef\next{\t@kens{\the\t@kens\ins@rt{#1}{#2}\@nd}}\next
+ \let\next\m@sktr@nslator
+ \fi
+ \else
+ \let\next\m@sktr@nslator
+ \fi
+ \next{#3}%
+}
+
+\def\m@sktr@nslator#1{}
+
+% binary converter
+
+\def\binary#1{%
+ \ifx#1\end
+ \let\next\relax
+ \else
+ \bin@ry#1\let\next\binary
+ \fi\next}
+
+\let\bits\toksa % storage for binary conversion bits
+\newtoks\bytes % storage for the binary representation
+\let\quotient\tempca
+\let\oldquotient\tempcb
+
+\def\bin@ry#1{\bits{}\tempcc=4 \quotient="#1 \oldquotient=\quotient
+\loop \divide\quotient by2 \multiply\quotient by2 \advance\oldquotient by-\quotient
+ \advance\tempcc by\m@ne
+ \edef\next{\bits{\the\oldquotient\the\bits}}\next
+ \divide\quotient by2 \oldquotient=\quotient
+\ifnum\tempcc > \z@
+\repeat
+\edef\next{\bytes{\the\bytes\the\bits}}\next}
+
+% display macros:
+%
+% o registers
+
+\newtoks\digittable % the table representing the register
+\newcount\columncount % counter for the current column
+
+% o fonts
+
+\font\fivessb=phvb at4pt
+
+% o generic control sequences
+
+\def\incrementcc{\advance\columncount by\@ne}
+\def\decrementcc{\advance\columncount by\m@ne}
+
+% o mask highlighting
+
+% the strange looking definition of \m@skspan originates from \multispan in plain.tex:
+% \newcount\mscount
+% \def\multispan#1{\omit \mscount#1\relax
+% \loop\ifnum\mscount>\@ne \sp@n\repeat}
+% \def\sp@n{\span\omit\advance\mscount\m@ne}
+%
+% the number of `physical' columns to span is (2 * columns - 1) due to the fact that we
+% have to span the gaps between columns as well.
+
+\def\m@skspan#1#2{%
+ \multispan{#1\advance\mscount by\mscount\advance\mscount by-1}{\vrule\highltcl{\leaders\hrule height 4pt\hfil}\vrule}%
+}
+
+% o mask underlining
+
+\def\m@sksp@n#1#2{%
+ \multispan{#1\advance\mscount by\mscount\advance\mscount by-1}{\hrulefill}%
+}
+
+% o mask legend typesetting
+
+\def\m@sklegend#1#2{%
+ \multispan{#1\advance\mscount by\mscount\advance\mscount by-1}{\hfil\lgndcl{\fivessb#2}\hfil}%
+}
+
+% o displaying each digit
+
+\def\dgtdispl@y#1#2{%
+ \ifx#20%
+ \let\colorbg\lightcl\let\colord\darkcl
+ \else
+ \let\colorbg\darkcl\let\colord\lightcl
+ \fi
+ \vrule\colorbg{\vrule height4pt width 12.5pt}%
+ \llap{\raise.6pt\hbox{\colord{\fivessb#1}$\,$}}\vrule
+}
+
+% o typesetting space between digits
+
+\def\c@lumnspacer#1{\tempca#1\tempcb\tempca\divide\tempca by8\multiply\tempca by8
+ \ifnum\tempca=\tempcb
+ \middlediamond
+ \else
+ \tempca#1\tempcb\tempca\divide\tempca by4\multiply\tempca by4
+ \ifnum\tempca=\tempcb
+ \middledot
+ \else
+ \hfil
+ \fi
+ \fi}
+
+% oo dimond to separate bytes
+
+\def\middlediamond{\setbox0=\hbox{$\scriptscriptstyle\diamond$}\tempda=4pt \advance\tempda by-\ht0
+ \divide\tempda by2 \hss\raise\tempda\box0\hss}%
+
+% oo dot to separate nybbles
+
+\def\middledot{\setbox0=\hbox{.}\tempda=4pt \advance\tempda by-\ht0
+ \divide\tempda by2 \hss\raise\tempda\box0\hss}%
+
+% o put it all together
+
+\let\stcr\cr % so that this can be used inside \tabalign which redef's \cr
+
+\def\regdisplay#1#2{{%
+ \binary#1\end
+ \linetranslator{}{\hrulefill\noexpand\eatone}{&$\,\,$}{&}{\stcr}{\incrementcc}:\bytes>\digittable
+ \linetranslator{}{\noexpand\dgtdispl@y{\the\columncount}}{&\noexpand\c@lumnspacer{\the\columncount}}{&}%
+ {\stcr}{\decrementcc}:\bytes>\digittable
+ \masktranslator{}{\noexpand\m@sksp@n}{&\hfil}{&}{\stcr}{\relax}:{#2}>\digittable
+ \masktranslator{}{\noexpand\m@skspan}{&\hfil}{&}{\stcr}{\relax}:{#2}>\digittable
+ \masktranslator{}{\noexpand\m@sksp@n}{&\hfil}{&}{\stcr}{\relax}:{#2}>\digittable
+ \expandafter\digittable\expandafter{\the\digittable\noalign{\vskip-3.8pt}}%
+ \masktranslator{}{\noexpand\m@sklegend}{&\hfil}{&}{\stcr}{\relax}:{#2}>\digittable
+ \vbox{\offinterlineskip
+ \halign{&##\stcr
+ \the\digittable
+ }
+ }%
+}}
+
+% colors
+
+\newif\iffullcolorpalette
+\fullcolorpalettetrue
+
+\iffullcolorpalette
+ \let\lightcl=\colorpeach
+ \let\shadedcl=\colorcorn
+ \let\highltcl=\colorgray
+ \let\lgndcl=\colorwhite
+\else
+ \let\lightcl=\colorwhite
+ \let\shadedcl=\colorgray
+ \let\highltcl=\colorwhite
+ \let\lgndcl=\colorblack
+% \let\colorlinkstart=\begingroup
+% \let\colorlinkend=\endgroup
+\fi
+ \let\darkcl=\colorblack
+
+% an alternate display
+
+\def\altmiddledot{\setbox0=\hbox{.}%
+ \tempda=\ht\thezero \advance\tempda by-\ht0
+ \divide\tempda by2 \advance\tempda by -\dp\thezero
+ $\,$\raise\tempda\box0$\,$%
+}
+
+\def\altmiddlediamond{\setbox0=\hbox{$\scriptscriptstyle\diamond$}%
+ \tempda=\ht\thezero \advance\tempda by-\ht0
+ \divide\tempda by2 \advance\tempda by -\dp\thezero
+ \hss\raise\tempda\box0\hss
+}
+
+\def\altdgtdispl@y#1#2{%
+ \ifx#20%
+ \let\colorbg\lightcl\let\colord\darkcl
+ \else
+ \let\colorbg\darkcl\let\colord\lightcl
+ \fi
+ \setbox0=\hbox{$\,$0$\,$}\tempda\ht0
+ \advance\tempda by 2pt \ht0\tempda
+ \vrule\colorbg{\lower1pt\hbox{\vrule height\ht0 depth\dp0 width \wd0}}%
+ \llap{\colord{\raise.5pt\hbox{\fivessb#1$\,$}}}\vrule
+}
+
+\def\altc@lumnspacer#1{\tempca#1\tempcb\tempca
+ \divide\tempca by4\multiply\tempca by4
+ \ifnum\tempca=\tempcb
+ \ %
+ \else
+ \kern1pt%
+ \fi
+}
+
+\def\bytedisplay#1{{%
+ \binary#1\end
+ \linetranslator{}{\hrulefill\noexpand\eatone}{&\hfil}{&}{\stcr}{\incrementcc}:\bytes>\digittable
+ \linetranslator{}{\noexpand\altdgtdispl@y{\the\columncount}}{&\noexpand\altc@lumnspacer{\the\columncount}}{&}%
+ {\stcr}{\decrementcc}:\bytes>\digittable
+ \linetranslator{}{\hrulefill\noexpand\eatone}{&\hfil}{&}{\stcr}{\incrementcc}:\bytes>\digittable
+ \lower\dp\thezero\vbox{\offinterlineskip
+ \halign{&##\stcr
+ \the\digittable
+ }
+ }%
+}}
+
+% macros to typeset the hex numbers in `graphic' format
+
+\newtoks\registerlegend
+
+\def\registerdisplay#1\end{\edef\next{\the\registerlegend}%
+ \ifx\next\empty
+ \edef\next{\noexpand\bytedisplay{#1}}\next
+ \else
+ \edef\next{\noexpand\regdisplay{#1}{\the\registerlegend}}\next
+ \fi
+}
+
+\newbox\thezero
+
+\setbox\thezero=\hbox{\lower1pt\hbox{\vbox{\offinterlineskip
+\halign{#&$\,$#$\,$&#\cr
+\noalign{\hrule}
+\omit\vrule height1pt&&\omit\vrule height1pt\cr
+\vrule&\phantom0&\vrule\cr
+\omit\vrule height1pt&&\omit\vrule height1pt\cr
+\noalign{\hrule}
+}}}}
+
+\def\texbinary{\global\let\oldT\T
+ \global\def\T##1{{\let\end\relax\let\^\registerdisplay##1\end{\tt :}\let\^\hexify##1\end}}}
+
+\def\endtexbinary{\global\let\T\oldT}
+
+\def\hexify#1\end{\hbox{{\tt #1}$_{\scriptscriptstyle1\kern-.7pt6}$}}
+
+% delay functions prettyprinting and other miscellanea;
+
+\def\delayhalfsec{\hbox{wait \kern-.5pt\raise1pt\hbox{$\scriptstyle1$}%
+\kern-1pt/\kern-1pt\lower1pt\hbox{$\scriptstyle2$} sec, }}
+\def\delayquartersec{\hbox{wait \kern-.5pt\raise1pt\hbox{$\scriptstyle1$}%
+\kern-1pt/\kern-1pt\lower1pt\hbox{$\scriptstyle4$} sec, }}
+
+\def\delay#1sec{%
+\hbox{\def\secmult{}wait
+\getsecmult#1\end
+\if\secmult u\def\secmodifier{ $\mu$\kern.05pt }\else
+\if\secmult m\def\secmodifier{ m}\else
+\if\secmult n\def\secmodifier{ n}\else
+ \secmult\def\secmodifier{ }%
+\fi\fi\fi
+\secmodifier sec$\rm\scriptstyle s$, }
+}
+
+\def\getsecmult#1{%
+\ifx#1\end\let\next\relax\else
+ \secmult\def\secmult{#1}\let\next\getsecmult
+\fi\next
+}
+
+% attribute prettyprinting;
+
+\long\def\parseattrib#1#2\end{\csname attrib#1\endcsname}
+
+\def\xxattributexx#1{\ifx(#1\let\next\xxattributex\else\let\next\xxattribute\fi\next#1}
+\def\xxattributex((\\#1{%
+ \expandafter\let\expandafter\currentattrib\csname attrib#1\endcsname
+ \ifx\currentattrib\attribpacked
+ \strut\colorblack{%
+ \lower2pt\hbox{\vrule width \wd\thezero height
+ \ht\thezero depth
+ \dp\thezero}}\llap{\colorwhite{\hbox{$\scriptscriptstyle\bf 01\kern.5pt$}}}%
+ \let\next\eatparentheses
+ \fi
+ \ifx\currentattrib\attribnoinline
+ {\ \bf noinline\rm_a}%
+ \let\next\eatparentheses
+ \fi
+ \ifx\currentattrib\attribformat
+ {\ \bf format\rm_a}%
+ \let\next\eatarguments
+ \fi
+ \next
+}
+
+\def\eatparentheses#1)){}
+\def\eatarguments(\\#1,#2,#3))){(\hbox{\rm as }\.{#1})}
+
+\def\xxattribute#1{\.{\_\_attribute\_\_} (\sc GNU) #1}
+
+\let\attribnoinline=1
+\let\attribpacked=2
+\let\attribformat=3
+
+%\registerlegend{{8}{\noexpand\phantom{B}}}
diff --git a/support/splint/tex/limbo.sty b/support/splint/tex/limbo.sty
index 1ab76629a4..c810cd55da 100644
--- a/support/splint/tex/limbo.sty
+++ b/support/splint/tex/limbo.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2015, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -14,7 +14,7 @@
% You should have received a copy of the GNU General Public License
% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
-% limbo.sty version 2.3
+% limbo.sty version 3.0
\input epsf.tex
\input amssym.def
@@ -52,9 +52,29 @@
\font\seventitle=cmssbx7
\font\titlefrak=eufb10 at 12pt
+%\font\eightss=cmssq8
+%\font\eightssi=cmssqi8
+
\font\tenss=cmss10
\font\niness=cmss9
\font\eightss=cmss8
+\font\sevenss=cmss7
+\font\sixss=cmss6
+\font\fivess=cmss5
+
+\font\tenssn=cmssdc10
+\font\ninessn=cmssdc9
+\font\eightssn=cmssdc8
+\font\sevenssn=cmssdc7
+\font\sixssn=cmssdc6
+\font\fivessn=cmssdc5
+
+\font\tenssb=cmssbx10
+\font\ninessb=cmssbx9
+\font\eightssb=cmssbx8
+\font\sevenssb=cmssbx7
+\font\sixssb=cmssbx6
+\font\fivessb=cmssbx5
\font\twelvetitleit=cmssbxo10 at 12pt
\font\ninetitleit=cmssbxo10 at 9pt
@@ -75,10 +95,11 @@
\font\ninerm=cmr9
\font\eightrm=cmr8
\font\sevenrm=cmr7
+\font\sixrm=cmr6
+
\font\ninecyr=lhr9
\font\eightcyr=lhr8
\font\sevencyr=lhr7
-\font\sixrm=cmr6
\font\ninei=cmmi9
\font\eighti=cmmi8
@@ -90,10 +111,6 @@
\font\sixsy=cmsy6
\skewchar\ninesy='60 \skewchar\eightsy='60 \skewchar\sixsy='60
-\font\eightss=cmssq8
-
-\font\eightssi=cmssqi8
-
\font\twelvebf=cmbx12
\font\ninebf=cmbx9
\font\eightbf=cmbx8
@@ -102,6 +119,13 @@
\font\ninett=cmtt9
\font\eighttt=cmtt8
\font\seventt=cmtt7
+\font\sixtt=cmtt6
+
+\font\tentti=cmitt10 % typewriter italic
+\font\ninetti=cmitt9
+\font\eighttti=cmitt8
+\font\seventti=cmitt7
+\font\sixtti=cmitt6
\hyphenchar\tentt=-1 % inhibit hyphenation in typewriter type
\hyphenchar\ninett=-1
@@ -110,6 +134,7 @@
\font\ninesl=cmsl9
\font\eightsl=cmsl8
\font\sevensl=cmsl7
+\font\sixsl=cmsl6
\font\nineit=cmti9
\font\eightit=cmti8
@@ -137,11 +162,19 @@
\font\ninefrak=eufm9
\font\eightfrak=eufm8
\font\sevenfrak=eufm7
+\font\sixfrak=eufm6
\font\hv=phvr
+\font\dings=pzdr
+\font\dingssmall=pzdr at 8pt
+\chardef\pen='062
+\chardef\leaf='247
+\chardef\fancystar='122
+
+\newfam\ssfam
+\newfam\ssbnfam
\newfam\itbfam
-\newfam\frakfam
\newfam\msbmfam
\newfam\msamfam
@@ -183,26 +216,35 @@
\let\{=\LB % left brace in a string
\let\}=\RB % right brace in a string
}%
+ \def\tti{\fam\ttfam\tentti % switch to typewriter italic
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ }%
\def\ttex{\tentex
\let\{=\LB % left brace in a string
\let\}=\RB % right brace in a string
}%
\def\ttl{\let\it\tentitlei\let\sl\tentitlei\tentitle}%
- \def\ssf{\tenss}%
+ \def\ssf{\fam\ssfam\tenss}%
+ \textfont\ssfam=\tenss\scriptfont\ssfam=\sevenss
+ \def\ssfb{\fam\ssfam\tenssb}%
+ \def\ssfbn{\fam\ssbnfam\tenssb}%
+ \textfont\ssbnfam=\tenssn\scriptfont\ssfam=\sevenssn
\textfont\ttfam=\tentt
- \tt \ttglue=.5em plus.25em minus.15em
+ \fam\ttfam\tentt \ttglue=.5em plus.25em minus.15em
\def\Bbb{\fam\msbmfam\tenmsbm}%
\textfont\msbmfam=\tenmsbm\scriptfont\msbmfam=\sevenmsbm \scriptscriptfont\msbmfam=\fivemsbm
\textfont\msamfam=\tenmsam\scriptfont\msamfam=\sevenmsam
\scriptscriptfont\msamfam=\fivemsam
- \textfont\frakfam=\tenfrak
- \def\frak##1{{\fam\frakfam\tenfrak ##1}}%
+ \def\frak##1{{\tenfrak ##1}}%
\normalbaselineskip=12pt
\let\sc=\eightrm
+ \let\sci=\eightit
\let\mc=\ninerm
\let\cyr=\tencyr
\let\big=\tenbig
\setbox\strutbox=\hbox{\vrule height8.5pt depth3.5pt width0pt}%
+ \let\sscmd\sevenpoint
\normalbaselines\rm}
\def\ninepoint{\def\rm{\fam0\ninerm}%
@@ -223,26 +265,36 @@
\let\{=\LB % left brace in a string
\let\}=\RB % right brace in a string
}%
+ \def\tti{\fam\ttfam\ninetti % switch to typewriter italic
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ }%
\def\ttex{\ninetex
\let\{=\LB % left brace in a string
\let\}=\RB % right brace in a string
}%
\def\ttl{\let\it\ninetitleit\let\sl\ninetitleit\ninetitle}%
- \def\ssf{\niness}%
+ \def\ssf{\fam\ssfam\niness}%
+ \textfont\ssfam=\niness\scriptfont\ssfam=\sixss
+ \def\ssfb{\fam\ssfam\ninessb}%
+ %no room for another font family
+ \def\ssfbn{\fam\ssbnfam\ninessn}%
+ \textfont\ssbnfam=\ninessn\scriptfont\ssbnfam=\sixssn
\textfont\ttfam=\ninett
- \tt \ttglue=.5em plus.25em minus.15em
+ \fam\ttfam\ninett \ttglue=.5em plus.25em minus.15em
\def\Bbb{\fam\msbmfam\ninemsbm}%
\textfont\msbmfam=\ninemsbm\scriptfont\msbmfam=\sixmsbm \scriptscriptfont\msbmfam=\fivemsbm
\textfont\msamfam=\ninemsam\scriptfont\msamfam=\sixmsam
\scriptscriptfont\msamfam=\fivemsam
- \textfont\frakfam=\ninefrak
- \def\frak##1{{\fam\frakfam\ninefrak ##1}}%
+ \def\frak##1{{\ninefrak ##1}}%
\normalbaselineskip=11pt
\let\sc=\sevenrm
+ \let\sci\sevenit
\let\mc=\eightrm
\let\cyr=\ninecyr
\let\big=\ninebig
\setbox\strutbox=\hbox{\vrule height8pt depth3pt width0pt}%
+ \let\sscmd\sixpoint
\normalbaselines\rm}
\def\eightpoint{\def\rm{\fam0\eightrm}%
@@ -262,24 +314,34 @@
\let\{=\LB % left brace in a string
\let\}=\RB % right brace in a string
}%
+ \def\tti{\fam\ttfam\eighttti % switch to typewriter italic
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ }%
\def\ttex{\eighttex
\let\{=\LB % left brace in a string
\let\}=\RB % right brace in a string
}%
\textfont\ttfam=\eighttt
- \tt \ttglue=.5em plus.25em minus.15em
+ \fam\ttfam\eighttt \ttglue=.5em plus.25em minus.15em
+ \def\ssf{\fam\ssfam\eightss}%
+ \textfont\ssfam=\eightss\scriptfont\ssfam=\sixss
+ \def\ssfb{\fam\ssfam\eightssb}%
+ \def\ssfbn{\fam\ssbnfam\eightssb}%
+ \textfont\ssbnfam=\eightssn\scriptfont\ssbnfam=\sixssn
\def\Bbb{\fam\msbmfam\eightmsbm}%
\textfont\msbmfam=\eightmsbm\scriptfont\msbmfam=\sixmsbm \scriptscriptfont\msbmfam=\fivemsbm
\textfont\msamfam=\eightmsam\scriptfont\msamfam=\sixmsam
\scriptscriptfont\msamfam=\fivemsam
- \textfont\frakfam=\eightfrak
- \def\frak##1{{\fam\frakfam\eightfrak ##1}}%
+ \def\frak##1{{\eightfrak ##1}}%
\normalbaselineskip=9pt
\let\sc=\sixrm
+ \let\sci=\sixit
\let\mc=\sevenrm
\let\cyr=\eightcyr
\let\big=\eightbig
\setbox\strutbox=\hbox{\vrule height7pt depth2pt width0pt}%
+ \let\sscmd\sixpoint
\normalbaselines\rm}
\def\sevenpoint{\def\rm{\fam0\sevenrm}%
@@ -298,21 +360,92 @@
\let\{=\LB % left brace in a string
\let\}=\RB % right brace in a string
}%
+ \def\tti{\fam\ttfam\seventti % switch to typewriter italic
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ }%
\textfont\ttfam=\seventt
- \tt \ttglue=.5em plus.25em minus.15em
+ \fam\ttfam\seventt \ttglue=.5em plus.25em minus.15em
+ \def\ssf{\fam\ssfam\sevenss}%
+ \textfont\ssfam=\sevenss\scriptfont\ssfam=\sixss
+ \def\ssfb{\fam\ssfam\sevenssb}%
+ \def\ssfbn{\fam\ssbnfam\sevenssb}%
+ \textfont\ssbnfam=\sevenssn\scriptfont\ssbnfam=\sixssn
\def\Bbb{\fam\msbmfam\sevenmsbm}%
\textfont\msbmfam=\sevenmsbm\scriptfont\msbmfam=\sixmsbm \scriptscriptfont\msbmfam=\fivemsbm
\textfont\msamfam=\sevenmsam\scriptfont\msamfam=\sixmsam
\scriptscriptfont\msamfam=\fivemsam
- \textfont\frakfam=\sevenfrak
- \def\frak##1{{\fam\frakfam\sevenfrak ##1}}%
+ \def\frak##1{{\sevenfrak ##1}}%
\normalbaselineskip=8pt
\let\sc=\sixrm
+ \let\sci=\sixit
\let\mc=\sixrm
\let\big=\sevenbig
\setbox\strutbox=\hbox{\vrule height6pt depth2pt width0pt}%
\normalbaselines\rm}
+\def\sixpoint{\def\rm{\fam0\sixrm}%
+ \textfont0=\sixrm \scriptfont0=\fiverm \scriptscriptfont0=\fiverm
+ \textfont1=\sixi \scriptfont1=\fivei \scriptscriptfont1=\fivei
+ \textfont2=\sixsy \scriptfont2=\fivesy \scriptscriptfont2=\fivesy
+ \textfont3=\tenex \scriptfont3=\tenex \scriptscriptfont3=\tenex
+ \def\it{\fam\itfam\sixit}%
+ \def\itbold{\fam\itbfam\sixboldi}%
+ \textfont\itfam=\sixit
+ \def\sl{\fam\slfam\sixsl}%
+ \textfont\slfam=\sixsl
+ \def\bf{\fam\bffam\sixbf}%
+ \textfont\bffam=\sixbf \scriptfont\bffam=\fivebf\scriptscriptfont\bffam=\fivebf
+ \def\tt{\fam\ttfam\sixtt
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ }%
+ \def\tti{\fam\ttfam\sixtti % switch to typewriter italic
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ }%
+ \textfont\ttfam=\sixtt
+ \fam\ttfam\sixtt \ttglue=.5em plus.25em minus.15em
+ \def\ssf{\fam\ssfam\sixss}%
+ \textfont\ssfam=\sixss\scriptfont\ssfam=\fivess
+ \def\ssfb{\fam\ssfam\sixssb}%
+ \def\ssfbn{\fam\ssbnfam\sixssb}%
+ \textfont\ssbnfam=\sixssn\scriptfont\ssbnfam=\fivessn
+ \def\Bbb{\fam\msbmfam\sixmsbm}%
+ \textfont\msbmfam=\sixmsbm\scriptfont\msbmfam=\fivemsbm \scriptscriptfont\msbmfam=\fivemsbm
+ \textfont\msamfam=\sixmsam\scriptfont\msamfam=\fivemsam
+ \scriptscriptfont\msamfam=\fivemsam
+ \def\frak##1{{\sixfrak ##1}}%
+ \normalbaselineskip=8pt
+ \let\sc=\sixrm
+ \let\sci=\sixit
+ \let\mc=\sixrm
+ \let\big=\sixbig
+ \setbox\strutbox=\hbox{\vrule height5.5pt depth1.5pt width0pt}%
+ \normalbaselines\rm}
+
+\def\em{\let\tt\tti\let\sc\sci\it}
+
+% fonts for the chapter titles
+
+\font\cmhuge=cmssbx10 at .7in
+\font\tthuge=cmtt10 at .7 in
+
+\font\cmmiddle=cmss10 at .3in
+\font\ttmiddle=cmtt10 at .3in
+
+\def\hugetitle{%
+ \let\ssf\cmhuge
+ \let\tt\tthuge
+ \ssf
+}
+
+\def\midtitle{%
+ \let\ssf\cmmiddle
+ \let\tt\ttmiddle
+ \ssf
+}
+
% temporary registers
\input trt1.sty
@@ -416,244 +549,10 @@
\raise\ht\strutbox\vbox to 0pt{\vss\hbox to 0pt{\pdfdest name {#1} xyz}}%
\fi}
-% macros to typeset hex values in customized form (useful when typesetting embedded code)
-
-% the line translator: take a sequence of tokens and translate it into another sequence
-% #1 is the sequence of tokens (will be expanded) to insert at the beginning
-% #2 is the sequence of tokens (will be expanded) to insert before every token in the sequence
-% #3 is the first sequence of tokens (will be expanded) to insert between tokens in the sequence
-% #4 is the second sequence of tokens (will be expanded) to insert between tokens in the sequence
-% #5 is the sequence of tokens (will be expanded) to insert at the end
-% #6 is the command to execute after each token
-% #7 is original sequence
-% #8 is the resulting sequence
-
-\def\linetranslator#1#2#3#4#5#6:#7>#8{%
- \def\ins@rt{#2}\def\insert@{#3}\def\@insert{#4}%
- \def\@nd{#5}\def\c@mmand{#6}\let\t@kens#8%
- \edef\next{\t@kens{\the\t@kens#1}}\next
- \expandafter\linetr@nslator\the#7\end}
-
-\def\linetr@nslator#1#2{%
- \ifx#1\end
- \let\next\relax % no more tokens left
- \else
- \ifx#2\end % #1 is the last token
- \edef\next{\t@kens{\the\t@kens\ins@rt#1\@nd}}\next
- \else
- \edef\next{\t@kens{\the\t@kens\ins@rt#1\insert@\@insert}}\next
- \c@mmand
- \fi
- \let\next\linetr@nslator
- \fi\next#2
-}
-
-% the mask translator: take a sequence of pairs {length:number}{contents} and translate it into another sequence
-% #1 is the sequence of tokens (will be expanded) to insert at the beginning
-% #2 is the sequence of tokens (will be expanded) to insert before every pair in the sequence
-% #3 is the first sequence of tokens (will be expanded) to insert between pairs in the sequence
-% #4 is the second sequence of tokens (will be expanded) to insert between pairs in the sequence
-% #5 is the sequence of tokens (will be expanded) to insert at the end
-% #6 is the command to execute after each pair
-% #7 is original sequence
-% #8 is the resulting sequence
-
-\def\masktranslator#1#2#3#4#5#6:#7>#8{%
- \def\ins@rt{#2}\def\insert@{#3}\def\@insert{#4}%
- \def\@nd{#5}\def\c@mmand{#6}\let\t@kens#8%
- \edef\next{\t@kens{\the\t@kens#1}}\next
- \m@sktranslator#7{"40000000}\relax\relax}
-
-\def\m@sktranslator#1#2#3{%
- \ifnum#1<"40000000 % only happens when there are no pairs
- \ifnum#3<"40000000 % not the last pair
- \edef\next{\t@kens{\the\t@kens\ins@rt{#1}{#2}\insert@\@insert}}\next
- \c@mmand
- \let\next\m@sktranslator
- \else
- \edef\next{\t@kens{\the\t@kens\ins@rt{#1}{#2}\@nd}}\next
- \let\next\m@sktr@nslator
- \fi
- \else
- \let\next\m@sktr@nslator
- \fi
- \next{#3}%
+\def\pdfpagelink#1{% reference the page number
+ \pdfstartlink attr {/Border [0 0 0]} goto page #1 {/XYZ null null null}\BlueGreen#1\Black\pdfendlink
}
-\def\m@sktr@nslator#1{}
-
-% binary converter
-
-\def\binary#1{%
- \ifx#1\end
- \let\next\relax
- \else
- \bin@ry#1\let\next\binary
- \fi\next}
-
-\let\bits\toksa % storage for binary conversion bits
-\newtoks\bytes % storage for the binary representation
-\let\quotient\tempca
-\let\oldquotient\tempcb
-
-\def\bin@ry#1{\tempcc=4 \quotient="#1 \oldquotient=\quotient
-\loop \divide\quotient by2 \multiply\quotient by2 \advance\oldquotient by-\quotient
- \advance\tempcc by\m@ne
- \edef\next{\bits{\the\oldquotient\the\bits}}\next
- \divide\quotient by2 \oldquotient=\quotient
-\ifnum\tempcc > \z@
-\repeat
-\edef\next{\bytes{\the\bytes\the\bits}}\next
-\bits{}}
-
-% display macros:
-%
-% o registers
-
-\newtoks\digittable % the table representing the register
-\newcount\columncount % counter for the current column
-
-% o fonts
-
-\font\fivessb=phvb at4pt
-
-% o generic control sequences
-
-\def\incrementcc{\advance\columncount by\@ne}
-\def\decrementcc{\advance\columncount by\m@ne}
-
-% o mask highlighting
-
-% the strange looking definition of \m@skspan originates from \multispan in plain.tex:
-% \newcount\mscount
-% \def\multispan#1{\omit \mscount#1\relax
-% \loop\ifnum\mscount>\@ne \sp@n\repeat}
-% \def\sp@n{\span\omit\advance\mscount\m@ne}
-%
-% the number of `physical' columns to span is (2 * columns - 1) due to the fact that we
-% have to span the gaps between columns as well.
-
-\def\m@skspan#1#2{%
- \multispan{#1\advance\mscount by\mscount\advance\mscount by-1}{\vrule\highltcl{\leaders\hrule height 4pt\hfil}\vrule}%
-}
-
-% o mask underlining
-
-\def\m@sksp@n#1#2{%
- \multispan{#1\advance\mscount by\mscount\advance\mscount by-1}{\hrulefill}%
-}
-
-% o mask legend typesetting
-
-\def\m@sklegend#1#2{%
- \multispan{#1\advance\mscount by\mscount\advance\mscount by-1}{\hfil\lgndcl{\fivessb#2}\hfil}%
-}
-
-% o displaying each digit
-
-\def\dgtdispl@y#1#2{%
- \ifx#20%
- \let\colorbg\lightcl\let\colord\darkcl
- \else
- \let\colorbg\darkcl\let\colord\lightcl
- \fi
- \vrule\colorbg{\vrule height4pt width 12.5pt}%
- \llap{\raise.6pt\hbox{\colord{\fivessb#1}$\,$}}\vrule
-}
-
-% o typesetting space between digits
-
-\def\c@lumnspacer#1{\tempca#1\tempcb\tempca\divide\tempca by8\multiply\tempca by8
- \ifnum\tempca=\tempcb
- \middlediamond
- \else
- \tempca#1\tempcb\tempca\divide\tempca by4\multiply\tempca by4
- \ifnum\tempca=\tempcb
- \middledot
- \else
- \hfil
- \fi
- \fi}
-
-% oo dimond to separate bytes
-
-\def\middlediamond{\setbox0=\hbox{$\scriptscriptstyle\diamond$}\tempda=4pt \advance\tempda by-\ht0
- \divide\tempda by2 \hss\raise\tempda\box0\hss}%
-
-% oo dot to separate nybbles
-
-\def\middledot{\setbox0=\hbox{.}\tempda=4pt \advance\tempda by-\ht0
- \divide\tempda by2 \hss\raise\tempda\box0\hss}%
-
-% o put it all together
-
-\let\stcr\cr % so that this can be used inside \tabalign which redef's \cr
-
-\def\regdisplay#1#2{{%
- \binary#1\end
- \linetranslator{}{\hrulefill\noexpand\eatone}{&$\,\,$}{&}{\stcr}{\incrementcc}:\bytes>\digittable
- \linetranslator{}{\noexpand\dgtdispl@y{\the\columncount}}{&\noexpand\c@lumnspacer{\the\columncount}}{&}%
- {\stcr}{\decrementcc}:\bytes>\digittable
- \masktranslator{}{\noexpand\m@sksp@n}{&\hfil}{&}{\stcr}{\relax}:{#2}>\digittable
- \masktranslator{}{\noexpand\m@skspan}{&\hfil}{&}{\stcr}{\relax}:{#2}>\digittable
- \masktranslator{}{\noexpand\m@sksp@n}{&\hfil}{&}{\stcr}{\relax}:{#2}>\digittable
- \expandafter\digittable\expandafter{\the\digittable\noalign{\vskip-3.8pt}}%
- \masktranslator{}{\noexpand\m@sklegend}{&\hfil}{&}{\stcr}{\relax}:{#2}>\digittable
- \vbox{\offinterlineskip
- \halign{&##\stcr
- \the\digittable
- }
- }%
-}}
-
-% an alternate display
-
-\def\altmiddledot{\setbox0=\hbox{.}%
- \tempda=\ht\thezero \advance\tempda by-\ht0
- \divide\tempda by2 \advance\tempda by -\dp\thezero
- $\,$\raise\tempda\box0$\,$%
-}
-
-\def\altmiddlediamond{\setbox0=\hbox{$\scriptscriptstyle\diamond$}%
- \tempda=\ht\thezero \advance\tempda by-\ht0
- \divide\tempda by2 \advance\tempda by -\dp\thezero
- \hss\raise\tempda\box0\hss
-}
-
-\def\altdgtdispl@y#1#2{%
- \ifx#20%
- \let\colorbg\lightcl\let\colord\darkcl
- \else
- \let\colorbg\darkcl\let\colord\lightcl
- \fi
- \setbox0=\hbox{$\,$0$\,$}\tempda\ht0
- \advance\tempda by 2pt \ht0\tempda
- \vrule\colorbg{\lower1pt\hbox{\vrule height\ht0 depth\dp0 width \wd0}}%
- \llap{\colord{\raise.5pt\hbox{\fivessb#1$\,$}}}\vrule
-}
-
-\def\altc@lumnspacer#1{\tempca#1\tempcb\tempca
- \divide\tempca by4\multiply\tempca by4
- \ifnum\tempca=\tempcb
- \ %
- \else
- \kern1pt%
- \fi
-}
-
-\def\bytedisplay#1{{%
- \binary#1\end
- \linetranslator{}{\hrulefill\noexpand\eatone}{&\hfil}{&}{\stcr}{\incrementcc}:\bytes>\digittable
- \linetranslator{}{\noexpand\altdgtdispl@y{\the\columncount}}{&\noexpand\altc@lumnspacer{\the\columncount}}{&}%
- {\stcr}{\decrementcc}:\bytes>\digittable
- \linetranslator{}{\hrulefill\noexpand\eatone}{&\hfil}{&}{\stcr}{\incrementcc}:\bytes>\digittable
- \lower\dp\thezero\vbox{\offinterlineskip
- \halign{&##\stcr
- \the\digittable
- }
- }%
-}}
-
\quickcolordef{peach}{0 0.06 0.14 0}
\quickcolordef{corn}{0 0.06 0.63 0.02}
\quickcolordef{sandybrown}{0 0.33 0.61 0.04}
@@ -664,54 +563,6 @@
\def\colorwhite#1{\grayset{1}#1\restorecolor}
\def\colorgray#1{\grayset{.5}#1\restorecolor}
-\newif\iffullcolorpalette
-\fullcolorpalettetrue
-
-\iffullcolorpalette
- \let\lightcl=\colorpeach
- \let\shadedcl=\colorcorn
- \let\highltcl=\colorgray
- \let\lgndcl=\colorwhite
-\else
- \let\lightcl=\colorwhite
- \let\shadedcl=\colorgray
- \let\highltcl=\colorwhite
- \let\lgndcl=\colorblack
-% \let\colorlinkstart=\begingroup
-% \let\colorlinkend=\endgroup
-\fi
- \let\darkcl=\colorblack
-
-% macros to typeset the hex numbers in `graphic' format
-
-\newtoks\registerlegend
-
-\def\registerdisplay#1\end{\edef\next{\the\registerlegend}%
- \ifx\next\empty
- \edef\next{\noexpand\bytedisplay{#1}}\next
- \else
- \edef\next{\noexpand\regdisplay{#1}{\the\registerlegend}}\next
- \fi
-}
-
-\newbox\thezero
-
-\setbox\thezero=\hbox{\lower1pt\hbox{\vbox{\offinterlineskip
-\halign{#&$\,$#$\,$&#\cr
-\noalign{\hrule}
-\omit\vrule height1pt&&\omit\vrule height1pt\cr
-\vrule&\phantom0&\vrule\cr
-\omit\vrule height1pt&&\omit\vrule height1pt\cr
-\noalign{\hrule}
-}}}}
-
-\def\texbinary{\global\let\oldT\T
- \global\def\T##1{{\let\end\relax\let\^\registerdisplay##1\end{\tt :}\let\^\hexify##1\end}}}
-
-\def\endtexbinary{\global\let\T\oldT}
-
-\def\hexify#1\end{\hbox{{\tt #1}$_{\scriptscriptstyle1\kern-.7pt6}$}}
-
% verbatim listing macros borrowed (with changes) from The TeXbook
\newcount\democodelc
@@ -801,31 +652,55 @@
% macros that provide a way to customize printing of reserved words
-\newtoks\tempseq
-\tempseq={RVD}
\let\oldamp\&
\let\oldoneletterid\|
-\def\replaceunderscore#1{\let\next\replaceunderscore
- \ifx#1\_\tempseq=\expandafter{\the\tempseq x}\else
- \ifx#1\#\tempseq=\expandafter{\the\tempseq H}\else
- \ifx#1\end\let\next\relax\else\tempseq=\expandafter{\the\tempseq #1}\fi
- \fi
- \fi\next}
-\def\reservedid#1{{\replaceunderscore#1\end
- \expandafter\let\expandafter\newseq\csname\the\tempseq\endcsname
- \ifx\relax\newseq\oldamp{#1}\else\newseq\fi}}
-
-\def\reservedoneletterid#1{{%
- \expandafter\let\expandafter\newseq\csname\the\tempseq\string#1\endcsname
- \ifx\relax\newseq\oldoneletterid{#1}\else\newseq\fi}}
+\let\oldslashslash\\
+
+\def\replaceunderscore#1{%
+ \ifx#1\_%
+ \yybreak{x\replaceunderscore}%
+ \else
+ \ifx#1\#%
+ \yybreak@{H\replaceunderscore}%
+ \else
+ \ifx#1\end
+ \yybreak@@{}%
+ \else
+ \yybreak@@{\string#1\replaceunderscore}%
+ \fi
+ \fi
+ \yycontinue
+}
+
+\def\reservedid#1{\expandafter\r@servedid\expandafter{\csname RVD\replaceunderscore#1\end\endcsname}{#1}}
+
+\def\r@servedid#1#2{\ifx#1\relax\yybreak{\oldamp{#2}}\else\yybreak{#1}\yycontinue}
+
+\def\reservedname#1{\expandafter\r@servedname\expandafter{\csname RVD\replaceunderscore#1\end\endcsname}{#1}}
+
+\def\r@servedname#1#2{\ifx#1\relax\yybreak{\oldslashslash{#2}}\else\yybreak{#1}\yycontinue}
+
+\def\reservedoneletterid#1{%
+ \expandafter\ifx\csname RVD\string#1\endcsname\relax
+ \yybreak{\oldoneletterid{#1}}%
+ \else
+ \yybreak{\csname RVD\string#1\endcsname}%
+ \yycontinue}
\def\defreserved#1{%
- \expandafter\def\csname\the\tempseq #1\endcsname
+ \expandafter\def\csname RVD\replaceunderscore#1\end\endcsname
}
\let\&\reservedid
\let\|\reservedoneletterid
+% better `hash'
+
+\let\oldhash\#
+\def\#{\lower.5pt\hbox{\tt\oldhash}}
+
+\let\oldmathS\$
+
% cweb macros adopted to making typesetting languages other than C possible: Makefile and linker scripts.
\tempca=\catcode`\^^I% remember the old catcode
@@ -843,6 +718,8 @@
\let\&=\AM % ampersand in a string
\let\^=\CF % circumflex in a string
\let\$=\oldmathS % dollar sign
+ \let\#=\oldhash % hash symbol: the new definition above would break alignment
+ \let\n\empty % the `end of line' inserted by the preprocessing script
\def^^I{$\llcorner$&$\lrcorner$}% a tab is a tab
\tabalign{}#1\cr}}}\endgroup} % verbatim string
\catcode`\^^I=\tempca
@@ -854,17 +731,12 @@
\def\R{\hbox{$^{\rm not}$}}
\let\CM\lnot
\def\MRL#1{\KK#1}\def\KK#1#2{\buildrel\;{\let\OR\lor\scriptscriptstyle#1}\over#2}
-\def\C#1{\5\5\quad$\triangleright\,${\rm #1}$\,\triangleleft$}
+\def\C#1{\5\5\quad\hbox{$\triangleright\,$}{\rm #1}\hbox{$\,\triangleleft$}}
\let\Z=\leq \let\G=\geq
\let\E==
\def\tabC#1{\quad$\triangleright\,${\cmntfont#1}$\,\triangleleft$}
-% better `hash'
-
-\let\oldhash\#
-\def\#{\lower.5pt\hbox{\.{\oldhash}}}
-
\def\.#1{\leavevmode\hbox{\tt % typewriter type for strings
\let\\=\BS % backslash in a string
\let\{=\LB % left brace in a string
@@ -880,263 +752,180 @@
% macros to change the appearance of section headers
\outer\def\N#1#2#3.{% beginning of starred section
- \ifacro{\toksF={}\makeoutlinetoks#3\outlinedone\outlinedone}\fi
- \gdepth=#1\gtitle={#3}\MN{#2}%
- \ifon\ifnum#1<\secpagedepth \vfil\eject % force page break if depth is small
- \else\vfil\penalty-100\vfilneg\vskip\intersecskip\fi\fi
- \message{*\secno} % progress report
- \def\stripprefix##1>{}\def\gtitletoks{#3}%
- \edef\gtitletoks{\expandafter\stripprefix\meaning\gtitletoks}%
- \edef\next{\write\cont{%\noexpand\noexpand\noexpand\eatone{\noexpand\meaning\noexpand\ZZ}%
- \noexpand\noexpand\noexpand % AS this is a (sort of) bug in cwebmac.tex
- % as long as the index is output (i.e. ...\eject)
- % before all the sections this is unnecessary
- % uncomment the line after the brace to see what \ZZ
- % expands to in case of weird errors
- \ZZ{\gtitletoks}{#1}{\secno}% write to contents file
- {\noexpand\the\pageno}{\the\toksE}}}\next % \ZZ{title}{depth}{sec}{page}{ss}
- \ifpdftex\expandafter\xdef\csname curr#1\endcsname{\secno}%
- \ifnum#1>0\countB=#1 \advance\countB by-1
- \advancenumber{chunk\the\countB.\expnumber{curr\the\countB}}\fi\fi
- \ifpdf\special{pdf: outline #1 << /Title (\the\toksE) /Dest
- [ @thispage /FitH @ypos ] >>}\fi
- \ifon\startsection{\ttl#3.\ }\ignorespaces} % changed the font; AS
+ \ifacro{\toksF={}\makeoutlinetoks#3\outlinedone\outlinedone}\fi
+ \gdepth=#1\gtitle={#3}\MN{#2}%
+ \ifon\ifnum#1<\secpagedepth \vfil\eject % force page break if depth is small
+ \else\vfil\penalty-100\vfilneg\vskip\intersecskip\fi\fi
+ \message{*\secno} % progress report
+ \def\stripprefix##1>{}\def\gtitletoks{#3}%
+ \edef\gtitletoks{\expandafter\stripprefix\meaning\gtitletoks}%
+ \edef\next{\write\cont{%\noexpand\noexpand\noexpand\eatone{\noexpand\meaning\noexpand\ZZ}%
+ \noexpand\noexpand\noexpand % AS this is a (sort of) bug in cwebmac.tex
+ % as long as the index is output (i.e. ...\eject)
+ % before all the sections this is unnecessary
+ % uncomment the line after the brace to see what \ZZ
+ % expands to in case of weird errors
+ \ZZ{\gtitletoks}{#1}{\secno}% write to contents file
+ {\noexpand\the\pageno}{\the\toksE}}}\next % \ZZ{title}{depth}{sec}{page}{ss}
+ \ifpdftex\expandafter\xdef\csname curr#1\endcsname{\secno}%
+ \ifnum#1>0\countB=#1 \advance\countB by-1
+ \advancenumber{chunk\the\countB.\expnumber{curr\the\countB}}\fi\fi
+ \ifpdf\special{pdf: outline #1 << /Title (\the\toksE) /Dest
+ [ @thispage /FitH @ypos ] >>}\fi
+ \ifon\startsection{\ttl#3.\ }\ignorespaces} % changed the font; AS
\let\oldN\N
\outer\def\textN#1#2#3.{% beginning of starred section in `text' mode
- \ifacro{\toksF={}\makeoutlinetoks#3\outlinedone\outlinedone}\fi
- \gdepth=#1\gtitle={#3}\MN{#2}%
- \ifon
- \ifnum#1<2
- \vfil\eject % force page break for chapters
- \else
- \vskip0pt plus 3.5\baselineskip\penalty-100\vskip0pt plus -3.5\baselineskip\vskip\intersecskip % no page break
- \fi
- \fi
- \message{*\secno} % progress report
- \def\stripprefix##1>{}\def\gtitletoks{#3}%
- \edef\gtitletoks{\expandafter\stripprefix\meaning\gtitletoks}%
- \edef\next{\write\cont{%\noexpand\noexpand\noexpand\eatone{\noexpand\meaning\noexpand\ZZ}%
- \noexpand\noexpand\noexpand % AS this is a (sort of) bug in cwebmac.tex
- % as long as the index is output (i.e. ...\eject)
- % before all the sections this is unnecessary
- % uncomment the line after the brace to see what \ZZ
- % expands to in case of weird errors
- \ZZ{\gtitletoks}{#1}{\secno}% write to contents file
- {\noexpand\the\pageno}{\the\toksE}}}\next % \ZZ{title}{depth}{sec}{page}{ss}
- \ifpdftex\expandafter\xdef\csname curr#1\endcsname{\secno}%
- \ifnum#1>0\countB=#1 \advance\countB by-1
- \advancenumber{chunk\the\countB.\expnumber{curr\the\countB}}\fi\fi
- \ifpdf\special{pdf: outline #1 << /Title (\the\toksE) /Dest
- [ @thispage /FitH @ypos ] >>}\fi
- \ifon\startsection{\ttl#3}\smallskip\noindent\ignorespaces}
+ \ifacro{\toksF={}\makeoutlinetoks#3\outlinedone\outlinedone}\fi
+ \gdepth=#1\gtitle={#3}\MN{#2}%
+ \ifon
+ \ifnum#1<2
+ \vfil\eject % force page break for chapters
+ \else
+ \vskip0pt plus 3.5\baselineskip\penalty-100\vskip0pt plus -3.5\baselineskip\vskip\intersecskip % no page break
+ \fi
+ \fi
+ \message{*\secno} % progress report
+ \def\stripprefix##1>{}\def\gtitletoks{#3}%
+ \edef\gtitletoks{\expandafter\stripprefix\meaning\gtitletoks}%
+ \edef\next{\write\cont{%\noexpand\noexpand\noexpand\eatone{\noexpand\meaning\noexpand\ZZ}%
+ \noexpand\noexpand\noexpand % AS this is a (sort of) bug in cwebmac.tex
+ % as long as the index is output (i.e. ...\eject)
+ % before all the sections this is unnecessary
+ % uncomment the line after the brace to see what \ZZ
+ % expands to in case of weird errors
+ \ZZ{\gtitletoks}{#1}{\secno}% write to contents file
+ {\noexpand\the\pageno}{\the\toksE}}}\next % \ZZ{title}{depth}{sec}{page}{ss}
+ \ifpdftex\expandafter\xdef\csname curr#1\endcsname{\secno}%
+ \ifnum#1>0\countB=#1 \advance\countB by-1
+ \advancenumber{chunk\the\countB.\expnumber{curr\the\countB}}\fi\fi
+ \ifpdf\special{pdf: outline #1 << /Title (\the\toksE) /Dest
+ [ @thispage /FitH @ypos ] >>}\fi
+ \ifon\startsection{\ttl#3}\smallskip\noindent\ignorespaces}
+
+\outer\def\chapterN#1#2#3.{% beginning of starred section in `book' mode
+ \ifacro{\toksF={}\makeoutlinetoks#3\outlinedone\outlinedone}\fi
+ \gdepth=#1\gtitle={#3}\MN{#2}%
+ \ifon
+ \ifnum#1<\tw@
+ \vfil\eject % force page break for chapters and major subsections
+ \ifodd\pageno
+ \else
+ \null\vfill\eject
+ \fi
+ \else
+ \vskip0pt plus 3.5\baselineskip
+ \penalty-100
+ \vskip0pt plus -3.5\baselineskip
+ \vskip\intersecskip % no forced page break
+ \fi
+ \fi
+ \message{*\secno} % progress report
+ \def\stripprefix##1>{}\def\gtitletoks{#3}%
+ \edef\gtitletoks{\expandafter\stripprefix\meaning\gtitletoks}%
+ \edef\next{\write\cont{%\noexpand\noexpand\noexpand\eatone{\noexpand\meaning\noexpand\ZZ}%
+ \noexpand\noexpand\noexpand % AS this is a (sort of) bug in cwebmac.tex
+ % as long as the index is output (i.e. ...\eject)
+ % before all the sections this is unnecessary
+ % uncomment the line after the brace to see what \ZZ
+ % expands to in case of weird errors
+ \ZZ{\gtitletoks}{#1}{\secno}% write to contents file
+ {\noexpand\the\pageno}{\the\toksE}}}\next % \ZZ{title}{depth}{sec}{page}{ss}
+ \ifpdftex\expandafter\xdef\csname curr#1\endcsname{\secno}%
+ \ifnum#1>0\countB=#1 \advance\countB by-1
+ \advancenumber{chunk\the\countB.\expnumber{curr\the\countB}}\fi\fi
+ \ifpdf\special{pdf: outline #1 << /Title (\the\toksE) /Dest
+ [ @thispage /FitH @ypos ] >>}\fi
+ \ifon\stsecchap{#1}{#3}\ignorespaces
+}
+
+\def\stsecchap#1#2{\rightskip=0pt % get out of C mode (cf. \B)
+ \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50
+%
+ \ifnum#1>0
+ \noindent{\let\*=\lapstar\llap{\tentitle\secstar\quad}}{\ttl #2}\smallskip\noindent% push it to the margins
+ \else
+ \null % sloppy but this works for the narrow case of this example
+ \global\chapterheadtrue
+ \vskip1.5in
+ \vbox{\tabskip=0pt plus 1 fil
+ \halign to\hsize{%
+ \hfil##\tabskip=0pt\cr
+ \cmhuge\secstar\cr
+ \noalign{\vskip 1pc}%
+ \cmmiddle#2\cr
+ }%
+ }%
+ \bigskip
+ \noindent
+ \fi
+%
+ \ifpdftex\smash{\raise\baselineskip\hbox to0pt{%
+ \let\*=\empty\ifmakepdf\pdfdest num \secstar fith\fi}}% this space is a bug in the original cwebmac.tex; AS
+ \else\ifpdf\smash{\raise\baselineskip\hbox to0pt{%
+ \let\*=\empty\special{%
+ pdf: dest (\romannumeral\secstar) [ @thispage /FitH @ypos ]}}}\fi\fi}
\outer\def\textM#1{\MN{#1}\ifon\vskip0pt plus 3\baselineskip\penalty-100\vskip0pt plus -3\baselineskip % no page break
- \vskip\intersecskip\startsection\ignorespaces}
+ \vskip\intersecskip\startsection\ignorespaces}
\def\MN#1{\par % common code for \M, \N
- {\xdef\secstar{#1}\let\*=\empty\xdef\secno{#1}}% remove \* from section name
- \ifx\secno\secstar \onmaybe \else\ontrue \fi
- \mark{{\secno}{\the\gdepth}{\the\gtitle}}} % remove the annoying
- % `paragraph' sign; AS
+ {\xdef\secstar{#1}\let\*=\empty\xdef\secno{#1}}% remove \* from section name
+ \ifx\secno\secstar \onmaybe \else\ontrue \fi
+ \mark{{\secno}{\the\gdepth}{\the\gtitle}}% remove the annoying `paragraph' sign; AS
+}
-% a new start section macro: fix the extra space bug and push the setion number to the margins
+% a new start section macro: fix the extra space bug and push the section number to the margins
\def\stseclap{\rightskip=0pt % get out of C mode (cf. \B)
- \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50
- \noindent{\let\*=\lapstar\llap{\tentitle\secstar\quad}}% push it to the margins
- \ifpdftex\smash{\raise\baselineskip\hbox to0pt{%
- \let\*=\empty\ifmakepdf\pdfdest num \secstar fith\fi}}% this space is a bug in the original cwebmac.tex; AS
- \else\ifpdf\smash{\raise\baselineskip\hbox to0pt{%
- \let\*=\empty\special{%
- pdf: dest (\romannumeral\secstar) [ @thispage /FitH @ypos ]}}}\fi\fi}
+ \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50
+ \noindent{\let\*=\lapstar\llap{\tentitle\secstar\quad}}% push it to the margins
+ \ifpdftex\smash{\raise\baselineskip\hbox to0pt{%
+ \let\*=\empty\ifmakepdf\pdfdest num \secstar fith\fi}}% this space is a bug in the original cwebmac.tex; AS
+ \else\ifpdf\smash{\raise\baselineskip\hbox to0pt{%
+ \let\*=\empty\special{%
+ pdf: dest (\romannumeral\secstar) [ @thispage /FitH @ypos ]}}}\fi\fi}
\let\startsection\stseclap
+\newif\ifchapterhead
+
% make page and sectoin number hang in the margins; \quad is chosen to
% be consistent with section appearance; the page numbers are printed
% in old-style numerals;
-\def\lheader{\headertrue\llap{\mainfont\oldstyle\the\pageno\tentitle\quad}\eightpoint\rm\grouptitle
- \hfill\title\rlap{\tentitle\quad\tenpoint$^{\hbox{\sevenrm\topsecno}}_{\hbox{\sevenrm\botsecno}}$}} % top line on left-hand pages
-\def\rheader{\headertrue
-\llap{\tenpoint$^{\hbox{\sevenrm\topsecno}}_{\hbox{\sevenrm\botsecno}}$\tentitle\quad}%
-\eightpoint\rm\title\hfill
- \grouptitle\rlap{\tentitle\quad\mainfont\oldstyle\the\pageno}} % top line on right-hand pages
+\def\lheader{%
+ \ifchapterhead
+ \hfil
+ \else
+ \termindexfalse\headertrue\llap{\mainfont\oldstyle\the\pageno\tentitle\quad}%
+ \eightpoint\rm\grouptitle\hfill\title
+ \rlap{\tentitle\quad\tenpoint$^{\hbox{\sevenrm\topsecno}}_{\hbox{\sevenrm\botsecno}}$}%
+ \fi
+} % top line on left-hand pages
+
+\def\rheader{%
+ \ifchapterhead
+ \hfil
+ \else
+ \termindexfalse\headertrue\llap{\tenpoint$^{\hbox{\sevenrm\topsecno}}_{\hbox{\sevenrm\botsecno}}$\tentitle\quad}%
+ \eightpoint\rm\title\hfill\grouptitle
+ \rlap{\tentitle\quad\mainfont\oldstyle\the\pageno}%
+ \fi
+} % top line on right-hand pages
\def\botsecno{\expandafter\takeone\botmark} % the first section on the
% next page
-% from time to time, entries must be omitted from the index;
-% the macros below implement a mechanism to do that
-
-\newif\ifisindexable
-
-\def\setindexable#1{%
- \isindexabletrue
- \def\next{#1}%
- \expandafter\s@t@ndexable\unindexable.\end
-}
+\newwrite\exampletable
-\def\s@t@ndexable#1#2\end{%
- {%
- \def\ifisindexable{#1}%
- \ifx\ifisindexable\next
- \yybreak{\aftergroup\isindexablefalse\aftergroup\eattoend}%
- \else
- \def\ifisindexable{#2}%
- \ifx\ifisindexable\dotcontainer
- \yybreak@{\aftergroup\eattoend}%
- \else
- \yybreak@{\aftergroup\s@t@ndexable}%
- \fi
- \yycontinue
- }%
- #2\end
-}
-
-\def\inxmod{%
- \write\cont{} % ensure that the contents file isn't empty
- \write\cont{\catcode `\noexpand\@=12\relax} % \makeatother
- \closeout\cont % the contents information has been fully gathered
- \message{Index:}
- \medskip
- \eightpoint\raggedright
- \fnotesstart=2
- \fnotesspan=1
- \noofcolumns=3
- \icgap=5pt%
- \linecount=3
- \setmcparams
- \dsskip=0pt%
- \adjskip=0pt plus 9pt%
- \ifx\unindexable\UNDEFINED
- \def\unindexable{{$\TeXx$}{$\TeXa$}{$\TeXb$}{$\TeXf$}{$\TeXao$}{$\TeXfo$}}%
- \else
- \expandafter\def\expandafter\unindexable\expandafter{\unindexable
- {$\TeXx$}{$\TeXa$}{$\TeXb$}{$\TeXf$}{$\TeXao$}{$\TeXfo$}%
- }%
- \fi
- \def\I##1, ##2.{%
- {%
- \setindexable{##1}%
- \ifisindexable
- \else
- \aftergroup\eatone
- \fi
- }%
- {%
- \hangindent1em\noindent##1:\kern.5em
- \ifacro\pdfnote##2.\else##2\fi.%
- \par
- }%
- }%
- % indexing macros for grammar terms
- \def\termidstring##1{% processed name in italics
- \numberstocharsandspaces##1\end
- \let\optstrextra\optstrextraesc
- \expandafter\nameproc\expandafter{\the\toksa}%
- \def\idxentry{{\it\the\toksa}}%
- }%
- \def\termvstring##1{% processed name in typewriter style
- \numberstocharsandspaces##1\end
- \let\optstrextra\optstrextraesc
- \expandafter\nameproc\expandafter{\the\toksa}%
- \def\idxentry{{\tt\def\_{\char`\_}\the\toksa}}%
- }%
- \def\termttstring##1{% straightforward typewriter text
- \numberstocharsandspaces##1\end
- \def\idxentry{{\tt\the\toksa}}%
- }%
- \def\termostring##1{% options (e.g. \flex\ and \bison\)
- \numberstocharsandspaces##1\end
- \def\idxentry{{$\langle$\bf\the\toksa$\rangle$}}%
- }%
- \let\termhdrstring\termidstring
- \def\termstring##1{%
- \numberstocharsandspaces##1\end
- \let\optstrextra\optstrextraesc
- \expandafter\nameproc\expandafter{\the\toksa}%
- \def\idxentry{{\tt"\the\toksa"}}%
- }%
- \def\texcsstring##1{%
- \numberstocharsandspaces##1\end
- \def\idxentry{%
- \def\texnspace{index}%
- \def\getcescape{% an \ seen is really an \, and will not go through C string processing
- \def\next{escape}%
- \action\next\in\currentstate
- }%
- \termindexfalse\expandafter\inlineTeXx\expandafter{\expandafter/\the\toksa}%
- }%
- }%
- \expandafter\def\csname acharswitch:index\endcsname{% correct reserved \TeX\ characters a la CWEB verbatim
- %$\%\\ % unaffected
- %\#\ % these never appear
- _{%
- \yybyte\expandafter{\csname \the\yybyte\endcsname}%
- \expandafter\yycp@\expandafter`\the\yybyte\relax
- \mkpurebyte
- \yyreturn
- }
- }%
- \expandafter\setspecialcharsfrom\csname acharswitch:index\endcsname
- \expandafter\let\expandafter\acharswitch\csname acharswitch:index\endcsname
- \def\texlexer{% now that all character codes are 12
- \let\default\yygetchar
- \let\next\yycp@
- \ifnum\yycp@>"3F %
- \ifnum\yycp@<"5B % an uppercase letter or @
- \def\next{letter}%
- \fi
- \fi
- \ifnum\yycp@>"60 %
- \ifnum\yycp@<"7B %
- \def\next{letter}%
- \fi
- \fi
- \action\next\in\currentstate
- }%
- \def\indexseparator##1##2{%
- \vskip.5\baselineskip
- \centerline{\dinkus}%
- \vskip.5\baselineskip
- }
- \def\GI##1##2##3##4.{%
- {%
- \def\hostparsernamespace{##1}%
- \toksa{}##2{##3}%
- \I{\idxentry}##4.%
- }%
- }%
- % end indexing macros for grammar terms
- \let\*=\lapstar
- \def\[##1]{{\it##1}} % definitions
- \def\(##1){$\underline{##1}$} % underlined index item
- \def\(##1){{\bf ##1}} % an alternative to the above
- \def\e##1e{##1{\sevenpoint$^\circ$}} % terms in examples
- \def\f##1f{{\it##1\/\kern.2ex}${}^\circ$} % lhs in examples (italic correction does not seem to be enough)
- \def\g##1g{$\underline{##1}^\circ$} % definitions in examples
- \def\g##1g{{\bf ##1}$^\circ$} % an alternative to the above
- \begindoublecols
- \readindex
- \otherlangindexseparator
- \readgindex
-}
-
-\def\otherlangindexseparator{%
- \par
- \vskip.5\baselineskip
- \centerline{B{\sc ISON AND} \TeX\ {\sc INDEX}}%
- \vskip.5\baselineskip
- \par
-}
+\newif\ifsaveparseoutput
+\newif\ifchecktable
\def\finmod{%
\enddoublecols
\closeout\exampletable
- \unsetfootnotes
\parfillskip 0pt plus 1fil
\def\grouptitle{NAMES OF THE SECTIONS}
\let\topsecno=\nullsec
@@ -1178,68 +967,122 @@
\centerline{\sc A LIST OF ALL SECTIONS}
\penalty300
\medskip
+ \emergencystretch=10pt
\readsections
}
-\newread\trygindex
+% \Cee\ section macros
-\def\readgindex{%
- \openin\trygindex=\jobname.gdy
- \ifeof\trygindex
- \else
- \closein\trygindex
- \input \jobname.gdy
- \fi
-}
+% stage one macros for `\B' sections: collecting tokens
-% main section macro
+% \B is always paired with \par (see CWEAVE section 213); unfortunately, this is
+% where certainty ends; the output of \CWEAVE\ is woefully unstructured, to say the
+% least; the ugly hack below appears to be the only way to typeset the \Cee\ sections
+% in their own style (using the 9pt face as is the case below).
\let\oldB\B
-% stage one macros for `\B' sections: collecting tokens
-
-% \B is always paired with \par (see CWEAVE section 213)
-
\long\def\Bvbpp#1\par{%
- \Bvbp@#1\X\X${}\E{}$\par
+ \Bvbp@#1\X\X$\E$\par
+}
+
+\long\def\Bvbpp#1\par{% the \vb{\yyendgame}\vb... is inserted by brack.pl
+ \Bvbp@#1\cleanBtail\X\X$\E$\par
}
-\long\def\Bvbp@#1\X#2\X$#3\E#4$#5\par{%
+\def\cleanBtail\X\X$\E${}
+
+\long\def\Bvbp@#1\X#2\X$#3\E#4$#5\par{% new version of the above, experimental
\yystringempty{#5}%
- {%
- \Bvb@@#1\X#2\X$#3\E#4$\par
- }{%
- \Bvb@@#1\X#2\X${#3}\E{#4}$\begingroup
+ {% this is a \Cee\ section (@c or @p); it is tempting to assume that the suffix
+ % is \X\X$\E$\par and forego the invocation of \Bvb@@, however, this is not always
+ % the case as the first \X may come from a different section in the middle.
+ \oldB#1\X#2\X$#3\E#4$\par
+ }{% the logic here is not perfect but if this is still a \Cee\ section,
+ % inserting @t@> between @> and whatever follows that produces $...\E...$
+ % will correct the misidentification (the result of which may be, at best,
+ % part of the section being typeset in a wrong face, or, worse \begingroup
+ % starting a group in a wrong place (such as in the middle of the math mode))
+ \oldB#1\X#2\X${#3}\E{#4}$\begingroup % the braces around #3 and #4 are necessary
+ % to ensure proper spacing around \E in case
+ % #3 and #4 are empty
\ninepoint
+ \Binputtoks{#5}\Btoksmathfalse
#5\par\endgroup
}%
}
-\long\def\Bvb@@#1\X\X$#2\E#3$\par{%
- \oldB#1\par
+\newtoks\Binputtoks
+
+\newif\ifBtoksmath % does the section start in math mode?
+
+\let\yyendgame\empty
+
+\let\postparse\empty % the `upper half' \preparse... macros will use the contents of \Binputtoks
+
+\newif\ifyyskipparse
+
+\let\B\Bvbpp
+
+% parser stack setup
+
+\def\fillpstack#1#2{%
+ \expandafter\def\csname currentparser[#1]\endcsname{#2}%
}
-\def\begingsec#1#2\endgsec{%
- \ifmmode
- \yybreak{{}${}\vbpp{}$#2\vb\endgsec{#1}{$#2}}%$
+\def\poppstack#1{%
+ \expandafter\ifx\csname currentparser[#1]\endcsname\relax
+ \yybreak{% unknown language, skip the section
+ \preparsetrivial
+ }
\else
- \yybreak{\vbpp{}#2\vb\endgsec{#1}{#2}}%
+ \yybreak{%
+ \expandafter\expandafter\expandafter
+ \p@ppstack\csname currentparser[#1]\endcsname\end{#1}%
+ }%
\yycontinue
}
-\long\def\vbpp#1#2\vb#3#{% verbatim section preprocessor
- \yystringempty{#3}{%
- \vbp@{#1\stashed{#2}}%
+\def\p@ppstack#1#2\end#3{%
+ \yystringempty{#2}{%
+ \fillpstack{#3}\relax#1%
}{%
- #3{#1\stashed{#2}}%
+ \fillpstack{#3}{#2}#1%
}%
}
-\long\def\vbp@#1#2{%
- \vbpp{#1#2}%
+% section macros
+
+\def\lsectionbegin#1{%
+ \ifmmode
+ \yybreak{%
+ {}$% exit the group inside the math mode
+ \Btoksmathtrue
+ \poppstack{#1}\vb{}$%
+ }% finish the math mode and reinsert it as stash
+ \else
+ \yybreak{%
+ \poppstack{#1}%
+ }%
+ \yycontinue
}
-\let\B\Bvbpp
+\def\skiptolsection#1\lsectionbegin#2{%
+ \ifBtoksmath
+ \yybreak{%
+ \lsectionbegin{#2}\vb{}${}%
+ }%
+ \else
+ \yybreak{%
+ \lsectionbegin{#2}%
+ }%
+ \yycontinue
+}
+
+\def\removefinalvb#1\endparse{}
+
+\def\preparsetrivial#1\postparse{} % in case the section contains some dangerous
+ % terms like \insertraw{...} that must be skipped
% URL typesetting
@@ -1260,15 +1103,29 @@
% commonly used names
-\def\CWEB{\.{CWEB}}\def\CTANGLE{\.{CTANGLE}}\def\CWEAVE{\.{CWEAVE}}
+\def\CWEB{\.{CWEB}}
+\def\CTANGLE{\.{CTANGLE}}
+\def\CWEAVE{\.{CWEAVE}}
+\def\WEB{\.{WEB}}
+\def\Pascal{P{\sc ASCAL}}
+\def\noweb{\.{noweb}}
\def\splint{\.{SPLinT}}
\def\POSIX{{\sc POSIX}}
+\def\EAST{{\sc EAST}}
+\def\WEST{{\sc WEST}}
\def\ISO{{\mc ISO}}
-\def\bison{\.{bison}}
-\def\flex{\.{flex}}
+\def\bison{\ifheader B{\sc ISON}\else\.{bison}\fi}
+\def\flex{\ifheader F{\sc LEX}\else\.{flex}\fi}
\def\lex{\.{lex}}
+\def\yacc{\.{yacc}}
\def\gcc{\.{gcc}}
+\def\ld{\ifheader LD\else\.{ld}\fi}
\def\GNU{{\sc GNU}}
+\def\CEEPP/{{\mc C{\tt ++}\spacefactor1000}}
+\def\Ceepp{\CEEPP/}
+\def\mft{\.{mft}}
+\def\MF{{\tt META}\-{\tt FONT}\spacefactor1000 }
+\def\MP{{\tt META}\-{\tt POST}\spacefactor1000 }
% from tugboat.cmn
\newbox\TestBox
\def\La{\tempca=\the\fam \leavevmode L%
@@ -1289,84 +1146,31 @@
}%
}
-% debugging
-
-\def\shownethe#1{%
- \edef\next{\the#1}%
- \ifx\next\empty
- \else
- \showthe#1%
- \fi
-}
-
-\def\showem#1#2#3{\toksa{#1}\toksb{#2}\toksc{#3}{\newlinechar=`^^J%
- \errmessage{%
- arg. 1: \the\toksa^^J%
- arg. 2: \the\toksb^^J%
- arg. 3: \the\toksc%
-}}}
-
% sugar
\def\FOREVER{{\bf forever}}
-% delay functions prettyprinting and other miscellanea;
-
-\def\delayhalfsec{\hbox{wait \kern-.5pt\raise1pt\hbox{$\scriptstyle1$}%
-\kern-1pt/\kern-1pt\lower1pt\hbox{$\scriptstyle2$} sec, }}
-\def\delayquartersec{\hbox{wait \kern-.5pt\raise1pt\hbox{$\scriptstyle1$}%
-\kern-1pt/\kern-1pt\lower1pt\hbox{$\scriptstyle4$} sec, }}
-
-\def\delay#1sec{%
-\hbox{\def\secmult{}wait
-\getsecmult#1\end
-\if\secmult u\def\secmodifier{ $\mu$\kern.05pt }\else
-\if\secmult m\def\secmodifier{ m}\else
-\if\secmult n\def\secmodifier{ n}\else
- \secmult\def\secmodifier{ }%
-\fi\fi\fi
-\secmodifier sec$\rm\scriptstyle s$, }
-}
-
-\def\getsecmult#1{%
-\ifx#1\end\let\next\relax\else
- \secmult\def\secmult{#1}\let\next\getsecmult
-\fi\next
-}
-
-% attribute prettyprinting;
-
-\long\def\parseattrib#1#2\end{\csname attrib#1\endcsname}
-
-\def\xxattributexx#1{\ifx(#1\let\next\xxattributex\else\let\next\xxattribute\fi\next#1}
-\def\xxattributex((\\#1{%
- \expandafter\let\expandafter\currentattrib\csname attrib#1\endcsname
- \ifx\currentattrib\attribpacked
- \strut\colorblack{%
- \lower2pt\hbox{\vrule width \wd\thezero height
- \ht\thezero depth
- \dp\thezero}}\llap{\colorwhite{\hbox{$\scriptscriptstyle\bf 01\kern.5pt$}}}%
- \let\next\eatparentheses
- \fi
- \ifx\currentattrib\attribnoinline
- {\ \bf noinline\rm_a}%
- \let\next\eatparentheses
- \fi
- \ifx\currentattrib\attribformat
- {\ \bf format\rm_a}%
- \let\next\eatarguments
- \fi
- \next
-}
-
-\def\eatparentheses#1)){}
-\def\eatarguments(\\#1,#2,#3))){(\hbox{\rm as }\.{#1})}
-
-\def\xxattribute#1{\.{\_\_attribute\_\_} (\sc GNU) #1}
-
-\let\attribnoinline=1
-\let\attribpacked=2
-\let\attribformat=3
+\ifacro
+ \ifpdftex
+ \input extras/texmf/macros/protcode.tex
+ \pdfprotrudechars=2
+ \setprotcode\tenrm
+ \setprotcode\ninerm
+ \setprotcode\eightrm
+ \setprotcode\sevenrm
+ \setprotcode\sixrm
+ \setprotcode\tenit
+ \setprotcode\nineit
+ \setprotcode\eightit
+ \setprotcode\sevenit
+ \setprotcode\sixit
+ % do not stretch characters
+ %\pdfdjustspacing=2
+ %\pdffontexpand\sevenrm 30 20 10 autoexpand
+ % TODO: use \pdfsavepos, \pdflastxpos, and \pdflastypos to
+ % save the position of index terms on the page
+ \fi
+\fi
\tenpoint
-%\registerlegend{{8}{\noexpand\phantom{B}}}
+
diff --git a/support/splint/tex/noweb.sty b/support/splint/tex/noweb.sty
new file mode 100644
index 0000000000..a0f2c7cf43
--- /dev/null
+++ b/support/splint/tex/noweb.sty
@@ -0,0 +1,399 @@
+% Copyright 2012-2020, Alexander Shibakov
+% This file is part of SPLinT
+%
+% SPLinT is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% SPLinT is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
+
+\def\stseclap{\rightskip=0pt % get out of C mode (cf. \B)
+ \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50
+ \noindent{\let\*=\empty\llap{\tentitle\setsafesecno{\secno}\quad}}% push it to the margins
+ \putxref{\MNM}{}{}.% generate a location reference for noweb cross referencing style
+ \ifpdftex\smash{\raise\baselineskip\hbox to0pt{%
+ \let\*=\empty\ifmakepdf\pdfdest num \secstar fith\fi}}% this space is a bug in the original cwebmac.tex; AS
+ \else
+ \ifpdf
+ \smash{\raise\baselineskip
+ \hbox to0pt{%
+ \let\*=\empty\special{%
+ pdf: dest (\romannumeral\secstar) [ @thispage /FitH @ypos ]%
+ }%
+ }%
+ }%
+ \fi
+ \fi
+}
+
+\def\stsecchap#1#2{\rightskip=0pt % get out of C mode (cf. \B)
+ \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50
+%
+ \ifnum#1>\z@ % the `level' if this section is below that of a chapter
+ \noindent{\let\*=\empty\llap{\tentitle
+ \setsafesecno{\secno}\quad}}{\ttl #2}% push it to the margins
+ \putxref{\MNM}{}{}.% generate a location reference for noweb cross referencing style
+ \smallskip\noindent
+ \else
+ \setchaptertitle{\secno}{#2}%
+ \putxref{\MNM}{0}{}.% generate a chapter location reference for noweb cross referencing style
+ \fi
+%
+ \ifpdftex\smash{\raise\baselineskip\hbox to0pt{%
+ \let\*=\empty\ifmakepdf\pdfdest num \secstar fith\fi}}% this space is a bug in the original cwebmac.tex; AS
+ \else\ifpdf\smash{\raise\baselineskip\hbox to0pt{%
+ \let\*=\empty\special{%
+ pdf: dest (\romannumeral\secstar) [ @thispage /FitH @ypos ]}}}\fi\fi}
+
+\def\setchaptertitle#1#2{%
+ \global\chapterheadtrue
+ \null
+ {\ninepoint\tempda=\baselineskip
+ \multiply\tempda by 17
+ \vskip\tempda plus\baselineskip minus 2pt
+ }%
+ \vbox to 0pt{%
+ \vss
+ \tabskip=0pt plus 1 fil
+ \halign to\hsize{%
+ \hfil##\tabskip=0pt\cr
+ \hugetitle\setsafechapno{#1}\cr
+ \noalign{\vskip 1pc}%
+ \midtitle#2\cr
+ }%
+ }%
+ \prevdepth=0pt
+ \bigskip
+ \noindent{\let\*=\empty\llap{\tentitle\setsafesecno{\secno}\quad}}%
+}
+
+\let\startsection\stseclap
+
+\expandafter\def\expandafter\oldB\expandafter{\oldB\global\csectionstarttrue\putxref{\BBB}{}{}.}
+
+\def\putxref#1#2.{% it is important that #2 contains at least two braced groups (as in {}{})
+ % otherwise the parameter scanning mechanism will strip the outside braces
+ \ifxreflocal
+ {\edef\next{\write\xrefstream{\nx\nx\nx#1{\nx\the\nx\pageno}{\secno}#2\harmlesscomment}}\next}%
+ \fi
+}
+
+\def\X#1:#2\X{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi %$% section name
+ \XX$\langle\,${\let\I=\ne#2\eightrm\kern.5em
+ \ifacro{\pdfnote#1.}\else#1\fi}$\,\rangle$\putpathindex{\secno}{#1}\XX\putxrefx{#1}{#2}}
+
+\def\putxrefx#1#2{%
+ \ifxreflocal
+ {\def\sname{#2}%
+ \def\stripprefix##1>{ }%
+ \let\*\empty
+ \edef\next{\write\xrefstream{\nx\nx\nx\XXX{\nx\the\nx\pageno}{\secno}{#1}\harmlesscomment
+ \expandafter\stripprefix\meaning\sname}}\next}%
+ \fi
+}
+
+\newif\ifcsectionstart % does this section name appear at the beginning of a \Cee\ section?
+
+\def\putpathindex#1#2{%
+ \ifcsectionstart
+ \global\csectionstartfalse\strut
+ \vadjust{%
+ \setbox0=\hbox{\strut}%
+ \kern-\dp0
+ \vbox to 0pt{
+ \vss
+ \hbox to\pagewidth{%
+ \hfil\rlap{%
+ \let\*\empty
+ \kern1em \setpathlinks{#1}{#2}%
+ }%
+ }%
+ }%
+ \setbox0=\hbox{\strut}%
+ \kern\dp0
+ }%
+ \fi
+}
+
+\def\setpathlinks#1#2{%
+ \expandafter\ifx\csname xchain[#1][#2]down\endcsname\relax
+ \expandafter\ifx\csname xchain[#1][#2]up\endcsname\relax
+ \else
+ \setuplink{#1}{#2}{\hfil##\hfil}%
+ \fi
+ \else
+ \expandafter\ifx\csname xchain[#1][#2]up\endcsname\relax
+ \setdownlink{#1}{#2}{\hfil##\hfil}%
+ \else
+ \setuplink{#1}{#2}{##\hfil}
+ \setdownlink{#1}{#2}{\hfil##}%
+ \fi
+ \fi
+}
+
+\def\setdownlink#1#2#3{%
+ {\setbox0\vtop{
+ \sevenpoint\halign{#3\cr
+ \xref@nowebsection{\csname xchain[#1][#2]down\endcsname}\cr
+ \relax\ifacro
+ \pdflink{\csname xchain[#1][#2]down\endcsname}{\raise3.5pt\hbox{$\scriptscriptstyle\bigtriangledown$}}%
+ \else
+ \raise3.5pt\hbox{$\scriptscriptstyle\bigtriangledown$}%
+ \fi
+ \cr
+ }
+ }%
+ \dp0=0pt \box0}%
+}
+
+\def\setuplink#1#2#3{%
+ {\setbox0\vbox{
+ \sevenpoint\halign{#3\cr
+ \relax\ifacro
+ \pdflink{\csname xchain[#1][#2]up\endcsname}{\lower1.3pt\hbox{$\scriptscriptstyle\bigtriangleup$}}%
+ \else
+ \lower1.3pt\hbox{$\scriptscriptstyle\bigtriangleup$}%
+ \fi
+ \cr
+ \xref@nowebsection{\csname xchain[#1][#2]up\endcsname}\cr
+ }
+ }%
+ \box0}%
+}
+
+\def\makenote{%
+ \addtokens\toksB{\noexpand\pdflink{\the\toksC}{\setsafesecno{\the\toksC}}}%
+ \toksC={}\global\countC=0
+}
+
+% redefine \pdflink; N.B.: the semantics of this command sequence have changed, since now
+% #2 is not ignored (as it would have been if using pdftex); instead it becomes a typesetting
+% template for the link
+
+\ifpdftex
+ \ifx\pdfannotlink\undefined\let\pdfannotlink\pdfstartlink\fi% for pdfTeX 0.14
+ \def\pdflink#1#2{\hbox{\pdfannotlink height\ht\strutbox depth\dp\strutbox
+ attr{/Border [0 0 0]} goto num #1 \BlueGreen #2\Black\pdfendlink}}
+\else\def\pdflink#1#2{\setbox0=\hbox{\special{pdf: bc [ \pdflinkcolor ]}{#2}%
+ \special{pdf: ec}}\special{pdf: ann width \thewidth height \theheight
+ depth \thedepth << /Type /Annot /Subtype /Link
+ /Border [0 0 0] /A << /S /GoTo /D (\romannumeral#1) >> >>}\box0\relax}\fi
+
+% while typesetting the table of contents, show the actual section numbers
+% TODO: introduce section accounting for book style typesetting.
+
+\def\contentsline#1#2#3#4#5{\ifnum#2=0 \smallbreak\fi
+ \line{\consetup{#2}#1
+ \rm\leaders\hbox to .5em{.\hfil}\hfil
+ \ \ifacro\pdflink{#3}{#3}\else#3\fi\hbox to3em{\hss#4}}}
+
+\newif\ifxreflocal % are we generating references in noweb style (as page no., position pairs)?
+
+\newread\trystream % generic stream to test for an existence of a file
+
+\def\readlxrefs{% see if the local reference file exists
+ \openin\trystream=\jobname.xxr
+ \ifeof\trystream
+ \else
+ \closein\trystream
+ \input \jobname.xxr
+ \fi
+}
+
+\newif\ifcsecactive
+
+\def\BBB#1#2#3#4{% #1 is the page number
+ % #2 is the section number
+ \csecactivetrue
+}
+
+\def\lxrcurrentpage{-1}
+
+\newcount\lxrcurrentindex
+\newcount\chaptercount
+
+\lxrcurrentindex=\z@
+
+\def\MNM#1#2#3#4{% #1 is the page number
+ % #2 is the section number
+ % #3 is the chapter flag or empty
+ % #4 is reserved
+ \ifnum#1=\lxrcurrentpage
+ \else
+ \lxrcurrentindex=\z@
+ \def\lxrcurrentpage{#1}%
+ \fi
+ {%
+ \tomodalpha\lxrcurrentindex\next
+ \def\nnext{\expandafter\noexpand\csname lxref[#2]\endcsname}%
+ \yystringempty{#3}{%
+ \let\nnnext\empty
+ }{%
+ \global\advance\chaptercount\@ne
+ \def\nnnext{\the\chaptercount}%
+ }%
+ \edef\next{\def\nnext{{#1}{\next}{\nnnext}}}%
+ \expandafter
+ }\next
+ \advance\lxrcurrentindex\@ne
+}
+
+\def\xref@nowebsection#1{% translate the \CWEB\ section number into a \noweb\ reference
+ \expandafter\xr@f@nowebsection\romannumeral-1\csname lxref[#1]\endcsname.%
+}
+
+\def\xr@f@nowebsection#1#2#3.{%
+ {#1}{#2}%
+}
+
+\def\xref@chapter#1{% translate the \CWEB\ section number into a chapter number
+ \expandafter\xr@f@chapter\romannumeral-1\csname lxref[#1]\endcsname.%
+}
+
+\def\xr@f@chapter#1#2#3#4.{%
+ \yystringempty{#3}{{000}}{%
+ {#3}%
+ }%
+}
+
+\def\setsafesecno#1{%
+ \expandafter\ifx\csname lxref[#1]\endcsname\relax
+ #1%
+ \else
+ \xref@nowebsection{#1}%
+ \fi
+}
+
+\def\setsafechapno#1{%
+ \expandafter\ifx\csname lxref[#1]\endcsname\relax
+ #1%
+ \else
+ \xref@chapter{#1}%
+ \fi
+}
+
+\def\tomodalpha#1#2{%
+ \tempca=#1
+ \let#2\empty
+ \bloop
+ \tempcb=\tempca
+ \divide\tempca by 26
+ \tempcc=\tempca
+ \multiply\tempcc by 26
+ \advance\tempcb by -\tempcc
+ \advance\tempcb by `\a
+ \uccode`\.=\tempcb
+ \uppercase{\edef#2{.#2}}%
+ \advance\tempca\m@ne
+ \ifnum\tempca<\z@
+ \else
+ \repeat
+}
+
+\def\XXX#1#2#3{%
+ \ifcsecactive % previous command was \BBB (produced by the \B macro)
+% \expandafter\def\csname lxref[][]\endcsname{}%
+ \csecactivefalse
+ \fi
+}
+
+\def\SSS{\let\XXX\xxxchain} % reference separator
+
+\def\lxrefseparator{%
+ \write\xrefstream{\nx\SSS}%
+}
+
+\def\xxxchain#1#2#3{%
+ \xxxch@in{}{}#3, .%
+}
+
+\newif\iftracenowebchains
+
+\def\xxxch@in#1#2#3, #4.{% #1 is the chain head
+ % #2 is the chain previous
+ % #3 is the chain next
+ % #4 is the remaining chain
+ \yystringempty{#1}{% start the chain
+ \yystringempty{#3}{%
+ \errmessage{The reference chain (#3) is malformed.}%
+ }{%
+ \xxxch@in{#3}{}#4, .%
+ }%
+ }{%
+ \yystringempty{#2}{% potentially the second link
+ \yystringempty{#3}{% this is a one link chain
+ }{% this is a second link
+ \expandafter\def\csname xchain[#1][#1]down\endcsname{#3}%
+ \expandafter\def\csname xchain[#3][#1]up\endcsname{#1}%
+ \iftracenowebchains\message{s(#1.->#3 #3->#1.)}\fi
+ \xxxch@in{#1}{#3}#4, .%
+ }%
+ }{% this is the middle or the end of the chain
+ \yystringempty{#3}{% this is the end of the chain
+ }{%
+ \expandafter\def\csname xchain[#3][#1]up\endcsname{#2}%
+ \expandafter\def\csname xchain[#2][#1]down\endcsname{#3}%
+ \iftracenowebchains\message{m(#1)(#2->#3 #3->#2)}\fi
+ \xxxch@in{#1}{#3}#4, .%
+ }%
+ }%
+ }%
+}
+
+% replace the default reference setting macros in gindex.sty;
+% typeset references so that, for example, \(77){8, 9} becomes
+% \(\pdflink{77}{8c}), \(\pdfpagelink{9}) provided section 77
+% is section 8c by noweb's reckoning.
+
+\def\consumeonexref#1#2{% #1 is the accumulated references
+ % #2 is the section number
+ \expandafter\ifx\csname lxref[#2]\endcsname\relax
+ \errmessage{Section #2 does not have a local index.}%
+ \else
+ \yybreak{\expandafter\c@nsumeonexref\romannumeral-1\xref@nowebsection{#2}{#2}{#1}}%
+ \yycontinue
+}
+
+\def\c@nsumeonexref#1#2#3#4#5{% #1 is the page number of the beginning of the section
+ % #2 is the (\noweb) section number (within the page) where the term appears
+ % #3 is the (\CWEB) section number there the term appears
+ % #4 is the accumulated references
+ % #5 is a list of pages where this term appears
+ \c@nsume@nexref{#1}{#2}{#3}{#4}{}#5, \end
+}
+
+\def\c@nsume@nexref#1#2#3#4#5#6, {% #1 is the page number of the beginning of the section
+ % #2 is the (\noweb) section number (within the page) where the term appears
+ % #3 is the (\CWEB) section number where the term appears
+ % #4 is a total list of processed references
+ % #5 is a local list of processed references
+ % #6 is a page number from the list
+ \ifnum#1=#6 % the term appears on the same page where the section begins
+ \yybreak{\c@nsume@nexr@f{#1}{#2}{#3}#4{#5}{\compoundlink{#3}{#1#2}}}%
+ \else
+ \yybreak{\c@nsume@nexr@f{#1}{#2}{#3}#4{#5}{\pagelink{#6}}}%
+ \yycontinue
+}
+
+\def\c@nsume@nexr@f#1#2#3#4#5#6#7#8{%
+ \c@nsume@n@xr@f{#1}{#2}{#3}{{#4}{#5}{#6}}{#7, #5#8#4}%
+}
+
+\def\c@nsume@n@xr@f#1#2#3#4#5#6\end{% no more page numbers
+ \yystringempty{#6}{%
+ \attachlocallist{#1}{#2}{#3}#4{#5}%
+ }{%
+ \c@nsume@nexref{#1}{#2}{#3}{#4}{#5}#6\end
+ }%
+}
+
+\def\attachlocallist#1#2#3#4#5#6#7{%
+ \grabfinexrefs{#6#7}%
+}
diff --git a/support/splint/tex/stokenset.sty b/support/splint/tex/stokenset.sty
index 7146fcf0c1..9382415f6c 100644
--- a/support/splint/tex/stokenset.sty
+++ b/support/splint/tex/stokenset.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2014, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -14,10 +14,19 @@
% You should have received a copy of the GNU General Public License
% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
-\prettywordpair{OPTIONAL}{{\tt opt}}%
-\prettywordpair{NO_ATTR}{{\tt na}}%
-\prettywordpair{EXTENDED}{{\tt ext}}%
-\prettywordpair{INTEGER}{{$[\,0\ldots9\,]\ast$}}%
-\prettywordpair{IDENTIFIER}{{$[\,\hbox{\tt a}\ldots\hbox{\tt Z}\,0\ldots9\,]\ast$}}%
-\prettywordpair{WILDCARD}{{{\tt *} {\rm or} {\tt ?}}}%
-\prettywordpair{PERCENT_IDENTIFIER}{{\tt\%$[\,\hbox{\tt a}\ldots\hbox{\tt Z}\,0\ldots9\,]\ast$}}%
+% token typesetting for the name parser; we forego setting up
+% automatic token typesetting (see xxexpression example for how
+% this can be done) since the token set is rather small
+
+\prettywordpairwvis{OPTIONAL}{{\tt opt}}{opt}%
+\prettywordpairwvis{NO_ATTR}{{\tt na}}{na}%
+\prettywordpairwvis{EXTENDED}{{\tt ext}}{ext}%
+\prettywordpair{LT}{{\tt l}}%
+\prettywordpair{RT}{{\tt r}}%
+\prettywordpairwvis{$\ undefined}{{\tt\$undefined}}{$undefined}
+\prettywordpairwvis{INTEGER}{{$[\,0\ldots9\,]\ast$}}{[0...9]}%
+\prettywordpairwvis{IDENTIFIER}{{$[\,\hbox{\tt a}\ldots\hbox{\tt Z}\,0\ldots9\,]\ast$}}{[a...Z0...9]*}%
+\prettywordpair{META_IDENTIFIER}{{\cyr\lqq{\rm meta identifier}\rqq}}%
+\prettywordpairwvis{WILDCARD}{{{\tt *} {\rm or} {\tt ?}}}{* or ?}%
+\prettywordpairwvis{C_ESCCHAR}{\hbox{{\sixpoint\.{\\}}$c$}}{\benignescape c}%
+\prettywordpairwvis{PERCENT_IDENTIFIER}{{\tt\%$[\,\hbox{\tt a}\ldots\hbox{\tt Z}\,0\ldots9\,]\ast$}}{\%[a...Z0...9]*}%
diff --git a/support/splint/tex/trt1.sty b/support/splint/tex/trt1.sty
index e3e722c91f..7783e15767 100644
--- a/support/splint/tex/trt1.sty
+++ b/support/splint/tex/trt1.sty
@@ -1,4 +1,4 @@
-% Copyright 2014, Alexander Shibakov
+% Copyright 2014-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -33,5 +33,7 @@
\newtoks\toksd
\newtoks\tokse
\newtoks\toksf
+\newtoks\toksg
+\newtoks\toksh
\expandafter\def\csname loadtexruntime1\endcsname{\endinput}
diff --git a/support/splint/tex/xarithm.sty b/support/splint/tex/xarithm.sty
index 4d424a863c..d971092043 100644
--- a/support/splint/tex/xarithm.sty
+++ b/support/splint/tex/xarithm.sty
@@ -1,4 +1,4 @@
-% Copyright 2014, Alexander Shibakov
+% Copyright 2014-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
diff --git a/support/splint/tex/yxunion.sty b/support/splint/tex/yxunion.sty
index fb0d2460b3..4d03d83c78 100644
--- a/support/splint/tex/yxunion.sty
+++ b/support/splint/tex/yxunion.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2015, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
diff --git a/support/splint/tex/yy.sty b/support/splint/tex/yy.sty
index 22a7948e9d..96769a0fc5 100644
--- a/support/splint/tex/yy.sty
+++ b/support/splint/tex/yy.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2014, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -27,14 +27,12 @@
\newwrite\tokendefs
\let\nx\noexpand
-\def\drvname{bo}
-
\input yycommon.sty % general routines for stack and array access
\input yymisc.sty % helper macros (stack manipulation, table processing, value stack pointers)
+ % parser intitialization, optimization
\input yyinput.sty % input functions
\input yyparse.sty % parser machinery
\input flex.sty % lexer functions
-\input yyboth.sty % parser intitialization, optimization
\ifnum\optimization>\tw@
\input yyfaststack.sty
@@ -43,17 +41,31 @@
\input yystype.sty % scanner auxilary types and functions
\input yyunion.sty % parser data structures
+% modify the input routine to recognize \yyendgame; the somewhat verbose end of
+% the section is necessary to gracefully handle parser failures: the \endparse
+% control sequence must appear outside of any \vb block for \cleanupparse
+% to do its job; the \yyinput reads \vb blocks in pairs so the closing \vb{} is
+% necessary and is removed by \removefinalvb (see limbo.sty and brack.pl for
+% details).
+
+\expandafter\def\expandafter\multicharswitch\expandafter
+{\multicharswitch\yyendgame{\yyinput\yyeof\yyeof\endparseinput\removefinalvb}}
+
\def\indexpseudonamespace{[index]}
% the main parser
\let\parsernamespace\empty
+% the bootstrapping parser needs the name of the file where token equivalences will appear
+
\def\modebootstrap{%
- \edef\tokendeffile{\drvname.tok}%
+ \edef\tokendeffile{\jobname.tok}% so that the name of the token file can track the name of the parser
\edef\bstrapparser{byytab.tex}% sets \bootstrapmodetrue
\def\bootstraplexersetup{\let\yylexreturn\yylexreturnbootstrap}% only return tokens whose value is known at bootstrap
\input yybootstrap.sty%
+ \def\PB##1{}
+ \def\inlineTeXx##1{}
}
\def\modenormal{%
@@ -67,10 +79,7 @@
% \csname ##1\parsernamespace\the##2\endcsname
%}%
\input yyinit.sty%
+ \input yytexlex.sty%
}
-\ifx\modeactive\UNDEFINED
- \def\modeactive{\modenormal}
-\fi
-
-\modeactive
+\input yydebug.sty
diff --git a/support/splint/tex/yybootstrap.sty b/support/splint/tex/yybootstrap.sty
index 185ad3b0a6..97ddb1a666 100644
--- a/support/splint/tex/yybootstrap.sty
+++ b/support/splint/tex/yybootstrap.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2014, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -21,23 +21,36 @@
\immediate\openout\tokendefs=\tokendeffile
\fi
\genericparser
- name: main,
+ name: bootstrap,
ptables: \bstrapparser,
ltables: cweb/ltab.tex,
tokens: {},
asetup: \bootstraplexersetup,
- dsetup: \newlexerstateextra,
- rsetup: \noexpand\savefullstateextra,
+ dsetup: \newlexerstateextra\newparserstateextra,
+ rsetup: {},
optimization: \optimizeall;%
-\tomainparser % this saves the current state
+\tobootstrapparser % this saves the current state
-\input yytexlex.sty
+% stage two macros: parsing
+% note that the bootstrap parser has no way of telling if the \%token declarations
+% belong to the current parser or not (for example, the \flex\ parser has its own
+% declarations); it is thus important to make sure that the \%token declarations in
+% the file visible to the parser belong to a single parser (so the file read by the
+% bootstrap parser does not have declarations sections for a a parser other than
+% \bison's.
-\let\unparse\eatone
+\def\preparsebootstrap{%
+ \let\postparse\postparsebootstrap
+ \tobootstrapparser % this is not currently required since there are no namespace switching macros
+ % in the \TeX\ portion of the text; it is left here in case such macros are used in the future
+ \basicparserinit
+ \bisonparserinit
+ \bisonparserdatainit
+ \yyparse
+}
-\expandafter\def\csname parserstack[b]\endcsname#1#2{%
- \parsevb{#1}% Stage two, start the parsing
+\def\postparsebootstrap{%
\ifyyparsefail % do nothing if parsing failed
\yybreak{}%
\else % Stage three, process the parsed table
@@ -45,26 +58,32 @@
\yycontinue
}
-\expandafter\def\csname parserstack[]\endcsname#1#2{%
- \parsevb{#1}% Stage two, start the parsing
- \ifyyparsefail % do nothing if parsing failed
- \yybreak{}%
- \else % Stage three, process the parsed table
- \yybreak{\initbootstrap\the\table}%
- \yycontinue
+\fillpstack{b}{%
+ \preparsebootstrap
+ \relax
}
-% stage two macros: parsing
+% sections with no parser tag are assumed to be bison sections
-\def\parsevb#1{%
- %\ifchecktable {\toks0{#1}\errmessage{table before parsing: \the\toks0}}\fi
- \tomainparser % this is not currently required since there are no namespace switching macros
- % in the \TeX\ portion of the text; it is left here in case such macros are used in the future
- \doparse{#1}%
+\fillpstack{}{%
+ \preparsebootstrap
+ \relax
}
-\long\def\beginprod#1\endprod{%
- \endgroup
-}
+% ignore in text production examples (there is no way to parse them anyway)
+
+\long\def\beginprod#1\endprod{}
\let\begincprod\beginprod
+
+\def\nameproc#1\with#2{%
+ #2{}{}{}{}{}% pretend the name is empty
+}
+
+\def\frexproc#1\with#2{%
+ #2{}{}{}% pretend the regex is empty
+}
+
+\def\prodstyle#1{}
+
+\input yydebug.sty
diff --git a/support/splint/tex/yyboth.sty b/support/splint/tex/yyboth.sty
deleted file mode 100644
index f15fe006c2..0000000000
--- a/support/splint/tex/yyboth.sty
+++ /dev/null
@@ -1,181 +0,0 @@
-% Copyright 2012-2014, Alexander Shibakov
-% This file is part of SPLinT
-%
-% SPLinT is free software: you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation, either version 3 of the License, or
-% (at your option) any later version.
-%
-% SPLinT is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
-
-% parser environment
-
-\newif\ifyyskipparse
-\newif\ifsaveparseoutput
-\newif\ifchecktable
-\newif\ifchecktrim
-
-\newwrite\exampletable
-
-\def\basicparserinit{%
- \yytext{}%
- \yytextpure{}%
- \yytextseenpure{}%
- \yytextseen{}%
- \yybyte{}%
- \yyfbyte{}\yysbyte{}%
- \yystash{}%
- \yystashseen{}%
- \yyformat{}%
- \yyformatseen{}%
- \yyfutureyytext{}%
- \yyinitstack\yystatestack
- \yyfmark=\z@
- \yysmark=\z@
- \yyfmarklast=\z@
- \formatmarker=\z@
- \yysmarklast=\z@
- \stashmarker=\z@
- \yytextbackupfalse
- \yyg@yyinit=\z@
- \yyg@yystart=\z@
- \YYATBOL=\@ne
- \yyparsefailfalse
- \YYEOBLASTMATCHtrue
-}
-
-\def\parserinit{%
- \basicparserinit
- \yyinitstack\obstackforstring
- \yyinitstack\obstackforstringraw
- \percentpercentcount=\z@
- \lonesting=\z@
- \laststring{}\laststringraw{}%
- \currentlaststring{}\currentlaststringraw{}%
- \parserdatainit
-}
-
-\def\parserdatainit{%
- % make control sequences inserted by the parser non expandable to facilitate
- % token list manipulation; currently nothing is done
-}
-
-% optimization options
-
-\def\optimizeall{%
- % lexer
- \ifnum\optimization>\z@
- \optimize{yynxt}%
- \optimize{yyaccept}%
- \optimize{yydef}%
- \optimize{yychk}%
- \optimize{yybase}%
- \optimize{yyec}%
- \optimize{yymeta}%
- \tracingstats=\@ne
- \fi
- % parser
- \ifnum\optimization>\@ne
- \optimize{yytranslate}%
- \optimize{yyrone}%
- \optimize{yyrtwo}%
- \optimize{yyrthree}%
- \optimize{yydefact}%
- \optimize{yydefgoto}%
- \optimize{yypact}%
- \optimize{yypgoto}%
- \optimize{yytable}%
- \optimize{yycheck}%
- \optimize{yyprhs}%
- \optimize{yyrhs}%
- \optimize{yytoknum}%
- \optimize{yystos}%
- \optimizetext{yytname}%
- \fi
-}
-
-\long\def\endgsec#1#2#3{%
- \ifyyskipparse
- \yybreak{\unparse{#3}}%
- \else
- \yybreak{\csname parserstack[#2]\endcsname{#1}{#3}}%
- \yycontinue
-}
-
-\let\endcprod\endgroup
-\let\endmprod\endgroup
-\let\endprod\endgroup
-
-\def\genericparser name: #1, ptables: #2, ltables: #3, tokens: #4, asetup: #5, dsetup: #6, rsetup: #7, optimization: #8;{%
- % parser initialization
- %
- \expandafter\def\csname #1namespace\endcsname{[#1]}%
- \savecs{local-namespace}\parsernamespace
- \expandafter\let\expandafter\parsernamespace\csname #1namespace\endcsname
- \pinittoks{}%
- \input #2 % load main parser table
- \settokens % set the values of all tokens
- \yystringempty{#4}{}{%
- \input #4 % use token equivalence table to set the values of non-string tokens
- }%
- #5% additional setups
- %
- \input #3 % load lexer tables
- %
- % at this point the macros inside the table files (\newtable, \constset,
- % \yybigswitch, \stashswitch, \addname, \yydoactionswitch, \setflexstates,
- % \stateset, \tokeneq) have set up the corresponding stuctures in
- % the `parser namespace' (e.g. if the parser namespace is `main',
- % \newtable{yyaccept} created a token register \yyaccept[main]),
- % assigned the `generic' names to them (to continue
- % the example above, \newtable does \let\yyaccept\yyaccept[main]) and
- % recorded the corresponding commands in \pinittoks for future use.
- %
- % lexer state macros are namespace specific (just like token names)
- % so they have to be set in each namespace.
- %
- \setflexstates
- #8% possible optimization
- %
- % finally, we add the definitions for the variables used in running
- % the lexer and the parser.
- \newparserstate
- \newlexerstate
- #6% additional data setup (say, \newlexerstateextra)
- %
- % we record all the commands necessary to switch to the desired namespace
- % in a convenient macro
- \expandafter\edef\csname to#1parser\endcsname{%
- \noexpand\savefullstate % save the state of the current parser
- #7% any data that needs to be saved
- % switch to the new namespace
- \let\noexpand\parsernamespace\expandafter\noexpand\csname #1namespace\endcsname
- \the\pinittoks % restore all the tables, tokens and constants, and stacks
- \let\noexpand\getcurrentparser\expandafter\noexpand\csname to#1parser\endcsname
- }%
- \restorecs{local-namespace}\parsernamespace
-}
-
-\def\genericprettytokens namespace: #1, tokens: #2, correction: #3, host: #4;{%
- \savecs{local-namespace}{\parsernamespace\tokeneq}%
- \yystringempty{#2}{}{%
- \expandafter\let\expandafter\parsernamespace\csname #1namespace\endcsname
- \def\tokeneq##1##2{\prettytoken{##1}}%
- \let\tokenpp\prettytoken
- \input #2 % /* re-use token equivalence table to set the typesetting of tokens */
- }%
- \yystringempty{#3}{}{%
- \expandafter\let\expandafter\parsernamespace\csname #1namespace\endcsname
- \input #3 % input customized typesetting rules for tokens
- }%
- \yystringempty{#4}{}{%
- \expandafter\let\expandafter\hostparsernamespace\csname #4namespace\endcsname
- }%
- \restorecs{local-namespace}{\parsernamespace\tokeneq}%
-}
diff --git a/support/splint/tex/yycommon.sty b/support/splint/tex/yycommon.sty
index 5058fafe8a..a8144efaa4 100644
--- a/support/splint/tex/yycommon.sty
+++ b/support/splint/tex/yycommon.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2014, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -38,9 +38,9 @@
% the following macro is a mild example of expansion tricks
\def\yypopstack#1\by#2{%
- \ifnum#2>\z@
- \yyp@pst@ck{#1}{#2}%
- \fi
+ \ifnum#2>\z@
+ \yyp@pst@ck{#1}{#2}%
+ \fi
}
\def\yyp@pstack#1{%
@@ -53,8 +53,8 @@
\let.\expandafter
\def\yyp@pst@ck#1#2{%
- \let\sts\or
- \iffalse{\fi...\def...#1...{...\sts.\ifcase\number\number.\xincrement.{\number#2} \yyp@pstack#1}\else}\fi
+ \let\sts\or
+ \iffalse{\fi...\def...#1...{...\sts.\ifcase\number\number.\xincrement.{\number#2} \yyp@pstack#1}\else}\fi
}
\catcode`\.=12 % other character
@@ -64,17 +64,21 @@
\def\yypop#1\into#2{\def\sts{\consumeone{#2}}#1\stackend#1}
\long\def\consumeone#1#2{%
- #1{#2}\let\sts\scoopupstack
+ #1{#2}\let\sts\scoopupstack
}
% pushing stuff on a stack: \yypush{t o k e n s}\on\yyvs or \expandafter\yypush\number\yystate\on\yyss
-\long\def\yypush#1\on#2{\toksa={#1}\expandafter\toksb\expandafter{#2}\edef#2{\noexpand\sts{\the\toksa}\the\toksb}}
+\long\def\yypush#1\on#2{\expandafter\def\expandafter#2\expandafter{\romannumeral\yyp@sh{#2}{#1}}}
+
+\long\def\yyp@sh#1#2{\expandafter\yyp@@h\expandafter{#1}{#2}}
+
+\long\def\yyp@@h#1#2{0 \sts{#2}#1}
% push register contents on a stack: #1 is a register, #2 is a stack (a control
% sequence that expands to a `\sts{v a l u e}\sts...' list)
-\def\yypushr#1\on#2{\expandafter\toksa\expandafter{#2}\edef#2{\noexpand\sts{\the#1}\the\toksa}}
+\def\yypushr#1\on#2{\expandafter\yypush\expandafter{\the#1}\on#2}
% the first parameter is the stack, the second is the location from the top (a nonnegative number), the third is
% the control sequence that will hold the value;
@@ -82,12 +86,12 @@
\def\yyreadstack#1\at#2\to#3{\edef\sts{\noexpand\skipandcount{\number#2}{\noexpand#3}}#1\stackfinish#1}
\def\skipandcount#1#2#3{%
- \ifnum#1=\z@ %we have got to the element we need
- \def#2{#3}%
- \yybreak\ignorestack
- \else
- \yybreak{\edef\sts{\noexpand\skipandcount{\xdecrement{#1}}{\noexpand#2}}}%
- \yycontinue
+ \ifnum#1=\z@ %we have got to the element we need
+ \def#2{#3}%
+ \yybreak\ignorestack
+ \else
+ \yybreak{\edef\sts{\noexpand\skipandcount{\xdecrement{#1}}{\noexpand#2}}}%
+ \yycontinue
}
% same as above except read the value into a register
@@ -95,12 +99,12 @@
\def\yyreadstackr#1\at#2\to#3{\edef\sts{\noexpand\skipandcountr{\number#2}{#3}}#1\stackfinish#1}
\def\skipandcountr#1#2#3{%
- \ifnum#1=\z@ %we have got to the element we need
- #2#3%
- \yybreak\ignorestack
- \else
- \yybreak{\edef\sts{\noexpand\skipandcountr{\xdecrement{#1}}{\noexpand#2}}}%
- \yycontinue
+ \ifnum#1=\z@ %we have got to the element we need
+ #2#3%
+ \yybreak\ignorestack
+ \else
+ \yybreak{\edef\sts{\noexpand\skipandcountr{\xdecrement{#1}}{\noexpand#2}}}%
+ \yycontinue
}
\long\def\ignorestack#1\stackfinish#2{}
@@ -108,53 +112,53 @@
\def\stackfinish#1{\def#1{0\message{:stack empty:}}}
\def\yyreadvstack#1\upto#2{% assume that #2 > 0
- \edef\sts{\noexpand\splitstack{\number#2}{\expandafter\xincrement\expandafter{\number\toptoks}}}#1\stackend#1%
+ \edef\sts{\noexpand\splitstack{\number#2}{\expandafter\xincrement\expandafter{\number\toptoks}}}#1\stackend#1%
}
\long\def\splitstack#1#2#3{%
- \expandafter\def\csname$'#1\endcsname{#3}% $
- \ifnum#2<\@cclvi % we have not reached the maximum allocated number of token registers
- \expandafter\toksdef\csname$$'#1\endcsname=#2
- \toks#2{#3}%
- \fi
- \ifnum#1=\@ne %we have read the values
- \let\sts\scoopupstack
- \else
- \edef\sts{\noexpand\splitstack{\xdecrement{#1}}{\xincrement{#2}}}%
- \fi
+ \expandafter\def\csname$'#1\endcsname{#3}% $
+ \ifnum#2<\@cclvi % we have not reached the maximum allocated number of token registers
+ \expandafter\toksdef\csname$$'#1\endcsname=#2
+ \toks#2{#3}%
+ \fi
+ \ifnum#1=\@ne %we have read the values
+ \let\sts\scoopupstack
+ \else
+ \edef\sts{\noexpand\splitstack{\xdecrement{#1}}{\xincrement{#2}}}%
+ \fi
}
\def\yypeekvstack#1\upto#2{% assume #2 > 0
- \edef\sts{\noexpand\peelstack{\number#2}{\expandafter\xincrement\expandafter{\number\toptoks}}}#1\relax%
+ \edef\sts{\noexpand\peelstack{\number#2}{\expandafter\xincrement\expandafter{\number\toptoks}}}#1\relax%
}
\long\def\peelstack#1#2#3{%
- \expandafter\def\csname$'#1\endcsname{#3}% $
- \ifnum#2<\@cclvi % we have not reached the maximum allocated number of token registers
- \expandafter\toksdef\csname$$'#1\endcsname=#2
- \toks#2{#3}%
- \fi
- \ifnum#1=\@ne %we have read the values
- \let\sts\eatone
- \else
- \edef\sts{\noexpand\peelstack{\xdecrement{#1}}{\xincrement{#2}}}%
- \fi
+ \expandafter\def\csname$'#1\endcsname{#3}% $
+ \ifnum#2<\@cclvi % we have not reached the maximum allocated number of token registers
+ \expandafter\toksdef\csname$$'#1\endcsname=#2
+ \toks#2{#3}%
+ \fi
+ \ifnum#1=\@ne %we have read the values
+ \let\sts\eatone
+ \else
+ \edef\sts{\noexpand\peelstack{\xdecrement{#1}}{\xincrement{#2}}}%
+ \fi
}
% macros to support new printing routines
\def\yypeeksstack#1\upto#2\withprefix#3{% assume #2 > 0
- \edef\sts{\noexpand\peelsstack{\number#2}}%
- \expandafter\def\expandafter\sts\expandafter{\sts{#3}{}}#1\relax%
+ \edef\sts{\noexpand\peelsstack{\number#2}}%
+ \expandafter\def\expandafter\sts\expandafter{\sts{#3}{}}#1\relax%
}
\long\def\peelsstack#1#2#3#4{%
- \ifnum#1=\@ne %we have read the values
- #3\let\sts\eatone
- \else
- \edef\sts{\noexpand\peelsstack{\xdecrement{#1}}}%
- \expandafter\def\expandafter\sts\expandafter{\sts{#2}{#2{#4}#3}}%
- \fi
+ \ifnum#1=\@ne %we have read the values
+ #3\let\sts\eatone
+ \else
+ \edef\sts{\noexpand\peelsstack{\xdecrement{#1}}}%
+ \expandafter\def\expandafter\sts\expandafter{\sts{#2}{#2{#4}#3}}%
+ \fi
}
% token register access
@@ -164,7 +168,11 @@
}
\def\concatl#1#2{% store the concatenation result in the second sequence
- #2\expandafter\expandafter\expandafter{\expandafter\the\expandafter#1\the#2}%
+ \expandafter\conc@tl\expandafter{\the#2}{#1}{#2}%
+}
+
+\def\conc@tl#1#2#3{%
+ #3\expandafter{\the#2#1}%
}
\def\appendr#1#2{%
@@ -179,12 +187,35 @@
\tokreturn{}{}{#1{\the#1}}%
}
+% appending to token registers without expansion
+
+\long\def\appendlnx#1#2{%
+ \expandafter\app@ndlnx\expandafter{\the#1}{#2}{#1}%
+}
+
+\long\def\app@ndlnx#1#2#3{%
+ #3{#2#1}%
+}
+
+% one can use #1\expandafter{\the#1#2} instead of \appendrnx below;
+% this form (as well as the \appendlnx above) has the advantage of
+% being useable with \romannumeral0 in case one merely wants to record
+% the concatenation for future use
+
+\long\def\appendrnx#1#2{%
+ \expandafter\app@ndrnx\expandafter{\the#1}{#2}{#1}%
+}
+
+\long\def\app@ndrnx#1#2#3{%
+ #3{#1#2}%
+}
+
% the following macros are an expandable way to determine if a token register is empty;
% while a number of different conditionals can be used, including plain \iffalse,
% this choice seems to result in a shortest macro and the fewest number of \expandafter's;
% an idea from
% http://tex.stackexchange.com/questions/2936/test-whether-token-list-is-empty
-% where it is attributed to Ulrich Diez can be generalized to make multiple tests inside braces
+% where it is attributed to Ulrich Diez can be generalized to apply multiple tests inside braces
% in a row; the macros from that discussion are quoted below; note, however, that these macros
% lead to unbalanced braces inside alignments (see The \TeX book, Appendix~D, p.~385 for the
% discussion of the `master counter' and the `balance counter' and their behavior when
@@ -205,17 +236,17 @@
% non-brace while the parameter scanning mechanism of \TeX\ will try
% to collect the smallest possible balanced input; the `excessive'
% braces will disappear in the expansion of the `\if...' construct;
-% the reason \if or other macros that expand their argumens are so well suited for this
+% the reason \if or other macros that expand their arguments are so well suited for this
% `chain expansion' mechanism is in the fact that the expansions for \string and \if... are launched
% from the same point.
\long\def\yytoksempty#1{%
- \iffalse{{\fi
- \if{\expandafter\yytoks@mpty\the#1}}}%
- \yybreak\yyfirstoftwo
- \else
- \yybreak\yysecondoftwo
- \yycontinue
+ \iffalse{{\fi
+ \if{\expandafter\yytoks@mpty\the#1}}}%
+ \yybreak\yyfirstoftwo
+ \else
+ \yybreak\yysecondoftwo
+ \yycontinue
}
% when the token list is empty, \TeX\ will try to expand \yybreak premaurely;
@@ -225,12 +256,12 @@
% gleaned from `\TeX\ the program')
\long\def\yystringempty#1{%
- \iffalse{{\fi
- \if{\yytoks@mpty#1}}}%
- \yybreak\yyfirstoftwo
- \else
- \yybreak\yysecondoftwo
- \yycontinue
+ \iffalse{{\fi
+ \if{\yytoks@mpty#1}}}%
+ \yybreak\yyfirstoftwo
+ \else
+ \yybreak\yysecondoftwo
+ \yycontinue
}
\catcode`\>=2
@@ -253,7 +284,7 @@
}
% the macros below are a derivation of David Kastrup's magnificent string comparison
-% macros below:
+% macros:
% \def\strequal#1{\number\strequalstart{}{}#1\relax}
% \def\strequalstart#1#2#3{\if#3\relax\strequalstop\fi
% \strequalstart{\if#3#1}{#2\fi}}
@@ -261,7 +292,7 @@
%
% use: \if\strequal{string}{string}...
%
-% they were adjusted to handle spaces in the strings and conform to a different
+% they were adjusted to handle spaces inside the strings and to conform to a different
% syntax, namely \yyifsamestring{string1}{string2}{true}{false}
% the original macros use the fact that, say \if1\fi will expand to nothing and
% that \number'13 expands to 11 whereas \number13 expands to 13; the elegance of
@@ -269,7 +300,7 @@
\edef\yyifsamestring#1{\noexpand\yyifsamestr@ng{}{}#1 \noexpand\yyifsam@str@ng\space}
\def\yyifsamestr@ng#1#2#3 {\ifx\yyifsam@str@ng#3\yyifsam@str@ng\fi
- \yyifs@m@str@ng{#1}{#2}#3\space}
+ \yyifs@m@str@ng{#1}{#2}#3\space}
\def\yyifs@m@str@ng#1#2#3{%
\if#3\space
@@ -299,12 +330,12 @@
% but then \yytoks@mpty could not be reused
\long\def\yystartsinbrace#1{%
- \iffalse{\fi
- \if{\yytoks@mpty#1}}%
- \yybreak\yysecondoftwo
- \else
- \yybreak\yyfirstoftwo
- \yycontinue
+ \iffalse{\fi
+ \if{\yytoks@mpty#1}}%
+ \yybreak\yysecondoftwo
+ \else
+ \yybreak\yyfirstoftwo
+ \yycontinue
}
% a test to determine whether the argument is a given control sequence
@@ -333,89 +364,86 @@
\long\def\yyfirstoftwo#1#2{#1}
\long\def\yysecondoftwo#1#2{#2}
+\long\def\yyfirstofthree#1#2#3{#1}
\long\def\yysecondofthree#1#2#3{#2}
\long\def\yythirdofthree#1#2#3{#3}
-% arrays of integers are going to be represented by a string of tokens `element0 \or element1 \or ...'
+\long\def\yypioneofthree#1#2#3{{#1}}
+\long\def\yypitwoofthree#1#2#3{{#2}}
+\long\def\yypithreeofthree#1#2#3{{#3}}
+
+% (unoptimized) arrays of integers are represented by a string of tokens `element0 \or element1 \or ...'
% #2 is a register (otherwise the case and the integer from the array `coalesce');
% the following macro was designed to make something like
-% \vara=\getelemof\yytable\at\yyn\relax possible so it has to expand to a number;
+% \tempca=\getelemof\yytable\at\yyn\relax possible so it has to expand to a number;
% incidentally, some care should be taken using the above asignment to make sure that
% it is not followed by an expandable token (such as \if) as in this case the token might be
-% expanded prematurely, as the assignment is looking for the first non-expandable token which
+% expanded prematurely while the assignment is looking for the first non-expandable token which
% is not part of the number; this is the reason for the \relax
-\def\getelemof#1\at#2{% the original meaning of this macro
- \ifcase\expandafter#2\the#1\else\fi
+\def\getelemof#1\at#2{% #1 is the name of the token register containing the array, #2 is the index
+ \expandafter\get@l@mof\expandafter{\csname#1\endcsname}{#2}%
}
-\def\getelemof#1\at#2{% no longer limited to registers for #2
- \expandafter\get@lemof\expandafter{\the#1}{#2}%
+\def\get@l@mof#1#2{%
+ \expandafter\get@lemof\expandafter{\the#1}{#2}%
}
\def\get@lemof#1#2{%
- \ifcase#2 #1\else\fi
+ \ifcase#2 #1\else\fi
}
-\def\fastgetelemof#1\at#2{%
- \csname #1\parsernamespace\number#2\endcsname
-}
-
-\def\fgetelemof#1\at#2{%
- \expandafter\ifx\csname optopt[#1]\parsernamespace\endcsname\relax
- \expandafter\getelemof\csname #1\endcsname\at{#2}%
- \else
- \csname #1\parsernamespace\number#2\endcsname
- \fi
-}
+\let\fgetelemof\getelemof
% a nestable loop
-\def\bloop#1\repeat{#1\bloop{#1}\repeat\fi}
+\def\bloop#1\repeat{#1\bl@op{#1}\repeat\fi}
+
+\def\bl@op#1\repeat\fi{\fi#1\bl@op{#1}\repeat\fi}
% optimization macros: currently, the level of optimization has to be consistent throughout the
% document, i.e. \optimize macros have to be called on the same arrays after loading.
% the reason is the yyfaststack.sty file that modifies the \newtable macro once for all the tables
\def\optimize#1{%
- \setoptopt{#1}%
- \tempca\z@
- \bloop
- \tempcb=\expandafter\ifcase\expandafter\tempca\the\csname#1\endcsname\else\@MM\fi\relax
- \ifnum\tempcb<\@MM %
- \expandafter\edef\csname #1\parsernamespace\the\tempca\endcsname{\the\tempcb}%
- \advance\tempca\@ne
- \repeat
+ \setoptopt{#1}%
+ \tempca\z@
+ \bloop
+ \tempcb=\expandafter\ifcase\expandafter\tempca\the\csname#1\endcsname\else\@MM\fi\relax
+ \ifnum\tempcb<\@MM %
+ \expandafter\edef\csname #1\parsernamespace\the\tempca\endcsname{\the\tempcb}%
+ \advance\tempca\@ne
+ \repeat
}
\def\optimizetext#1{% optimizing text arrays
- \setoptopt{#1}%
- \tempca\z@
- \@ptimizetext{#1}
+ \setoptopt{#1}%
+ \tempca\z@
+ \@ptimizetext{#1}
}
\def\@ptimizetext#1{%
- \edef\next{\expandafter\ifcase\expandafter\tempca\the\csname#1\endcsname\else\end\fi}%
- \ifx\next\endcontainer
- \let\next\eatone
- \else
- \expandafter\edef\csname #1\parsernamespace\the\tempca\endcsname{\next}%
- \advance\tempca\@ne
- \let\next\@ptimizetext
- \fi
- \next{#1}%
+ \edef\next{\expandafter\ifcase\expandafter\tempca\the\csname#1\endcsname\else\end\fi}%
+ \ifx\next\endcontainer
+ \let\next\eatone
+ \else
+ \expandafter\edef\csname #1\parsernamespace\the\tempca\endcsname{\next}%
+ \advance\tempca\@ne
+ \let\next\@ptimizetext
+ \fi
+ \next{#1}%
}
\def\uoptimize#1{% same as the macro above but produces nonnegative constants as \mathchardef's
- \setoptopt{#1}%
- \tempca\z@
- \bloop
- \tempcb=\expandafter\ifcase\expandafter\tempca\the\csname#1\endcsname\else\@MM\fi\relax
- \ifnum\tempcb<\@MM %
- \toksa\expandafter{\csname #1\parsernamespace\the\tempca\endcsname}%
- \edef\next{\mathchardef\the\toksa=\the\tempcb\relax}\next
- \advance\tempca\@ne
- \repeat
+ \setoptopt{#1}%
+ \tempca\z@
+ \bloop
+ \tempcb=\expandafter\ifcase\expandafter\tempca\the\csname#1\endcsname\else\@MM\fi\relax
+ \ifnum\tempcb<\@MM %
+ \toksa\expandafter{\csname #1\parsernamespace\the\tempca\endcsname}%
+ \edef\next{\mathchardef\the\toksa=\the\tempcb\relax}\next
+ \advance\tempca\@ne
+ \repeat
}
\def\setoptopt#1{%
@@ -466,29 +494,29 @@
\newif\iftracedfa
\def\taction#1\in#2{%
- \begingroup
- \edef\acstring{#1}% in case #1 is, say, \the\toksa, so we no longer have to keep track of it
- \iftracedfa\derrmessage{acting on <\meaning\acstring>\space in (\string#2) \getstatename#2 }\fi
- \toksa\expandafter{#2}\toksb\expandafter{\acstring}%
- \edef\next{\toksa{\the\toksa\the\toksb{%
- \iftracedfa\noexpand\derrmessage{default action: \noexpand\meaning\noexpand\default}\fi
- \noexpand\default}}%
- \def\noexpand\next####1\the\toksb####2####{\noexpand\grabaction}}\next
- \expandafter\next\the\toksa\grabaction
- \tokreturn{}{}{\the\toksa}%
+ \begingroup
+ \edef\acstring{#1}% in case #1 is, say, \the\toksa, so we no longer have to keep track of it
+ \iftracedfa\ferrmessage{acting on <\meaning\acstring>\space in (\string#2) \getstatename#2 }\fi
+ \toksa\expandafter{#2}\toksb\expandafter{\acstring}%
+ \edef\next{\toksa{\the\toksa\the\toksb{%
+ \iftracedfa\noexpand\ferrmessage{default action: \noexpand\meaning\noexpand\default}\fi
+ \noexpand\default}}%
+ \def\noexpand\next####1\the\toksb####2####{\noexpand\grabaction}}\next
+ \expandafter\next\the\toksa\grabaction
+ \tokreturn{}{}{\the\toksa}%
}
\def\tactionx#1\in#2{% exclusive version of the macro above (i.e. match the last action before the brace)
- \begingroup
- \edef\acstring{#1}% in case #1 is, say, \the\toksa, so we no longer have to keep track of it
- \iftracedfa\errmessage{acting on <\meaning\acstring>\space in (\string#2) \getstatename#2 }\fi
- \toksa\expandafter{#2}\toksb\expandafter{\acstring}%
- \edef\next{\toksa{\the\toksa\the\toksb{%
- \iftracedfa\noexpand\derrmessage{default action: \noexpand\meaning\noexpand\default}\fi
- \noexpand\default}}%
- \def\noexpand\next####1\the\toksb####{\noexpand\grabaction}}\next
- \expandafter\next\the\toksa\grabaction
- \tokreturn{}{}{\the\toksa}%
+ \begingroup
+ \edef\acstring{#1}% in case #1 is, say, \the\toksa, so we no longer have to keep track of it
+ \iftracedfa\errmessage{acting on <\meaning\acstring>\space in (\string#2) \getstatename#2 }\fi
+ \toksa\expandafter{#2}\toksb\expandafter{\acstring}%
+ \edef\next{\toksa{\the\toksa\the\toksb{%
+ \iftracedfa\noexpand\ferrmessage{default action: \noexpand\meaning\noexpand\default}\fi
+ \noexpand\default}}%
+ \def\noexpand\next####1\the\toksb####{\noexpand\grabaction}}\next
+ \expandafter\next\the\toksa\grabaction
+ \tokreturn{}{}{\the\toksa}%
}
\def\getstatename#1{\expandafter\g@tstatename#1.\raw}
@@ -496,11 +524,11 @@
\def\g@tstatename#1#2\raw{\expandafter\eatone\string#1}
\def\caction#1\in#2{%
- \begingroup
- \uccode`.=#1\relax
- \uppercase{\toksa{\taction{.}\in}}%
- \toksb{#2}\concat\toksa\toksb
- \tokreturn{}{}{\the\toksa}%
+ \begingroup
+ \uccode`.=#1\relax
+ \uppercase{\toksa{\taction{.}\in}}%
+ \toksb{#2}\concat\toksa\toksb
+ \tokreturn{}{}{\the\toksa}%
}
\def\checkforcount#1{% a rough implementation of `type checking' for a parameter
@@ -513,17 +541,182 @@
}
\def\action#1\in#2{%
- \begingroup
- \checkforcount#1%
- \toksb{{#1}\in{#2}}\concat\toksa\toksb
- \tokreturn{}{}{\the\toksa}%
+ \begingroup
+ \checkforcount#1%
+ \toksb{{#1}\in{#2}}\concat\toksa\toksb
+ \tokreturn{}{}{\the\toksa}%
}%
\let\switchon\taction
+\let\switchonwithtype\action % phase out \action, since it is a rather common name
\let\default\relax
\def\grabaction#1#2\grabaction{\toksa{#1}}
+% switch manipulation macros: adding and replacing labels and actions
+% the macros assume that the switch to be manipulated is well formed, otherwise
+% no assumptions have been made;
+% if the label is not present in the switch or the new label already exists, an
+% error is returned
+% the macros are not expandable but can be made such with some
+% (rather significant) effort
+
+% #1 is the label at which to change
+% #2 is the new label
+% #3 is the name of the new switch
+% #4 is the switch
+% #5 is the operation to perform if #2 is present and #3 is not
+\def\matchswitch#1#2#3#4#5{%
+ \expandafter\matchswitch@a\expandafter{#1}{#2}{#3}{#4}{#1}{\matchswitch@e}{#5}%
+}
+
+% #1 is the expanded version of the switch
+% #2 is the label at which to change
+% #3 is the new label
+% #4 is the name of the new switch
+% #5 is the switch
+% #6 is the test sequence to apply if #2 is present
+% #7 is the operation to perform if #2 is present and #3 is not
+\def\matchswitch@a#1#2#3#4#5#6#7{\matchswitch@b{#1}{#1}{#2}{#3}{#4}{#5}{#6}{#7}}
+
+% #1 is the expanded version of the switch
+% #2 is the expanded version of the switch
+% #3 is the label at which to change
+% #4 is the new label
+% #5 is the name of the new switch
+% #6 is the switch
+% #7 is the test sequence to apply if #3 is present
+% #8 is the operation to perform if #3 is present and #4 is not
+\def\matchswitch@b#1#2#3#4#5#6#7#8{%
+ \def#5##1#3{\matchswitch@c}%
+ \expandafter\expandafter\expandafter#5\expandafter\eatone\string{#1#3}{#2}{#3}{#4}{#5}{#6}{#7}{#8}%
+}
+
+\def\matchswitch@c{%
+ \expandafter\expandafter\expandafter\matchswitch@d
+ \expandafter\expandafter\expandafter{\expandafter\eatone\string}%
+}
+
+% #1 is the match result
+% #2 is the expanded version of the switch
+% #3 is the label at which to change
+% #4 is the new label
+% #5 is the name of the new switch
+% #6 is the switch
+% #7 is the test sequence to apply if #3 is present
+% #8 is the operation to perform if #3 is present and #4 is not
+\def\matchswitch@d#1#2#3#4#5#6#7#8{%
+ #7{#1}{#2}{#3}{#4}{#5}{#6}{#8}%
+}
+
+% #1 is the match result
+% #2 is the expanded version of the switch
+% #3 is the label at which to change
+% #4 is the new label
+% #5 is the name of the new switch
+% #6 is the switch
+% #7 is the operation to perform if #3 is present and #4 is not
+\def\matchswitch@e#1#2#3#4#5#6#7{%
+ \yystringempty{#1}{% label not present
+ \errhelp{Switch #6 contents: #2}%
+ \errmessage{label \nx#3 was not found in switch \nx#6}%
+ }{%
+ \yystringempty{#4}{% no new label, skip the next test
+ #7{#2}{#3}{#4}{#5}%
+ }{%
+ \matchswitch@a{#2}{#4}{#3}{#5}{#6}{\matchswitch@f}{#7}%
+ }%
+ }%
+}
+
+\def\matchswitch@f#1#2#3#4#5#6#7{%
+ \yystringempty{#1}{% label not present
+ #7{#2}{#4}{#3}{#5}%
+ }{%
+ \errhelp{Switch #6 contents: #2}%
+ \errmessage{label \nx#3 already exists in switch \nx#6}
+ }%
+}
+
+% add a label to an existing action
+
+\def\extendswitch#1\at#2\by#3\to#4{%
+ \matchswitch{#1}{#2}{#3}{#4}{\@xtendswitch}%
+}
+
+\def\@xtendswitch#1#2#3#4{%
+ \def#4##1#2##2#3{\def#4{##1#2#3##2}}%
+ #4#1#3%
+}
+
+% replace an existing label inside a switch
+
+\def\replaceswitch#1\at#2\by#3\to#4{%
+ \matchswitch{#1}{#2}{#3}{#4}{\r@placeswitch}%
+}
+
+\def\r@placeswitch#1#2#3#4{%
+ \def#4##1#2##2#3{\def#4{##1#3##2}}%
+ #4#1#3%
+}
+
+% replace an existing action inside a switch
+
+\def\replaceaction#1\at#2\by#3\to#4{%
+ \matchswitch{#1}{#2}{}{#4}{\r@placeaction{#3}}%
+}
+
+% #1 holds the new action
+% #2 is the expanded switch
+% #3 is the label at which to make the replacement
+% #4 is empty
+% #5 is the name of the new switch
+\def\r@placeaction#1#2#3#4#5{%
+ \r@placeaction@a{#2}{#3}{#5}{#1}%
+}
+
+% #1 is the expanded switch
+% #2 is the label at which to make the replacement
+% #3 is the name of the new switch
+% #4 is the new action
+\def\r@placeaction@a#1#2#3#4{%
+ \def#3##1#2##2##{\expandafter\expandafter\expandafter
+ \r@placeaction@b\expandafter\expandafter\expandafter{\expandafter\eattwo\string}}%
+ \expandafter\expandafter\expandafter#3\expandafter\eatone\string{#1}{#2}{#3}{#1}{#4}%
+}
+
+% #1 is the part of the switch after the action
+% #2 is the label at which to make the replacement
+% #3 is the name of the new switch
+% #4 is the expanded switch
+% #5 is the new action
+\def\r@placeaction@b#1#2#3#4#5{%
+ \def#3##1#2##2##{\expandafter\expandafter\expandafter
+ \r@placeaction@c\expandafter\expandafter\expandafter{\expandafter\eatone\string}{##1}{##2}}%
+ \expandafter\expandafter\expandafter#3\expandafter\eattwo\string{#4.}{#2}{#3}{#1}{#5}%
+}
+
+% #1 = {{before the label}{between the label and the action} after the action . }
+\def\r@placeaction@c#1{%
+ \expandafter\yystringempty\expandafter{\r@placeaction@f#1}{% the remainder of the switch is gone
+ \expandafter\r@placeaction@d\r@placeaction@e#1%
+ }{%
+ \expandafter\r@placeaction@c\expandafter{\r@placeaction@e#1}%
+ }
+}
+
+% #1 before the label
+% #2 between the label and the action
+% #3 is the label
+% #4 is the name of the new switch
+% #5 part of the switch after the action
+% #6 is the new action
+\def\r@placeaction@d#1#2#3#4#5#6{\def#4{#1#3#2#6#5}}
+
+\def\r@placeaction@e#1#2#3.{{#1}{#2}}
+
+\def\r@placeaction@f#1#2#3.{}
+
% grab the first token unless it is a space or a brace
\def\getfirsttoken#1{%
@@ -554,7 +747,8 @@
\long\def\yybreak@@@#1#2\yycontinue{\fi\fi\fi\fi#1}
\long\def\yybreak@@@@#1#2\yycontinue{\fi\fi\fi\fi\fi#1}
-% we intentionally leave \yycontinue undefined since it should not be expanded normally
+% we intentionally leave \yycontinue defined as an \errmessage
+% since it should not be expanded normally;
% every conditional that uses \yybreak?{...} ... \yycontinue construct
% must have an \else clause, i.e.\ a conditional such as
% \if ab
@@ -562,27 +756,21 @@
% \yycontinue
% is a bad idea as it will result in an incomplete \iffalse
%\let\yycontinue\fi
+\def\yycontinue{\errmessage{\noexpand\yycontinue should never be expanded!}}
+% this also makes \if...\yycontinue constructs unskippable; this can be remedied by
+% adding a \fi before \yycontinue, which will not affect a properly constructed
+% conditional
% macros for taking care of extra tokens
-\long\def\yyid#1{#1}
-\long\def\yypione#1#2{#1}
-\long\def\yypitwo#1#2{#2}
+\long\def\yyid#1{#1} % this is misnamed since it changes #1 by stripping braces and spaces
\long\def\yyswap#1#2{#2#1}
\long\def\eatone#1{}
\long\def\eattwo#1#2{}
+\long\def\eatthree#1#2#3{}
\long\def\eattoend#1\end{}
+\long\def\eattospace#1 {}
\input xarithm.sty
-% temporaries
-
-\input trt1.sty
-
-% \tempcd used by \printrule and implicit rule name macros in yymisc.sty
-% \tempce used by implicit rule name macros in yymisc.sty
-
-% \tokse and \toksf so far only used in the bison action for
-% \codepropstype
-
\newif\ifbootstrapmode
diff --git a/support/splint/tex/yydebug.sty b/support/splint/tex/yydebug.sty
new file mode 100644
index 0000000000..0d763aecfa
--- /dev/null
+++ b/support/splint/tex/yydebug.sty
@@ -0,0 +1,148 @@
+% Copyright 2012-2020, Alexander Shibakov
+% This file is part of SPLinT
+%
+% SPLinT is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% SPLinT is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
+
+% handy debugging shortcuts
+
+\def\yydebugsetup{% initialize debugging (note that arbitrary commands
+ % can be also inserted by \insertraw{...}
+ \expandafter\def\expandafter\multicharswitch % allow execution of any code in the middle of input
+ \expandafter{\multicharswitch\yydebugbegin\yydebugend{\the\yybyte}}%
+}
+
+\def\yydebuggenericstart{% generic command executed in the middle of input
+ \yydebugmost % turn on tracing
+ \yyinput % ... and continue
+}
+
+\def\yydebuggenericfinish{% stop debugging
+ \yydebugnone % turn off tracing
+ \yyinput % ... and continue
+}
+
+\let\yydebugbegin\yydebuggeneric
+\let\yydebugend\yydebuggenericfinish
+
+\newif\ifcdebug % a temporary conditional
+
+\def\yydebugall{% turn all debugging options on
+ \yydebugmost
+ \checktabletrue
+ \saveparseoutputtrue
+}
+
+\def\yydebugparse{%
+ \tracelookaheadtrue
+ \traceparseresultstrue
+ \traceparserstatestrue
+ \tracerulestrue
+ \tracestackstrue
+ \tracediscardedinputtrue
+}
+
+\def\reporttokendisplay{% to make this skippable in bootstrap mode
+ \ifdisplaytokenraw\ferrmessage{tokens are typeset as is^^J}\fi
+}
+
+\def\yydebugmost{% do not save or display the tables
+ \ifbootstrapmode
+ \ferrmessage{*** bootstrap mode is on ***^^J^^J}%
+ \else
+ \reporttokendisplay
+ \checktrimtrue
+ \parseverbosetrue
+ \checktrailingstashtrue
+ \fi
+ \ifbracketedvisible\ferrmessage{Symbolic term names are visible^^J}\fi
+ \iftermindex\else\ferrmessage{Indexing is turned off^^J}\fi
+ \ifshowlastaction\else\ferrmessage{Last action will not be shown}\fi
+ \ifxreflocal\else\ferrmessage{Cross references are generated in noweb style}\fi
+ \ifx\optimization\UNDEFINED
+ \else
+ \ferrmessage{Optimization level set at \number\optimization^^J}%
+ \fi
+
+ \tracingonline=3
+ \showboxbreadth=10000
+ \showboxdepth=10000
+%
+ \yydebugparse
+ \traceactioncodetrue
+ \traceactionstrue
+ \tracebadcharstrue
+ \tracebadnamestrue
+ \tracedfatrue
+ \traceflexbufferstrue
+ \tracenamestrue
+ \tracestatestrue
+ \traceswitchlabelstrue
+ \tracetexpptrue
+ \tracetokennamestrue
+ \yyflexdebugtrue
+ \yyinputdebugtrue
+ \yytracereplacementstrue
+ \traceprettytokenstrue
+}
+
+\def\yydebugnone{% turn all debugging options off
+ \checktablefalse
+ \ifbootstrapmode
+ \else
+ \checktrimfalse
+ \parseverbosefalse
+ \fi
+ \saveparseoutputfalse
+ \traceactioncodefalse
+ \traceactionsfalse
+ \tracebadcharsfalse
+ \tracebadnamesfalse
+ \tracedfafalse
+ \tracediscardedinputfalse
+ \traceflexbuffersfalse
+ \tracelookaheadfalse
+ \tracenamesfalse
+ \traceparseresultsfalse
+ \traceparserstatesfalse
+ \tracerulesfalse
+ \tracestacksfalse
+ \tracestatesfalse
+ \traceswitchlabelsfalse
+ \tracetexppfalse
+ \tracetokennamesfalse
+ \yyflexdebugfalse
+ \yyinputdebugfalse
+ \yytracereplacementsfalse
+ \cdebugfalse
+}
+
+% miscellaneous shortcuts
+
+\def\shownethe#1{%
+ {%
+ \edef\next{\the#1}%
+ \ifx\next\empty
+ \else
+ \showthe#1%
+ \fi
+ }%
+}
+
+\def\showem#1#2#3{\toksa{#1}\toksb{#2}\toksc{#3}{\newlinechar=`^^J%
+ \errmessage{%
+ arg. 1: \the\toksa^^J%
+ arg. 2: \the\toksb^^J%
+ arg. 3: \the\toksc%
+}}}
+
diff --git a/support/splint/tex/yyfaststack.sty b/support/splint/tex/yyfaststack.sty
index cc43c33115..9bf46b3d1e 100644
--- a/support/splint/tex/yyfaststack.sty
+++ b/support/splint/tex/yyfaststack.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2014, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -14,23 +14,26 @@
% You should have received a copy of the GNU General Public License
% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
-% fast versions of stack access functions
+% fast(er) versions of stack access functions
\catcode`\@=11
-\def\yyinitstack#1{% #1 is the counter
+\def\yyinitstack#1{% #1 is the name of the stack
\csname \expandafter\eatone\string#1<count>\endcsname\m@ne
}
% stacks will be defined as pairs ( \s t a c k n a m e [n u m b e r], \s t a c k n a m e <count> )
-% where \s t a c k n a m e [n u m b e r] is a control sequence and \s t a c k n a m e <count>
-% is a \count register
+% where \s t a c k n a m e [n u m b e r] is an associative array of control sequences
+% and \s t a c k n a m e <count> is a \count register
%
% note that in the implementaion below the stack grows `the wrong
% way'; this is done for convenience, since there is no `memory read
% with increment' operation, the `usual' (say, hardware) stack
% implementations take advantage of, and our stack can grow
-% unrestricted this way
+% unrestricted this way; also note that while the array is namespace specific,
+% the stack pointer is not, so special effort is required to preserve it
+
+\let\yyinitarray\yyinitstack % using the stack as an array only makes sense for the optimized version
\def\getstackpointer#1{% expands to the value of the current top of the stack position
\expandafter\the\csname \expandafter\eatone\string#1<count>\endcsname
@@ -38,7 +41,15 @@
\def\gettopofstackcs#1{% expands to the control sequence (a member of the associative array)
% that holds the value of the current element at the top of the stack
- \csname \expandafter\eatone\string#1[\getstackpointer#1]\parsernamespace\endcsname
+ \csname \expandafter\eatone\string#1[\getstackpointer#1]\parsernamespace \endcsname
+}
+
+\def\gettopofstackcsx#1{% a version of the above to be used with \romannumeral
+ 0\expandafter\noexpand\csname \expandafter\eatone\string#1[\getstackpointer#1]\parsernamespace \endcsname
+}
+
+\def\gettopofstackcsxx#1{% to be used with \romannumeral, expands to the contents of the top stack element
+ 0\expandafter\expandafter\expandafter\space\csname \expandafter\eatone\string#1[\getstackpointer#1]\parsernamespace \endcsname
}
\def\getmidstackcs#1#2{% expands to the control sequence (a member of the associative array)
@@ -46,6 +57,10 @@
\csname \expandafter\eatone\string#1[#2]\parsernamespace\endcsname
}
+\def\getmidstackcsx#1#2{% a version of the above to be used with \romannumeral, safe to use with \edef
+ 0\expandafter\noexpand\csname \expandafter\eatone\string#1[#2]\parsernamespace\endcsname
+}
+
\def\movestackpointer#1\by#2{%
\expandafter\advance\csname \expandafter\eatone\string#1<count>\endcsname#2%
}
@@ -56,8 +71,8 @@
%
-\def\yypop#1\into#2{%
- #2\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{\gettopofstackcs#1}%
+\def\yypop#1\into#2{% pops the stack #1, stores the top element in token register #2
+ #2\expandafter{\romannumeral\gettopofstackcsxx#1}%
\movestackpointer#1\by\m@ne
}
@@ -68,6 +83,11 @@
\expandafter\expandafter\expandafter\def\gettopofstackcs#2{#1}%
}
+\long\def\yypushx#1\on#2{% push with expand
+ \movestackpointer#2\by\@ne
+ \expandafter\expandafter\expandafter\edef\gettopofstackcs#2{#1}%
+}
+
% push register contents on a stack: #1 is a register, #2 is a stack
\def\yypushr#1\on#2{%
@@ -199,6 +219,20 @@
\movestackpointer#1\by#2\relax
}
+% faster array access macros
+
+\def\fastgetelemof#1\at#2{%
+ \csname #1\parsernamespace\number#2\endcsname
+}
+
+\def\fgetelemof#1\at#2{% this definition allows mixing optimized and unoptimized tables
+ \expandafter\ifx\csname optopt[#1]\parsernamespace\endcsname\relax
+ \getelemof{#1}\at{#2}%
+ \else
+ \csname #1\parsernamespace\number#2\endcsname
+ \fi
+}
+
% new stack access macros that read the stack directly (to reduce namespace pollution)
% these are here more as an example
diff --git a/support/splint/tex/yyinit.sty b/support/splint/tex/yyinit.sty
index 8d9b7d33c3..5091c05007 100644
--- a/support/splint/tex/yyinit.sty
+++ b/support/splint/tex/yyinit.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2014, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -22,10 +22,10 @@
name: main,
ptables: cweb/gyytab.tex,
ltables: cweb/ltab.tex,
- tokens: \drvname.tok,
+ tokens: bo.tok,
asetup: {},
- dsetup: \newlexerstateextra,
- rsetup: \noexpand\savefullstateextra,
+ dsetup: \newlexerstateextra\newparserstateextra,
+ rsetup: {},
optimization: \optimizeall;%
% prologue parser
@@ -34,12 +34,63 @@
name: prologue,
ptables: cweb/dyytab.tex,
ltables: cweb/ltab.tex,
- tokens: \drvname.tok,
+ tokens: bo.tok,
asetup: {},
- dsetup: \newlexerstateextra,
- rsetup: \noexpand\savefullstateextra,
+ dsetup: \newlexerstateextra\newparserstateextra,
+ rsetup: {},
optimization: \optimizeall;%
+% flex parser
+
+\genericparser
+ name: flex,
+ ptables: cweb/fiptab.tex,
+ ltables: cweb/filtab.tex,
+ tokens: fo.tok,
+ asetup: {},
+ dsetup: {},
+ rsetup: {},
+ optimization: {};% optimized by the driver (--optimize-tables, --optimize-actions)
+
+% flex regex parser
+
+\genericparser
+ name: flexre,
+ ptables: cweb/reptab.tex,
+ ltables: cweb/filtab.tex,
+ tokens: fo.tok,
+ asetup: {},
+ dsetup: {},
+ rsetup: {},
+ optimization: {};% optimized by the driver (--optimize-tables, --optimize-actions)
+
+% flex section 2 parser
+
+\genericparser
+ name: flextwo,
+ ptables: cweb/raptab.tex,
+ ltables: cweb/filtab.tex,
+ tokens: fo.tok,
+ asetup: {},
+ dsetup: \newparserstateextra,
+ rsetup: {},
+ optimization: {};% optimized by the driver (--optimize-tables, --optimize-actions)
+
+% flex section 1 parser
+
+\genericparser
+ name: flexone,
+ ptables: cweb/ddptab.tex,
+ ltables: cweb/filtab.tex,
+ tokens: fo.tok,
+ asetup: {},
+ dsetup: {},
+ rsetup: {},
+ optimization: {};% optimized by the driver (--optimize-tables, --optimize-actions)
+
+\let\flexpseudonamespace\flexnamespace
+\let\flexpseudorenamespace\flexrenamespace
+
% parser for term names: this is not really a great idea in itself but rather an
% illustration of what is possible
@@ -50,84 +101,299 @@
tokens: {},
asetup: {},
dsetup: {},
- rsetup: \noexpand\savefullstateextra,
+ rsetup: \let\returnexplicitspace\ignoreexplicitspace, % ignore spaces in names
optimization: \optimizeall;%
\tomainparser
-\input yytexlex.sty
+% stage two macros: parsing
-\let\unparse\yyid
+% \flex parser stack
-\expandafter\def\csname parserstack[b]\endcsname#1#2{%
- \parsevb{#1}% Stage two, start the parsing
- \ifyyparsefail % revert to generic macros if parsing failed
- \yybreak{\message{parsing failed ...}#2}%
- \else % Stage three, process the parsed table
- \yybreak{\typesetalltables}%
- \yycontinue
+% section 1 parser
+
+\def\flexoneparserinit{%
+ \yylessusedtrue
+ \floption@sensetrue
}
-\expandafter\def\csname parserstack[]\endcsname#1#2{%
- \parsevb{#1}% Stage two, start the parsing
- \ifyyparsefail % revert to generic macros if parsing failed
- \yybreak{\message{parsing failed ...}#2}%
- \else % Stage three, process the parsed table
- \yybreak{\typesetalltables}%
- \yycontinue
+\def\flexoneparserdatainit{%
+ \table{}%
}
-% stage two macros: parsing
+% regular expression parser
-\newtoks\symstream
+\def\flexreparserinit{%
+ \yyBEGIN{SECT2}%
+ \flin@ruletrue
+ \yylessusedtrue
+}
-\def\parsevb#1{%
- \ifchecktable
- \ifsaveparseoutput
- {\toks0{#1}\newlinechar=`^^J\immediate\write\exampletable{^^J\harmlesscomment
- table before parsing:^^J\the\toks0}}%
- \else
- {\toks0{#1}\errmessage{table before parsing: \the\toks0}}%
- \fi
- \fi
+\def\flexreparserdatainit{%
+ \table{}%
+}
+
+% section 2 parser
+
+\def\flexparserinit{%
+ \yyBEGIN{SECT2}%
+ \def\flbracelevel{0}%
+ \yylessusedtrue
+}
+
+\def\flexparserdatainit{%
+ \table{}%
+}
+
+% output parsed tables
+
+\long\def\displayoutputcode#1#2#3{% #1 is the output code (will be expanded by \write)
+ % #2 is the output stream
+ % #3 is the preamble (will be expanded by \write)
+ \immediate\write#2{#3#1}%
+}
+
+\def\displayflextable#1{{%
+ \hidecslist\cwebstreamchars
+ \restorecslist{flexparser-debug}\yyflunion
+ \newlinechar=`^^J%
+ \expandafter\displayoutputcode\expandafter{\the\table}\exampletable
+ {^^J\harmlesscomment \parsernamespace::parsed table #1:^^J}%
+}}
+
+\def\displaybisontable#1{{%
+ \hidecslist\cwebstreamchars
+ \restorecslist{parser-debug}\yyunion
+ \newlinechar=`^^J%
+ \expandafter\displayoutputcode\expandafter{\the\table}\exampletable
+ {^^J\harmlesscomment \parsernamespace::parsed table #1:^^J}%
+}}
+
+% stage two parsing macros
+
+\def\preparsebisongrammar{%
+ \let\postparse\postparsebisongrammar
\tomainparser
- \doparse{#1}%
+ \displayrawtable % do this after the parse namespaces are setup
+ \basicparserinit
+ \bisonparserinit
+ \bisonparserdatainit
+ \yyparse
+}
+
+\def\preparsebisonprologue{%
+ \let\postparse\postparsebisonprologue
+ \toprologueparser
+ \displayrawtable % do this after the namespaces are setup
+ \basicparserinit
+ \bisonparserinit
+ \bisonparserdatainit
+ \yyparse
+}
+
+\def\preparseflexone{%
+ \let\postparse\postparseflexone
+ \toflexoneparser
+ \displayrawtable % do this after the namespaces are setup
+ \basicparserinit
+ \flexoneparserinit
+ \flexoneparserdatainit
+ \yyparse
+}
+
+\def\preparseflextwo{%
+ \let\postparse\postparseflextwo
+ \toflextwoparser
+ \displayrawtable % do this after the namespaces are setup
+ \basicparserinit
+ \flexparserinit
+ \flexparserdatainit
+ \yyparse
+}
+
+\def\preparsefallback#1{%
+ \let\postparse\relax
+ \message{#1}%
+}
+
+% stage three, postprocessing and typesetting
+
+\newif\ifparseverbose
+
+\def\postparsegeneric#1{%
\ifyyparsefail
- \toprologueparser
- \doparse{#1}%
- \ifyyparsefail
- \else
- \ifsaveparseoutput{\newlinechar=`^^J\immediate\write\exampletable{^^J\harmlesscomment parsed table (prologue):
- ^^J\the\table}}%
- \fi
- \fi
+ \yybreak{%
+ \ifparseverbose\ferrmessage{#1 parsing failed.}\fi
+ \parserreset
+ }%
\else
- \ifsaveparseoutput{\newlinechar=`^^J\immediate\write\exampletable{^^J\harmlesscomment parsed table (grammar):
- ^^J\the\table}}%
- \fi
+ \yybreak{%
+ \ifparseverbose\ferrmessage{#1 parsing successful.}\fi
+ \ifsaveparseoutput\displayparsedtable{#1}\fi
+ \typesetparsedtables
+ }%
+ \yycontinue
+}
+
+\def\parserreset#1\par{%
+ \yyparsefailfalse % in case the next pass is a \relax
+ \let\postparse\empty % ...
+ \expandafter\skiptolsection\the\Binputtoks\par% start the next parsing pass, skip \6\hbox{} trash
+}
+
+\def\postparsebisongrammar{%
+ \let\displayparsedtable\displaybisontable
+ \let\typesetparsedtables\typesetalltables
+ \postparsegeneric{(grammar)}%
+}
+
+\def\postparsebisonprologue{%
+ \let\displayparsedtable\displaybisontable
+ \let\typesetparsedtables\typesetalltables
+ \postparsegeneric{(prologue)}%
+}
+
+\def\postparseflexone{%
+ \let\displayparsedtable\displayflextable
+ \let\typesetparsedtables\typesetfsonetables
+ \postparsegeneric{(section 1)}%
+}
+
+\def\postparseflextwo{%
+ \let\displayparsedtable\displayflextable
+ \let\typesetparsedtables\typesetfstwotables
+ \postparsegeneric{(section 2)}%
+}
+
+\def\displayrawtable{%
+ \ifsaveparseoutput
+ {\newlinechar=`^^J\immediate\write\exampletable{^^J\harmlesscomment
+ table before parsing:^^J\the\Binputtoks}}%
+ \fi
+ \ifchecktable
+ \ferrmessage{table before parsing: \the\Binputtoks}%
\fi
}
-% stage three macros: typesetting
+\fillpstack{}{%
+ \preparsebisongrammar
+ \preparsebisonprologue
+ {\preparsefallback{**}}%
+ \relax % this \relax is necessary so that the braces above
+ % are not stripped by \poppstack
+}
+
+\fillpstack{b}{%
+ \preparsebisongrammar
+ \preparsebisonprologue
+ {\preparsefallback{**}}%
+ \relax % this \relax is necessary so that the braces above
+ % are not stripped by \poppstack
+}
+
+\fillpstack{fs1}{%
+ \preparseflexone
+ \preparseflextwo
+ {\preparsefallback{==}}%
+ \relax % this \relax is necessary so that the braces above
+ % are not stripped by \poppstack
+}
+
+\fillpstack{fs2}{%
+ \preparseflextwo
+ {\preparsefallback{--}}%
+ \relax % this \relax is necessary so that the braces above
+ % are not stripped by \poppstack
+}
+
+\fillpstack{t}{%
+ \relax
+}
+
+% stage 3.5 macros: typesetting
+
+\newtoks\symstream
\def\tlskip{\z@}
\def\tfskip{\parindent}
+\newif\ifchecktrailingstash
+
\def\typesetalltables{%
\begingroup
+ \ifsaveparseoutput
+ {\newlinechar=`^^J\immediate\write\exampletable{^^J\harmlesscomment
+ stashed stream:^^J\the\yystash^^J^^J\harmlesscomment
+ format stream: ^^J\the\yyformat}}%
+ \fi
+ \ifchecktable
+ \ferrmessage{parsed table: \the\table^^J^^J%
+ stashed stream: \the\yystash^^J^^J%
+ format stream: \the\yyformat}%
+ \fi
+ \extractprodtableinfo
+ \symstream\table
+ \table{}%
+ \setprodtable
+ \the\symstream\relax
+ \postoks{}\pushothertables
+ \ifchecktable
+ \ferrmessage{table after processing: \the\table}%
+ \fi
+ \ifsaveparseoutput
+ {\newlinechar=`^^J\immediate\write\exampletable{^^J\harmlesscomment
+ processed table:^^J\the\table}}%
+ \fi
+ \parindent1em
+ \checkforpropertable\table
+ \tabskip\tfskip
+ \ruletableset
+ \ifchecktrailingstash
+ \ferrmessage{remaining stash: \the\yystash}%
+ \fi
+ \unwrapstash\yystash
+ \toksa\expandafter{\the\yystash}%
+ \cleanstash\stripstash\checkforccode
+ \ifchecktrailingstash
+ \ferrmessage{stash after cleaning: \the\toksa}%
+ \fi
+ \ifnum\wd0>\z@
+ %\ifchecktable
+ % \showboxdepth=1000
+ % \showboxbreadth=1000
+ % \showbox0
+ %\fi
+ % currently testing for nontrivial leftover stash involves packaging the stash material
+ % into a \vbox; as a result, the stash containing ${}{}$\hbox{} will have a nonzero length
+ % which is why the test below is necessary
+ \ifnum\ht0>\z@
+ \indent\boxstash
+ \fi
+ \fi
+ \expandafter % export the value of the alignment
+ \endgroup
+ \expandafter\gaglue\the\gaglue\relax
+}
+
+\def\typesetfstwotables{%
+ \begingroup
\ifchecktable
\ifsaveparseoutput
{\newlinechar=`^^J\immediate\write\exampletable{^^J\harmlesscomment
- stashed stream:^^J\the\yystash}}%
+ stashed stream:^^J\the\yystash^^J^^J\harmlesscomment
+ format stream: ^^J\the\yyformat}}%
\else
- \errmessage{parsed table: \the\table^^J^^Jstashed stream: \the\yystash}%
+ \errmessage{parsed table: \the\table^^J^^J%
+ stashed stream: \the\yystash^^J^^J%
+ format stream: \the\yyformat}%
\fi
\fi
+ \extractregextableinfo
\symstream\table
\table{}%
- \setprodtable
+ \setregextable
\the\symstream\relax
- \postoks{}\pushothertables
+ \regextableset
\ifchecktable
\ifsaveparseoutput
\else
@@ -138,17 +404,76 @@
{\newlinechar=`^^J\immediate\write\exampletable{^^J\harmlesscomment
processed table:^^J\the\table}}%
\fi
- \parindent1em
- \checkforpropertable\table
- \tabskip\tfskip
- \ruletableset
\ifchecktable
- \message{remaining stash: \the\yystash}%
+ \ifchecktrim
+ \ferrmessage{remaining stash: \the\yystash}%
+ \fi
+ \fi
+ \unwrapstash\yystash
+ \toksa\expandafter{\the\yystash}%
+ \cleanstash\stripstash\checkforccode
+ \ifchecktable
+ \ifchecktrim
+ \ferrmessage{stash after cleaning: \the\toksa}%
+ \fi
+ \fi
+ \ifnum\wd0>\z@
+ %\ifchecktable
+ % \showboxdepth=1000
+ % \showboxbreadth=1000
+ % \showbox0
+ %\fi
+ % currently testing for nontrivial leftover stash involves packaging the stash material
+ % into a \vbox; as a result, the stash containing ${}{}$\hbox{} will have a nonzero length
+ % which is why the test below is necessary
+ \ifnum\ht0>\z@
+ \indent\boxstash
+ \fi
+ \fi
+ \endgroup
+}
+
+\def\typesetfsonetables{%
+ \begingroup
+ \ifchecktable
+ \ifsaveparseoutput
+ {\newlinechar=`^^J\immediate\write\exampletable{^^J\harmlesscomment
+ stashed stream:^^J\the\yystash^^J^^J\harmlesscomment
+ format stream: ^^J\the\yyformat}}%
+ \else
+ \errmessage{parsed table: \the\table^^J^^J%
+ stashed stream: \the\yystash^^J^^J%
+ format stream: \the\yyformat}%
+ \fi
+ \fi
+% \extractregextableinfo
+ \symstream\table
+ \table{}%
+ \setregexdeftable
+ \the\symstream\relax
+ \regexdeftableset
+ \ifchecktable
+ \ifsaveparseoutput
+ \else
+ \errmessage{table after processing: \the\table}%
+ \fi
+ \fi
+ \ifsaveparseoutput
+ {\newlinechar=`^^J\immediate\write\exampletable{^^J\harmlesscomment
+ processed table:^^J\the\table}}%
+ \fi
+ \ifchecktable
+ \ifchecktrim
+ \ferrmessage{remaining stash: \the\yystash}%
+ \fi
\fi
- \toksa{}\the\yystash
+ \unwrapstash\yystash
+ \toksa\expandafter{\the\yystash}%
\cleanstash\stripstash\checkforccode
\ifchecktable
- \message{stash after cleaning: \the\toksa}%
+ \ifchecktrim
+ \ferrmessage{stash after cleaning: \the\toksa}%
+ \fi
\fi
\ifnum\wd0>\z@
%\ifchecktable
@@ -166,10 +491,16 @@
\endgroup
}
+\let\extractprodtableinfo\empty % we do not preprocess the productions table
+
+\let\extractregextableinfo\empty % we do not preprocess the regex table
+
% setting the rule table: cross-section alignment and other effects are applied here;
% in order to produce the proper line skips before and after \unvbox, the rules followed by
% \TeX\ while adding an \halign to a vertical list have to be reproduced explicitly
+\newdimen\gaglue % the width of the action box of the last alignment
+
\def\ruletableset{%
\par
\vskip-\baselineskip
@@ -186,12 +517,48 @@
}
\expandafter
}\expandafter
- \unvbox\expandafter0\expandafter
+ \unvcopy\expandafter0\expandafter
\prevdepth\the\prevdepth\relax
+ \setbox\z@=\vbox{\unvbox\z@ \setbox\z@=\lastbox % set the alignment dimension
+ \hbox{\unhbox\z@ \unskip\setbox\z@=\lastbox\expandafter}\expandafter}\expandafter\gaglue\the\wd\z@
}
\def\setallterms#1{\setbox\z@=\hbox{\it#1}\ifsquashterms\hbox to0pt{\unhbox\z@\hss}\else\unhbox\z@\fi\hfil}
+% typesetting the scanner automaton rules
+
+\def\regextableset{%
+ \par
+ \vskip-\baselineskip
+ \setbox0 \vbox\expandafter{\expandafter
+ \null\expandafter\prevdepth\the\prevdepth
+ \halign to\hsize
+ {##\hfil\tabskip0 pt plus1fil\ &\relax\tabskip\tlskip\toksa{}##\makestashbox\hfil\cr
+ \the\table
+ }%
+ \expandafter
+ }\expandafter
+ \unvbox\expandafter0\expandafter
+ \prevdepth\the\prevdepth\relax
+}
+
+% typesetting named regular expression definitions
+
+\def\regexdeftableset{%
+ \par
+ \vskip-\baselineskip
+ \setbox0\vbox\expandafter{\expandafter
+ \null\expandafter\prevdepth\the\prevdepth
+ \halign to\hsize
+ {\hskip\parindent##\hfil\tabskip0 pt plus1fil\ &\relax\tabskip\tlskip\tt##\hfil\cr
+ \the\table
+ }%
+ \expandafter
+ }\expandafter
+ \unvbox\expandafter0\expandafter
+ \prevdepth\the\prevdepth\relax
+}
+
% quick and dirty global alignment: the size of the last box (and those in between)
% can be chosen automatically after one pass and read in for the final pass;
% in the future this will be the default implementation; for now, the inelegant
@@ -264,7 +631,8 @@
\tokdectoks\toksa
\edef\next{\table{\the\table\noalign{%
\tabskip\parindent
- \nx\displaytokenrawtrue
+ %\nx\displaytokenrawtrue % this controls how tokens are displayed
+ % in the declarations: if true, the macro names will be shown
\halign to\hsize{\the\tokdectoks}%
}%
}}\next
@@ -384,10 +752,12 @@
% macros for processing \Cee\ mode material
+\newif\ifchecktrim
+
%\long\def\buildstash#1{\toksa\expandafter{\the\toksa#1}} % = stashed
\def\cleanstash{%
- \ifchecktrim\errmessage{collected stash: \the\toksa}\fi
+ \ifchecktrim\ferrmessage{collected stash: \the\toksa}\fi
\expandafter\cleanst@sh\the\toksa\packagebox}
\def\cleanst@sh{\let\6\testsbox\setbox0=\vbox\bgroup}
@@ -417,7 +787,7 @@
\def\packagebox{\egroup\ifnum\wd0>\z@\else\toksa{}\fi}
\def\stripstash{%
- \ifchecktrim\errmessage{before trimming: \the\toksa}\fi
+ \ifchecktrim\ferrmessage{before trimming: \the\toksa}\fi
\def\6{}\expandafter\stripst@sh\expandafter\ignorespaces\the\toksa\6\str@pst@sh}
\def\stripst@sh{\toksa{}\stripst@shi}
@@ -451,7 +821,7 @@
\newif\iftrailingreturn
\def\striptrim{%
- \ifchecktable\errmessage{trimming: \the\toksb}\fi
+ \ifchecktrim\ferrmessage{trimming: \the\toksb}\fi
\edef\next{\the\toksb}%
\expandafter\striptr@m\the\toksb\relax\end
}
@@ -463,10 +833,10 @@
#3% \relax
#4% ?
\end{%
-% \def\next{#4}%
-% \ifx\next\empty
% \toksc{#3#4}\showthe\toksc
- \setbox\z@\vbox{#3#4}%
+%
+ \setbox\z@\vbox{
+ #3#4}%
\ifnum\wd\z@=\z@
\expandafter\trimreturn\the\toksa\end
\toksb{}%
@@ -485,8 +855,8 @@
}
\def\boxstash{%
- \ifchecktrim\errmessage{stash contents: \the\toksa}\fi
- $\vtop{\activateinlinec\tabskip\z@\halign{\strut\ignorespaces##\hfil\cr\the\toksa\crcr}}$}
+ \ifchecktrim\ferrmessage{stash contents: \the\toksa}\fi
+ $\vtop{\activateinlinec\tabskip\z@\halign{\strut\ignorespaces##\hfil\cr\relax\the\toksa\crcr}}$}
\def\makestashbox{\cleanstash\stripstash\boxstash}
@@ -533,12 +903,16 @@
\ifcat\noexpand\next0%
\let\next\pr@dterm
\else
- \let\next\oldmathS
+ \if\noexpand\next[%
+ \let\next\pr@dterm
+ \else
+ \let\next\oldmathS
+ \fi
\fi
\fi
\next
}
-
+
\def\pr@dterm#1{%
\ifx#1\$%
\def\next{\hbox{$\Upsilon$}}%
@@ -550,44 +924,60 @@
\ifnum`#1>`0\relax
\def\next{\seekno#1}%
\else
- \def\next{\hbox{$\Upsilon$}#1}%
+ \def\next{\hbox{$\Upsilon$}#1}% TODO: look for an identifier
\fi
\else
- \def\next{\hbox{$\Upsilon$}#1}%
+ \def\next{\hbox{$\Upsilon$}#1}% TODO: look for an identifier
\fi
\fi
\fi
\next
}%
-\let\oldmathS\$
\let\$\prodterm
+\defreserved\${\prodterm}
\def\seekno{\afterassignment\printterm\tempca}%
\def\seeksym#1]{%
- \hbox{$\Upsilon\kern-1pt{}_{\rm#1}$}}
+ \hbox{$\Upsilon\kern-1pt{}_{\def\\##1{\hbox{\sscmd\prodstyle{##1}}}\rm#1}$}}
+
+\def\seeksym#1]{% a better version of the above
+ \hbox{$\ulcorner\def\\##1{##1}\let\.\\\let\|\\\let\ous\_\let\_\relax
+ \edef\next{#1}\let\_\ous
+ \hbox{\expandafter\prodstyle\expandafter{\next}}\urcorner$}}
\def\printterm{\hbox{$\Upsilon\kern-1pt{}_{\number\tempca}$}}%
+% typesetting examples of \bison\ productions and \flex\ input in text
+
\long\def\setproduction#1{%
\def\termidxrank{5}%
\def\headeridxrank{4}%
\def\defidxrank{3}%
\def\texcsidxrank{5}%
+ \textproductionsetup
+ \hbox{\strut}%
+ \Binputtoks{\lsectionbegin{b}#1\yyeof\yyeof\endparseinput\endparse\postparse}%
+ \the\Binputtoks\par% Stage two, start the parsing
+}
+
+\def\textproductionsetup{%
\ninepoint
\let\returnexplicitspace\splitexplicitspace
\let\acharswitch\texcharadjust
\let\onecharswitch\texcsadjust
+ \let\extractprodtableinfo\empty % we do not preprocess the table
\showlastactionfalse
\let\actionfiller\empty
- \parsevb{#1} % Stage two, start the parsing
- \ifyyparsefail
- {\toks0{#1}\errmessage{failed to parse: \the\toks0}}%
- \else % Stage three, process the parsed table
- \par\hbox{\strut}%
- \typesetalltables
- \fi
+ \let\postparsetext\postparsebproduction
+ \fillpstack{b}{%
+ \preparsebisongrammar
+ \preparsebisonprologue
+ {\preparsefallback{**}}%
+ \relax % this \relax is necessary so that the braces above
+ % are not stripped by \poppstack
+ }%
}
\def\splitexplicitspace{%
@@ -605,7 +995,7 @@
\yybyte{\_}%
\expandafter\yycp@\expandafter`\the\yybyte\relax
\mkpurebyte
- \yyreturn
+ \yyreturn
}
}
@@ -636,8 +1026,9 @@
\long\def\b@ginprod#1\endprod{%
\setproduction{#1}%
+ \expandafter
\endgroup
- \par
+ \expandafter\gaglue\the\gaglue\relax % export the alignment width
}
\def\beginmprod{%
@@ -657,8 +1048,55 @@
\def\begincprod#1\endcprod{{\def\tlskip{0 pt plus1fill}\let\tfskip\tlskip\beginprod#1\endprod}}
-% the next macro assumes that \gindex being defined implies that all the bookkeeping required
-% for maintaining the index of grammar terms has been taken care of
+% flex examples typesetting
+
+\long\def\setflex#1{%
+ \def\fstatedefidxrank{3}%
+ \def\fstateidxrank{4}%
+ \def\fregexidxrank{5}%
+ \textflexsetup
+ \hbox{\strut}%
+ \Binputtoks{\lsectionbegin{fs1}#1\yyeof\yyeof\endparseinput\endparse\postparse}%
+ \the\Binputtoks\par% Stage two, start the parsing, the \par is expected by the \parserreset
+}
+
+\def\textflexsetup{%
+ \ninepoint
+ %\let\returnexplicitspace\splitexplicitspace
+ \let\acharswitch\texcharadjust
+ %\let\onecharswitch\texcsadjust
+ \let\extractprodtableinfo\empty % we do not preprocess the table
+ \let\postparsetext\postparsefsection
+ \fillpstack{fs1}{%
+ \preparseflexone % TODO
+ \preparseflextwo
+ {\preparsefallback{**}}%
+ \relax % this \relax is necessary so that the braces above
+ % are not stripped by \poppstack
+ }%
+}
+
+\def\beginflex{%
+ \par
+ \begingroup
+ \catcode`\^^M=12 %
+ \catcode`\#=12 %
+ \b@ginflex%
+}
+
+\long\def\b@ginflex#1\endflex{%
+ \setflex{#1}%
+ \expandafter
+ \endgroup
+ \expandafter\gaglue\the\gaglue\relax % export the alignment width, TODO: set \gaglue in \flex
+}
+
+
+
+% the following macros assume that \gindex or \xrefstream having been defined implies
+% that all the bookkeeping required for maintaining the custom index and local cross referencing
+% has been taken care of; this way during the bootstrapping mode, index entries or cross references
+% are not generated.
\ifx\gindex\UNDEFINED
\else
@@ -666,6 +1104,10 @@
\immediate\openout\gindex=\jobname.gdx
\fi
+\let\endcprod\endgroup
+\let\endmprod\endgroup
+\let\endprod\endgroup
+
% stringing all the manuals together (disabled for now)
%\newwrite\lastpageinfo
diff --git a/support/splint/tex/yyinput.sty b/support/splint/tex/yyinput.sty
index d424d299d8..0898410c51 100644
--- a/support/splint/tex/yyinput.sty
+++ b/support/splint/tex/yyinput.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2015, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -14,7 +14,13 @@
% You should have received a copy of the GNU General Public License
% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
-\def\mkpurebyte{\uccode`\@=\yycp@\uppercase{\yybytepure{@}}\uccode`\@=`\@}
+%\def\mkpurebyte{\uccode`\@=\yycp@\uppercase{\yybytepure{@}}\uccode`\@=`\@}
+
+% make all symbol characters category 12; most macros are indifferent to this
+% however, if delimited macros are used to process the mathched text, the option
+% makes it easier to write such macros;
+
+\def\mkpurebyte{\uccode`\.=\yycp@\uppercase{\yybytepure{.}}\uccode`\.=`\.}
\def\yyinput{\futurelet\next\yyinp@t} % get the code of the next character ...
@@ -57,7 +63,13 @@
\yycontinue
}
+% some \Cee\ escape characters; the rest are either silly (like \a and \b) or
+% are already defined to have other important functions in \TeX\ (such as \v and \t)
+
\chardef\n=`\^^J
+\chardef\r=`\^^M
+\chardef\f=`\^^L
+\chardef\HT=`\^^I % ASCII horizontal tab
\chardef\charseq1
\chardef\charac2
\chardef\chargroup3
@@ -78,7 +90,7 @@
% automatically
\yybyte{#1}%
\ifyyinputdebug
- \immediate\write16{read: \the\yybyte}%
+ \immediate\write16{read: \the\yybyte\space after: \the\yytext@seen}%
\fi
\ifx#1\ % a space token
\yybreak\returnexplicitspace
@@ -135,12 +147,24 @@
}%
\def\multicharswitch{
+ \raw\vb\raw {%
+ \vbunwrap
+ }
+ \raw\insertraw\raw {%
+ \insertrawnext
+ }
\raw\stashed\raw {%
\stashnext
}
\raw\format \formatlocal\raw {%
\formatnext
}
+ \raw\formatbegin\raw {%
+ \fmtbegin
+ }
+ \raw\formatp\raw {%
+ \fmtparam
+ }
\raw\sflush\raw {%
\sflushnext
}
@@ -158,6 +182,9 @@
\raw\fold \breakline\raw {%
\expandafter\yyinput\expandafter\formatlocal\expandafter{\the\yybyte}%
}
+ \raw\breakahead\raw {%
+ \expandafter\yyinput\expandafter\formatp\the\yybyte
+ }
\raw\break\raw {% for testing purposes
\yycp@=`\ %
\yybytepure={ }%
@@ -195,22 +222,64 @@
\setspecialcharsfrom\multicharswitch
\setspecialcharsfrom\acharswitch
+\def\insertrawnext#1{% insert a command
+ #1\yyinput
+}
+
+\def\vbunwrap#1#2\vb{%
+ \yyinput#1\stashed{#2}\vb
+}
+
\chardef\stashchar=`\ %
\chardef\formatchar=`\ %
\newcount\stashmarker
\newcount\formatmarker
-\def\stashnext#1{%
+\def\stashnextwithspace#1{%
\yybytepure{ }\yycp@\stashchar
- \toksa{#1}%
+ \yybyte\expandafter{\the\yybyte{#1}}%
\advance\stashmarker\@ne
- \edef\next{\yysbyte{\noexpand\strm[\the\stashmarker]{\the\yybyte{\the\toksa}}.[\the\stashmarker]}}\next
+ \edef\next{\yysbyte{\noexpand\strm[\the\stashmarker]{\the\yybyte}.[\the\stashmarker]}}\next
% the extra `.' is to avoid the stripping of braces by the parameter scanning mechanism of TeX
- \yybyte\expandafter{\the\yybyte{#1}}%
\yyreturn
}
+% the mechanism for stash processing making stash invisible
+
+\def\stashnextwithnothing#1{%
+ \advance\stashmarker\@ne
+ \yybyte\expandafter{\the\yybyte{#1}}\concat\yysubtext\yybyte
+ \appendr\yysbyte{\noexpand\strm[\the\stashmarker]{\the\yybyte}.[\the\stashmarker]}%
+ \ifyyinputdebug
+ \immediate\write16{stash byte: \the\yysbyte mid text: \the\yysubtext}%
+ \fi
+ % the extra `.' is to avoid the stripping of braces by the parameter scanning mechanism of TeX
+ \yyinput
+}
+
+% while collecting the stash, the macro below packages the stash contents into a command sequence
+% to add to the \yystash stream; the stash is presented to the lexer unpackaged though; this
+% introduces a minor inefficiency while ensuring that exactly one level of packaging is present
+% (otherwise the lexer may back up and repackage already packaged stash); the inefficiency only
+% persists while the lexer scans the current token (and possibly backs up).
+
+\def\stashnextwithnothingnx#1{%
+ \advance\stashmarker\@ne
+ \yypush{#1}\on\astarray
+ \appendr\yysbyte{\noexpand\strm[\the\stashmarker]{\the\yybyte{%
+ \expandafter\noexpand\romannumeral\gettopofstackcsx\astarray}}.[\the\stashmarker]}%
+ \yybyte\expandafter{\the\yybyte{#1}}% do not package the input
+ \concat\yysubtext\yybyte
+ \ifyyinputdebug
+ \immediate\write16{stash byte: \the\yysbyte mid text: \the\yysubtext}%
+ \fi
+ % the extra `.' is to avoid the stripping of braces by the parameter scanning mechanism of TeX
+ \yyinput
+}
+
+\let\stashnext\stashnextwithnothingnx
+
\def\formatnext#1{%
\yybytepure{ }\yycp@\formatchar
\toksa{#1}%
@@ -221,6 +290,9 @@
\yyreturn
}
+\def\fmtbegin#1\fmtend{\formatnext{#1}} % multiparameter format sequences
+\def\fmtparam#1#2{\formatnext{#1{#2}}} % single parameter format sequences
+
\chardef\boundarychar=`\ %
% the following is a minimal setup of a parsing boundary
@@ -237,22 +309,45 @@
\edef\next{\toksc{\the\yystash\the\yystashseen}}\next
\yyfifolastidx\toksc\in\toksc
\toksa{#1}\toksb{#2}%
- \edef\next{\yysbyte{\noexpand\strm[\the\toksa]{\the\yybyte{\the\toksb}{\the\toksc}}.[\the\toksa]}}\next
+ \appendr\yysbyte{\noexpand\strm[\the\toksa]{\the\yybyte{{\nx\it flushing}: ``\the\toksb'',
+ {\nx\it last index}: $[\the\toksc]$. }}.[\the\toksa]}%
% the extra `.' is to avoid the stripping of braces by the parameter scanning mechanism of TeX
\yybyte\expandafter{\the\yybyte{#1}{#2}}%
+ \concat\yysubtext\yybyte
+ \ifyyinputdebug
+ \immediate\write16{stash byte: \the\yysbyte mid text: \the\yysubtext}%
+ \fi
\yyreturn
}
+% the following implementation is marginally cleaner as it does not redefine \yyr@@dfifo
+% it also makes it almost transparent that \yyreadfifo does not modify any token registers
+% except for the two of its parameters
+% TODO: replace \yyr@@dfifo with \yyr@adfifo
+
\def\yyreadfifo#1\to#2\in#3{%
+%{% to reduce the side effects to the redefinition of the input and output
+ % token registers
\def\yyr@adfifo##1\strm[#2]##2[#2]##3\end{%
- \def\yyr@@dfifo{##3}%
- \ifx\yyr@@dfifo\empty
- #3{}% there is no such marker in the fifo
- \else
+ \yystringempty{##3}{#3{}}% there is no such marker in the fifo
+ {%
#3{##1\strm[#2]##2[#2]}%
\def\yyr@@dfifo####1\strm[#2]####2[#2]\end{#1{####1}}% strip off the inserted string
\yyr@@dfifo##3\end
- \fi
+% TODO: \def\yyr@dfifo####1\strm[#2].[#2]\end{#1{####1}}% strip off the inserted string
+% \yyr@dfifo##3\end
+ }%
+ }%
+ \expandafter\yyr@adfifo\the#1\strm[#2].[#2]\end
+%\edef\next{#1{\the#1}#3{\the#3}}\expandafter}\next
+}
+
+\def\yytrimfifo#1\to#2\in#3{% just save the initial segment of #1 in #3
+ \def\yyr@adfifo##1\strm[#2]##2[#2]##3\end{%
+ \yystringempty{##3}{#3{}}% there is no such marker in the fifo
+ {%
+ #3{##1\strm[#2]##2[#2]}%
+ }%
}%
\expandafter\yyr@adfifo\the#1\strm[#2].[#2]\end
}
diff --git a/support/splint/tex/yymisc.sty b/support/splint/tex/yymisc.sty
index fcc38da96d..b961135b02 100644
--- a/support/splint/tex/yymisc.sty
+++ b/support/splint/tex/yymisc.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2014, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -14,7 +14,7 @@
% You should have received a copy of the GNU General Public License
% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
-% `data structure access' macros': picking the n-th undelimited parameter
+% `data structure access' macros: picking the n-th undelimited parameter
% in a parameter list inside a token register
% it is assumed that none of the arguments is \end, and that there are enough
% parameters to pick the desired one
@@ -88,6 +88,28 @@
\def\g@ttenth#1#2#3#4#5#6#7#8#9\end{\g@tsecond#9\end}
+% removing the first element of a token register if it has more than one;
+
+\def\sansfirst#1{%
+ \expandafter\s@nsfirst\expandafter{\the#1}{#1}%
+}
+
+\def\s@nsfirst#1#2{%
+ \expandafter\s@nsf@rst\expandafter{\eatone#1}{#2}%
+}
+
+\def\s@nsf@rst#1#2{%
+ \yystringempty{#1}{}{%
+ #2{#1}%
+ }%
+}
+
+% a version of the macro above that expands to the original argument with the first element removed
+
+\def\sansfirstx#1{%
+ \expandafter\yystringempty\expandafter{\eatone#1}{#1}{\eatone#1}%
+}
+
% string replacement: all arguments are registers, nothing is expanded, no \next is defined
% note that this is not a greedy replacement: this could be arranged with a more sophisticated macro
% also note that the string being replaced cannot have any braces in it
@@ -270,6 +292,18 @@
% in the interest of efficiency; the old version (that used a control sequence
% as a `stop marker') was more prone to this bug.
+% the next sequence is not merely a convenient abbreviation; it is useful if one
+% wants to look at an `alternative' value stored for the sequence without restoring
+% it to the curent namespace; it also sets up the naming convention for namespaces
+
+\def\restorecsname#1#2{% get the name of the sequence in storage
+ % note that #2 can be a string beginning with an arbitrary
+ % character as a placeholder for the escape character
+ '#1'[\expandafter\eatone\string#2]%
+}
+
+% save macros listed in #2 in namespace #1
+
\def\savecs#1#2{\s@vecs{#1}#2.}
\def\s@vecs#1#2{%
@@ -277,12 +311,22 @@
\yybreak{}%
\else
\yybreak{%
- \expandafter\let\csname '#1'[\expandafter\eatone\string#2]\endcsname#2%
+ \expandafter\let\csname\restorecsname{#1}{#2}\endcsname#2%
\s@vecs{#1}%
}%
\yycontinue
}
+% similar to the macro above but the list is a control sequence
+
+\def\savecslist#1#2{%
+ \expandafter\s@vecslist\expandafter{#2}{#1}%
+}
+
+\def\s@vecslist#1#2{%
+ \savecs{#2}{#1}%
+}
+
\def\restorecs#1#2{\r@storecs{#1}#2.}
\def\r@storecs#1#2{%
@@ -290,12 +334,20 @@
\yybreak{}%
\else
\yybreak{%
- \expandafter\let\expandafter#2\csname '#1'[\expandafter\eatone\string#2]\endcsname
+ \expandafter\let\expandafter#2\csname\restorecsname{#1}{#2}\endcsname
\r@storecs{#1}%
}%
\yycontinue
}
+\def\restorecslist#1#2{%
+ \expandafter\r@storecslist\expandafter{#2}{#1}%
+}
+
+\def\r@storecslist#1#2{%
+ \restorecs{#2}{#1}%
+}
+
\def\hidecs#1{\h@decs#1.}
\def\h@decs#1{%
@@ -309,51 +361,53 @@
\yycontinue
}
-\def\savehcs#1#2{\savecs{#1}{#2}\hidecs{#2}}
-
-\def\savecslist#1#2{%
- \expandafter\s@vecslist\expandafter{#2}{#1}%
-}
+\def\hidecslist#1{\expandafter\hidecs\expandafter{#1}}
-\def\s@vecslist#1#2{%
- \savecs{#2}{#1}%
-}
+\def\savehcs#1#2{\savecs{#1}{#2}\hidecs{#2}}
-\def\restorecslist#1#2{%
- \expandafter\r@storecslist\expandafter{#2}{#1}%
+\def\savehcslist#1#2{%
+ \expandafter\s@vehcslist\expandafter{#2}{#1}%
}
-\def\r@storecslist#1#2{%
- \restorecs{#2}{#1}%
+\def\s@vehcslist#1#2{%
+ \savehcs{#2}{#1}%
}
% a twist on the macros above: save control sequences with a postfix
-\def\savecsx#1#2{\s@vecsx{#1}#2.}
+\def\savecsx#1#2{\s@vecsx{#1}#2.} % there is no \savecsxlist macro
-\def\s@vecsx#1#2{%
+\def\s@vecsx#1#2{% #1 is the namespace, #2 is a control sequence without the postfix or prefix
\ifx#2.%
\yybreak{}%
\else
\yybreak{%
- \expandafter\s@vecsxlet\expandafter#2\csname\expandafter\defprefix\expandafter\eatone\string#2\defpostfix\endcsname{#1}%
+ \expandafter\s@vecsxlet\csname\expandafter\defprefix\expandafter\eatone\string#2\defpostfix\endcsname#2{#1}%
\s@vecsx{#1}%
}%
\yycontinue
}
-\def\s@vecsxlet#1#2{%
- \expandafter\let\csname '#2'[\expandafter\defprefix\expandafter\eatone\string#1\defpostfix]\endcsname
+\def\s@vecsxlet#1#2#3{% #1 is the control sequence augmented by prefix and postfix,
+ % #2 is the control sequence without prefix or postfix
+ % #3 is the namespace
+ \expandafter\let\expandafter#1\csname\restorecsxname{#3}{#2}\endcsname
}
\def\restorecsx#1#2{\r@storecsx{#1}#2.}
+% see remarks about \restorecsname above
+
+\def\restorecsxname#1#2{%
+ '#1'[\expandafter\defprefix\expandafter\eatone\string#2\defpostfix]%
+}
+
\def\r@storecsx#1#2{%
\ifx#2.%
\yybreak{}%
\else
\yybreak{%
- \expandafter\r@storecsxlet\expandafter#2\csname '#1'[\expandafter\defprefix\expandafter\eatone\string#2\defpostfix]\endcsname
+ \expandafter\r@storecsxlet\expandafter#2\csname\restorecsxname{#1}{#2}\endcsname
\r@storecsx{#1}%
}%
\yycontinue
@@ -401,7 +455,7 @@
% in the appropriate namespace, this macro adds a
% preamble, a postamble and a `this' type macro; this
% will mostly be used with indexing \TeX\ control sequences
- \tokse{\def\thisname{#1}\edef\thisnamex{\expandafter\eatone\string#1}}%
+ \toksf{\def\thisname{#1}\edef\thisnamex{\expandafter\eatone\string#1}}%
\toksa\expandafter{%
\csname\expandafter\defprefix\expandafter\eatone\string#1\defpostfix\endcsname}%
\toksc\expandafter{\expandafter\def\the\toksa#2}%
@@ -410,11 +464,11 @@
}
\def\d@f@{%
- \appendl\toksd{\the\tokse}%
- \tokse\expandafter{\defypreamble}%
- \appendl\toksd{\the\tokse}%
- \tokse\expandafter{\defypostamble}%
- \appendr\toksd{\the\tokse}
+ \tokse{\defypreamble}%
+ \concatl\tokse\toksd
+ \concatl\toksf\toksd
+ \tokse{\defypostamble}%
+ \concat\toksd\tokse
\toksd\expandafter{\expandafter{\the\toksd}}%
\concat\toksc\toksd
\afterassignment\d@fy
@@ -429,12 +483,14 @@
\def\defp#1#2#{% flexible dynamic type checking
\toksa\expandafter\expandafter\expandafter{\yyuniontag#1}%
- \expandafter\edef\yyuniontag{\the\toksa}%
+ \expandafter\edef\yyuniontag{\the\toksa}% add the sequence to the current union
\def#1#2{\errmessage{unexpected type: \string#1 in namespace <\currentyyunionnamespace>}}%
\savecs\parserstrictnamespace#1%
\toksa{#2}%
- \edef#1{\the\toksa}%
+ \edef#1{\the\toksa}% save the prototype
\savecs\parserprototypesnamespace#1%
+ \let#1\relax
+ \savecs\parserdebugnamespace#1% save the debug sequence for outputting the AST
\def#1#2%
}
@@ -478,6 +534,17 @@
{\catcode`\^^M=12 \aftergroup\def\aftergroup\eolletter\aftergroup{\aftergroup^^M\aftergroup}}% end of line, ... not really
{\catcode`\|=0\catcode`\\=12 |aftergroup|def|aftergroup|benignescape|aftergroup{|aftergroup\|aftergroup}}% not an escape
{\catcode`\#=12 \aftergroup\def\aftergroup\hashletter\aftergroup{\aftergroup#\aftergroup}}% not a parameter token
+{\catcode`\~=12 \aftergroup\def\aftergroup\safetilde\aftergroup{\aftergroup~\aftergroup}}% inactive tie
+{\catcode`\$=12 \aftergroup\def\aftergroup\safemath\aftergroup{\aftergroup$\aftergroup}}% not really a start math character
+
+\let\uscore\_ % the canonical underscore for the fonts that do not have the character
+
+% remove the brackets from the namespace string;
+% the parameter is the control sequence that expands to the namespace string
+
+\def\stripbrackets#1{\expandafter\stripbr@ckets#1[]\end}
+
+\def\stripbr@ckets#1[#2]#3\end{\yystringempty{#3}{#1}{#1#2}}
% token name input
@@ -631,10 +698,11 @@
% tables
\def\newtable@full#1{%
- \toksa{\csname newtoks\endcsname}%
- \expandafter\the\expandafter\toksa\csname #1\parsernamespace\endcsname
- \edef\next{\let\csname #1\endcsname\csname #1\parsernamespace\endcsname}\next
- \toksa\expandafter{\next}\concat\pinittoks\toksa
+ \expandafter\expandafter\csname newtoks\endcsname\csname #1\parsernamespace\endcsname
+ \expandafter\expandafter\expandafter\let\expandafter
+ \expandafter\csname #1\endcsname\csname #1\parsernamespace\endcsname
+ \appendr\pinittoks{\let\expandafter\noexpand\csname #1\endcsname
+ \expandafter\noexpand\csname #1\parsernamespace\endcsname}%
\csname #1\parsernamespace\endcsname=%
}
@@ -645,72 +713,61 @@
\def\constset#1#2{%
% a \mathchardef would be nicer but it cannot handle negative numbers
\expandafter\def\csname #1\parsernamespace\endcsname{#2}%
- \toksa\expandafter{\csname #1\endcsname}%
- \toksb\expandafter{\csname #1\parsernamespace\endcsname}%
- \edef\next{\let\the\toksa\the\toksb}\next
- \toksa\expandafter{\next}\concat\pinittoks\toksa
+ \expandafter\expandafter\expandafter\let\expandafter
+ \expandafter\csname #1\endcsname\csname #1\parsernamespace\endcsname
+ \appendr\pinittoks{\let\expandafter\noexpand\csname #1\endcsname
+ \expandafter\noexpand\csname #1\parsernamespace\endcsname}%
}
\def\uconstset#1#2{%
% a \mathchardef for positive constants
\expandafter\mathchardef\csname #1\parsernamespace\endcsname=#2 %
- \toksa\expandafter{\csname #1\endcsname}%
- \toksb\expandafter{\csname #1\parsernamespace\endcsname}%
- \edef\next{\let\the\toksa\the\toksb}\next
- \toksa\expandafter{\next}\concat\pinittoks\toksa
+ \expandafter\expandafter\expandafter\let\expandafter
+ \expandafter\csname #1\endcsname\csname #1\parsernamespace\endcsname
+ \appendr\pinittoks{\let\expandafter\noexpand\csname #1\endcsname
+ \expandafter\noexpand\csname #1\parsernamespace\endcsname}%
}
\def\charset#1#2{%
\expandafter\chardef\csname #1\parsernamespace\endcsname=#2\relax%
- \toksa\expandafter{\csname #1\endcsname}%
- \toksb\expandafter{\csname #1\parsernamespace\endcsname}%
- \edef\next{\let\the\toksa\the\toksb}\next
- \toksa\expandafter{\next}\concat\pinittoks\toksa
-}
-
-% switch macro
-
-\def\stashswitch#1{%
- \toksa\expandafter{\csname #1\endcsname}%
- \toksb\expandafter{\csname #1\parsernamespace\endcsname}%
- \edef\next{\let\the\toksb\the\toksa}\next
- \edef\next{\let\the\toksa\the\toksb}%
- \toksa\expandafter{\next}\concat\pinittoks\toksa
+ \expandafter\expandafter\expandafter\let\expandafter
+ \expandafter\csname #1\endcsname\csname #1\parsernamespace\endcsname
+ \appendr\pinittoks{\let\expandafter\noexpand\csname #1\endcsname
+ \expandafter\noexpand\csname #1\parsernamespace\endcsname}%
}
% parser and lexer state control
-\def\settokreg#1{%
- \toksa{\csname newtoks\endcsname}%
- \expandafter\the\expandafter\toksa\csname #1\parsernamespace\endcsname
- \edef\next{\let\csname #1\endcsname\csname #1\parsernamespace\endcsname}\next
- \toksa\expandafter{\next}\concat\pinittoks\toksa
+\def\settokreg#1{% do not create individual token registers for each parser namespace
+ \expandafter\ifx\csname #1\endcsname\relax
+ \expandafter\expandafter\csname newtoks\endcsname\csname #1\endcsname
+ \fi
}
-\def\setcntreg#1{%
- \toksa{\csname newcount\endcsname}%
- \expandafter\the\expandafter\toksa\csname #1\parsernamespace\endcsname
- \edef\next{\let\csname #1\endcsname\csname #1\parsernamespace\endcsname}\next
- \toksa\expandafter{\next}\concat\pinittoks\toksa
+\def\setcntreg#1{% do not create individual count registers for each parser namespace
+ \expandafter\ifx\csname #1\endcsname\relax
+ \expandafter\expandafter\csname newcount\endcsname\csname #1\endcsname
+ \fi
}
\def\setnulstack#1{%
- \toksa\expandafter{\csname #1\endcsname}%
- \toksb\expandafter{\csname #1\parsernamespace\endcsname}%
- \edef\next{\let\the\toksb\noexpand\empty}\next
- \edef\next{\let\the\toksa\the\toksb}\next
- \toksa\expandafter{\next}\concat\pinittoks\toksa
- \setcntreg{#1<count>}% this is only needed for the accelerated stack
+ \expandafter\let\csname #1\parsernamespace\endcsname\empty % for the unoptimized stack
+ \appendr\pinittoks{\let\expandafter\noexpand\csname #1\endcsname
+ \expandafter\noexpand\csname #1\parsernamespace\endcsname}%
+ \setcntreg{#1<count>}% this is only (as well as the only action that is) needed for the accelerated stack
}
\def\setcurrentcs#1{%
- \toksa\expandafter{\csname #1\endcsname}%
- \toksb\expandafter{\csname #1\parsernamespace\endcsname}%
- \edef\next{\let\the\toksb\the\toksa}\next
- \edef\next{\toksa{\let\the\toksa\the\toksb}}\next
- \concat\pinittoks\toksa
+ \expandafter\expandafter\expandafter\let\expandafter
+ \expandafter\csname #1\parsernamespace\endcsname\csname #1\endcsname
+ \appendr\pinittoks{\let\expandafter\noexpand\csname #1\endcsname
+ \expandafter\noexpand\csname #1\parsernamespace\endcsname}%
}
+% switch macro
+
+\let\stashswitch\setcurrentcs
+
\def\newparserstate{%
\setcntreg{yytoken}%
\setcntreg{yystate}%
@@ -721,14 +778,18 @@
% \yyval and \yylval will be token registers
\settokreg{yyval}%
\settokreg{yylval}%
+ \setnulstack{astarray}% an array of AST nodes
\setnulstack{yyssa}%
\setnulstack{yyvsa}%
}
\def\newlexerstate{%
+ \settokreg{yytext@}% `dirty' buffer (contains stash and formatting)
+ \settokreg{yytext@seen}% read `dirty' buffer
\settokreg{yytext}%
\settokreg{yytextseen}%
\settokreg{yybyte}%
+ \settokreg{yysubtext}% stash between characters
\settokreg{yyfutureyytext}% token register used to save read text in eob macros
%
\settokreg{yytextpure}% % the registers that serve the same role
@@ -760,32 +821,133 @@
%
\setcntreg{yyfmark}% % the last marker in the current token
\setcntreg{yyfmarklast}%
+ \setcntreg{yyfmark@accept}%
\setcntreg{yysmark}%
\setcntreg{yysmarklast}%
+ \setcntreg{yysmark@accept}%
\setnulstack{yystatestack}%
\setcurrentcs{setflexstates}%
\setcurrentcs{ifyytextbackup}% this is purely to record the recovery command in \pinittoks
}
-\def\savestatelist#1{% this elaborate definition is needed to ensure that `throwaway token registers' like \toksa
- % survive the namespace switch
- \edef\next{\expandafter\expandafter\expandafter
- \let\expandafter\expandafter\expandafter\noexpand\expandafter\expandafter\csname #1\parsernamespace\endcsname
- \expandafter\noexpand\csname #1\endcsname}\next
-}
-
-\def\savefullstate{%
- \savestatelist{yyssa}%
- \savestatelist{yyvsa}%
- \savestatelist{yystatestack}%
- \savestatelist{ifyytextbackup}% buffer
-}
-
% use \pinittoks to compose a `parser restore' macro along with
% \let\yyvsa\yyvsa[parser namespace] and \let\yyssa\yyssa[parser namespace];
% `parser save' macro only has to set up \yy?sa[parser namespace]'s;
-% if a fully reentrant parser is required, use the macros above to save the contents of
-% all the variables by redefining \settokreg and \setcntreg and saving \yy?sa stacks
+%
+% this mechanism creates parsers that (barely) survive namespace switches (such as when a local
+% parser is used to extract information about the tokens) and does not result in a reentrant parser;
+% if a fully reentrant parser is required, either use the macros above to save the contents of
+% all the variables by redefining \settokreg and \setcntreg and saving \yy?sa stacks or, better still,
+% take advantage of the grouping mechanism provided by \TeX; note that the grouping approach seems
+% to be the only viable solution if the stack mechanism is `optimized'
+
+% optimization options
+
+\def\optimizeall{%
+ % lexer
+ \ifnum\optimization>\z@
+ \optimize{yynxt}%
+ \optimize{yyaccept}%
+ \optimize{yydef}%
+ \optimize{yychk}%
+ \optimize{yybase}%
+ \optimize{yyec}%
+ \optimize{yymeta}%
+ \tracingstats=\@ne
+ \fi
+ % parser
+ \ifnum\optimization>\@ne
+ \optimize{yytranslate}%
+ \optimize{yyrone}%
+ \optimize{yyrtwo}%
+ \optimize{yyrthree}%
+ \optimize{yydefact}%
+ \optimize{yydefgoto}%
+ \optimize{yypact}%
+ \optimize{yypgoto}%
+ \optimize{yytable}%
+ \optimize{yycheck}%
+ \optimize{yyprhs}%
+ \optimize{yyrhs}%
+ \optimize{yytoknum}%
+ \optimize{yystos}%
+ \optimizetext{yytname}%
+ \fi
+}
+
+% parser and lexer initialization, token prettyfying
+
+\def\genericparser name: #1, ptables: #2, ltables: #3, tokens: #4, asetup: #5, dsetup: #6, rsetup: #7, optimization: #8;{%
+ % parser initialization
+ %
+ \expandafter\def\csname #1namespace\endcsname{[#1]}%
+ \savecs{local-namespace}\parsernamespace
+ \expandafter\let\expandafter\parsernamespace\csname #1namespace\endcsname
+ \pinittoks{}%
+ \input #2 % load main parser table
+ \settokens % set the values of all tokens
+ \yystringempty{#4}{}{%
+ \input #4 % use token equivalence table to set the values of non-string tokens
+ }%
+ #5% (a)dditional setups
+ %
+ \input #3 % load lexer tables
+ %
+ % at this point the macros inside the table files (\newtable, \constset,
+ % \yybigswitch, \stashswitch, \addname, \yydoactionswitch, \setflexstates,
+ % \stateset, \tokeneq) have set up the corresponding stuctures in
+ % the `parser namespace' (e.g. if the parser namespace is `main',
+ % \newtable{yyaccept} created a token register \yyaccept[main]),
+ % assigned the `generic' names to them (to continue
+ % the example above, \newtable does \let\yyaccept\yyaccept[main]) and
+ % recorded the corresponding commands in \pinittoks for future use.
+ %
+ % lexer state macros are namespace specific (just like token names)
+ % so they have to be set in each namespace.
+ %
+ \setflexstates
+ #8% possible optimization
+ %
+ % finally, we add the definitions for the variables used in running
+ % the lexer and the parser.
+ \newparserstate
+ \newlexerstate
+ #6% additional (d)ata setup (say, \newlexerstateextra)
+ %
+ % we record all the commands necessary to switch to the desired namespace
+ % in a convenient macro
+ {%
+ \toks0{#7}% additional setup before switching namespaces
+ \edef\next{%
+ \the\toks0 % additional namespace setups
+ \let\noexpand\parsernamespace\expandafter\noexpand\csname #1namespace\endcsname
+ \the\pinittoks % restore all the tables, tokens and constants, and stacks
+ \let\noexpand\getcurrentparser\expandafter\noexpand\csname to#1parser\endcsname
+ }%
+ \toks0\expandafter{\next}%
+ \edef\next{\toks0{\def\expandafter\noexpand\csname to#1parser\endcsname{\the\toks0}}}\next
+ \expandafter
+ }\the\toks0
+ \restorecs{local-namespace}\parsernamespace
+}
+
+\def\genericprettytokens namespace: #1, tokens: #2, correction: #3, host: #4;{%
+ \savecs{local-namespace}{\parsernamespace\tokeneq}%
+ \yystringempty{#2}{}{%
+ \expandafter\let\expandafter\parsernamespace\csname #1namespace\endcsname
+ \def\tokeneq##1##2{\prettytoken{##1}}%
+ \let\tokenpp\prettytoken
+ \input #2 % /* re-use token equivalence table to set the typesetting of tokens */
+ }%
+ \yystringempty{#3}{}{%
+ \expandafter\let\expandafter\parsernamespace\csname #1namespace\endcsname
+ \input #3 % input customized typesetting rules for tokens
+ }%
+ \yystringempty{#4}{}{%
+ \expandafter\let\expandafter\hostparsernamespace\csname #4namespace\endcsname
+ }%
+ \restorecs{local-namespace}{\parsernamespace\tokeneq}%
+}
% switch and dfa macros
@@ -1186,7 +1348,7 @@
\def\setuprefs#1#2{%
\expandafter\let\csname$[#1]\endcsname.% $o the \ifx ... \relax test makes sense ...
\appendr\nameflagtoks{\noexpand\unsetsymname{#1}}% clean it up later
- \toksa{}\expandafter\charstonumbers#1\end
+ \toksa{}\expandafter\charstonumbers#1\end
\edef\next{\toksb{\space\space\noexpand\setsym{\the\toksa}{#2}\hc^^J\uu\uu\hc\hc\hc\uu#1 --> #2^^J}}\next
\edef\next{\toksc{\space\space\noexpand\unsetsym{\the\toksa}\hc^^J\uu\uu\hc\hc\hc\uu#1 --> \relax^^J}}\next
\concat\setsncommands\toksb
@@ -1420,3 +1582,8 @@
\setsymcs{#1}{#2}%
\setsymtr{#1}{#2}%
}
+
+% message output
+
+\def\ferrmessage#1{{\newlinechar`\^^J\immediate\write16{\parsernamespace::#1^^J}}}
+
diff --git a/support/splint/tex/yynested.sty b/support/splint/tex/yynested.sty
index db725abfc5..2a47c79593 100644
--- a/support/splint/tex/yynested.sty
+++ b/support/splint/tex/yynested.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2015, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -24,21 +24,12 @@
\boundaryupper-\@M
\boundarylower-\@M
-\expandafter\def\expandafter\parserdatainit\expandafter{%
- \parserdatainit
+\expandafter\def\expandafter\bisonparserdatainit\expandafter{%
+ \bisonparserdatainit
\boundaryupper-\@M
\boundarylower-\@M
}
-% the next sequence is just a reminder of what would have to be done if
-% reentrancy is required; the current state saving mechanism is intended for
-% bare unoptimized parsers exclusively and does not handle any constant saving
-
-\expandafter\def\expandafter\savefullstateextra\expandafter{%
- \savefullstateextra
- % save \boundaryupper and \boundarylower
-}
-
\def\inputboundarynext#1{%
\yybytepure{ }\yycp@\boundarychar
#1\getstackpointer\yyvsa\relax
diff --git a/support/splint/tex/yyparse.sty b/support/splint/tex/yyparse.sty
index ce5ab8b5e3..f6c6dadff8 100644
--- a/support/splint/tex/yyparse.sty
+++ b/support/splint/tex/yyparse.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2015, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -37,14 +37,14 @@
\yypushr\yystate\on\yyssa
{%
\iftraceparserstates
- \derrmessage{^^Jstate \the\yystate\iftracestacks, \fi}%
+ \ferrmessage{^^Jstate \the\yystate\iftracestacks, \fi}%
\fi
\iftracestacks
\iftraceparserstates
\else
- \derrmessage{^^J}%
+ \ferrmessage{^^J}%
\fi
- \showstack\yyssa\derrmessage{state stack: \stackcs^^J}%
+ \showstack\yyssa\ferrmessage{state stack: \stackcs^^J}%
\fi
}%
\yybreak\yybackup
@@ -117,7 +117,7 @@
\yybreak@@@\yynewstate % new state will be shifted
\else % ...if (yyn < 0)
\iffalse % if (yytable_value_is_error(yyn))
- % \ifnum\yyn=\YYTABLEERROR\relax
+ % /* #define yytable_value_is_error(Yytable_value) YYID (0) */
\yybreak@@@@\yyerr
\else
\yyn=-\yyn
@@ -137,7 +137,7 @@
\yyn=\fgetelemof{yydefact}\at\yystate\relax
% yyn = yydefact[yystate]
\iftraceactions
- \derrmessage{default action^^J}%
+ \ferrmessage{default action^^J}%
\fi
\ifnum\yyn=\z@
\xskiptofi\yyerr
@@ -149,16 +149,16 @@
\def\yyreduce{%
\yylen=\fgetelemof{yyrtwo}\at\yyn\relax
\iftracerules
- \derrmessage{^^Jreducing (rule \the\yyn)}\printrule{\yyn}%
+ \ferrmessage{^^Jreducing (rule \the\yyn)}\printrule{\yyn}%
\fi
{%
\iftracestacks
\iftracerules
\else
- \derrmessage{^^J}%
+ \ferrmessage{^^J}%
\fi
\showstack\yyssa
- \derrmessage{stack: \stackcs^^Jpopping \the\yylen^^J}%
+ \ferrmessage{stack: \stackcs^^Jpopping \the\yylen^^J}%
\fi
}%
\yyilen=\fgetelemof{yyrthree}\at\yyn\relax
@@ -218,14 +218,14 @@
\def\yypaccept{%
\iftraceparseresults
- \derrmessage{accepted^^J}%
+ \ferrmessage{accepted^^J}%
\fi
\finishparse
}
\def\yyerr{%
\iftraceparseresults
- \derrmessage{(parse) error^^J}%
+ \ferrmessage{(parse) error^^J}%
\fi
\cleanupparse
}
@@ -235,10 +235,12 @@
\let\yysymswitch\eatone
\let\yysymcleanup\eatone
+% parser specific output message: defines the current token name to output
+
\def\derrmessage#1{{%
\newlinechar=`\^^J%
\edef\tokname{\fgetelemof{yytname}\at\yytoken}%
- \message{#1}%
+ \ferrmessage{#1}%
}}
% these macros reuse dedicated counters ... locally
@@ -256,7 +258,7 @@
\else
\edef\ruleline{\ruleline\space<empty>}%
\fi
- \message{ -->\ruleline}%
+ \ferrmessage{ -->\ruleline}%
}}
% print the rule without using yyprhs and yyrhs (necessary if using
@@ -269,7 +271,7 @@
\else
\edef\ruleline{\ruleline\space<empty>}%
\fi
- \message{ -->\ruleline}%
+ \ferrmessage{ -->\ruleline}%
}}
\def\appendtoruleline#1{%
@@ -293,7 +295,7 @@
\long\def\cleanupparse#1\endparse{%
\iftracediscardedinput
- \immediate\write16{discarding the rest of the input}%
+ {\toksa{#1}\immediate\write16{discarding the rest of the input: \the\toksa}}%
\fi
\yyerror
}
@@ -317,3 +319,39 @@
%
\yysymcleanup{\yyn}% removing symbol names from the namespace
}
+
+% common parser initializations; note that some initializations (such as resetting the data
+% and state stacks) are done at parser startup (see the definition of \yyparse)
+
+\def\basicparserinit{%
+ \yytext{}%
+ \yysubtext{}%
+ \yytext@{}%
+ \yytextpure{}%
+ \yytextseenpure{}%
+ \yytextseen{}%
+ \yytext@seen{}%
+ \yybyte{}%
+ \yyfbyte{}\yysbyte{}%
+ \yystash{}%
+ \yystashseen{}%
+ \yyformat{}%
+ \yyformatseen{}%
+ \yyfutureyytext{}%
+ \yyinitstack\astarray % flattened AST to (possibly) speed up the parser
+ \yyinitstack\yystatestack
+ \yyfmark=\z@
+ \yysmark=\z@
+ \yyfmarklast=\z@
+ \yyfmark@accept=\z@
+ \formatmarker=\z@
+ \yysmarklast=\z@
+ \yysmark@accept=\z@
+ \stashmarker=\z@
+ \yytextbackupfalse
+ \yyg@yyinit=\z@
+ \yyg@yystart=\z@
+ \YYATBOL=\@ne
+ \yyparsefailfalse
+ \YYEOBLASTMATCHtrue
+}
diff --git a/support/splint/tex/yypretty.sty b/support/splint/tex/yypretty.sty
new file mode 100644
index 0000000000..aeb1179b32
--- /dev/null
+++ b/support/splint/tex/yypretty.sty
@@ -0,0 +1,25 @@
+% Copyright 2012-2020, Alexander Shibakov
+% Copyright 2002-2014 Free Software Foundation, Inc.
+% This file is part of SPLinT
+%
+% SPLinT is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% SPLinT is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
+
+% prettified token output for the common parts of \bison grammars;
+% for these to be properly displayed, the name parser must produce
+% the tokens in an appropriate namespace; they should also not be
+% \bison\ names (otherwise \TeX\ will complain about `... name ...
+% not exceptional ...')
+
+\prettywordpair{emptyrhs&}{$\circ$ {\rm(empty rhs)}}%
+\prettywordpair{inline_action&}{$\diamond$ {\rm(inline action)}}%
diff --git a/support/splint/tex/yystype.sty b/support/splint/tex/yystype.sty
index e37b298590..8e4660fb6e 100644
--- a/support/splint/tex/yystype.sty
+++ b/support/splint/tex/yystype.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2014, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -23,15 +23,10 @@
\setnulstack{obstackforstringraw}%
}
-\def\savefullstateextra{%
- \savestatelist{obstackforstring}%
- \savestatelist{obstackforstringraw}%
-}
-
% lexer environment
-\def\yycomplain#1{\immediate\write16{#1}} % lexer errors
-\def\yypdeprecated#1{\errmessage{option: #1 is ignored}} % outdated options
+\def\yycomplain#1{\ferrmessage{flex: #1}} % lexer errors
+\def\yypdeprecated#1{\yywarn{option: #1 is ignored}} % outdated options
\def\STRINGGROW{%
\concat\currentlaststring\yytextpure
@@ -63,3 +58,104 @@
\newtoks\laststringraw
\newtoks\currentlaststring
\newtoks\currentlaststringraw
+
+% common \bison parser initialization; the first macro initializes the lexer structures only
+% while the second one deals exclusively with the data produced by the parser; logically, in a `real'
+% \bison\ parser, the second set of initializations is applied to the |..._extra| local
+% data for the parser (for a reentrant yyparse()); we put it here for convenience.
+
+\def\bisonparserinit{%
+ \yyinitstack\obstackforstring
+ \yyinitstack\obstackforstringraw
+ \percentpercentcount=\z@
+ \lonesting=\z@
+ \laststring{}\laststringraw{}%
+ \currentlaststring{}\currentlaststringraw{}%
+}
+
+\def\bisonparserdatainit{%
+ \table{}\typestable{}\prectable{}\opttable{}%
+}
+
+% macros for \flex\ lexer
+
+\newif\iffldidadef
+\newif\ifflindented@code
+\newif\iffloption@sense
+\newif\iffllex@compat
+\newif\ifflposix@compat
+\newif\ifflin@rule
+\newif\iffldoing@rule@action
+\newif\ifflcontinued@action
+\newif\ifflend@is@ws
+\newif\ifflsf@skip@ws
+\newif\ifflsf@case@ins
+\newif\ifflsf@dot@all
+
+\newcount\fllinenum
+\def\flinc@linenum{\advance\fllinenum\@ne}
+\def\flinc#1{%
+ \expandafter\fl@nc\expandafter{\number#1}{#1}%
+}
+\def\fl@nc#1#2{%
+ \edef#2{\xincrement{#1}}%
+}
+
+\def\fldec#1{%
+ \expandafter\fld@c\expandafter{\number#1}{#1}%
+}
+\def\fld@c#1#2{%
+ \edef#2{\xdecrement{#1}}%
+}
+
+\def\yylessafter#1{}% put back the string starting at (after) #1
+\def\flsf@push{}% push the next parenthesis level
+\def\flsf@pop{}% pop the nesting level
+
+\def\RETURNNAME{\yylexreturnsym{NAME}}
+\def\RETURNCHAR{\yylexreturnsym{CHAR}}
+\def\yyflexoptreturn#1{%
+ \edef\next{\yylval{{\iffloption@sense\else no\fi}{\the\yytextpure}{\the\yyfmark}{\the\yysmark}}}\next
+ \yylexreturnregular{#1}%
+}
+
+% macros to process special character classes
+
+\def\makecclpair#1#2{%
+ \expandafter\def\csname xccl@#1\endcsname{\langle#2\rangle}%
+ \mak@cclpair#1.{#2}%
+}
+
+\def\mak@cclpair CCE_#1.#2{%
+ \expandafter\def\csname xccl@CCE_NEG_#1\endcsname{\langle^\neg#2\rangle}%
+}
+
+\makecclpair{CCE_ALPHA}{\alpha\beta}
+\makecclpair{CCE_ALNUM}{\alpha n}
+\makecclpair{CCE_BLANK}{\hbox{ }}
+\makecclpair{CCE_GRAPH}{\hbox{\dingssmall\leaf}}
+\makecclpair{CCE_DIGIT}{\hbox{\.{0..9}}}
+\makecclpair{CCE_XDIGIT}{\hbox{\.{0..Z}}}
+\makecclpair{CCE_SPACE}{\hbox{\.{\ }}}
+\makecclpair{CCE_LOWER}{\hbox{\.{a..z}}}
+\makecclpair{CCE_UPPER}{\hbox{\.{A..Z}}}
+\makecclpair{CCE_PRINT}{\hbox{\dingssmall\pen}}
+\makecclpair{CCE_PUNCT}{\hbox{\.{.}}}
+\makecclpair{CCE_CNTRL}{\mapsto}
+
+\def\xcclreturn#1{%
+ \yyBEGIN{CCL}%
+ \yytextpure{#1}% substitute the token name for the actual text
+ % this is slightly dangerous, because of the `_' in the name
+ % for this to work, ftokenset.sty must be used
+ \yylexreturnsym{#1}%
+}
+
+\chardef\flquotechar`\"
+
+\def\fllexsetup{%
+ \def\flbrace@depth{0}%
+ \def\flsectnum{0}%
+ \def\flnmstr{{}{}}% recorded name
+ \def\flnmdef{{}{}}% recorded definition
+}
diff --git a/support/splint/tex/yytexlex.sty b/support/splint/tex/yytexlex.sty
index a7e7dc3250..7c149108d3 100644
--- a/support/splint/tex/yytexlex.sty
+++ b/support/splint/tex/yytexlex.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2015, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -40,7 +40,7 @@
\appendyybyte}
=
{%
- \appendr\texlinetoks{{}${}={}${}}%
+ \appendrnx\texlinetoks{{}${}={}${}}%
\yygetchar
}
\{
@@ -62,12 +62,12 @@
\else
\def\next{^^A}%
\fi
- \action\next\in\texdefaultstate
+ \switchon\next\in\texdefaultstate
}
^^A % \yycp@==1
{%
\edef\next{\noexpand\noexpand\the\yybyte}%
- \action\next\in\texdefaultstate}
+ \switchon\next\in\texdefaultstate}
\raw\hbox\raw
{%
\appendnext}
@@ -151,14 +151,14 @@
\yycp@=`\\%
\putother\yycp@\in\yybyte
\def\next{escape}%
- \action\next\in\currentstate}
+ \switchon\next\in\currentstate}
}
\def\texescdefault{%
\let\currentstate\esccurrentstate
\yycp@=`\ %
\yybyte{\ }%
- \action\yycp@\in\currentstate
+ \caction\yycp@\in\currentstate
}
\def\getcescape{%
@@ -189,37 +189,42 @@
\fi
\fi
\fi
- \action\next\in\currentstate
+ \switchonwithtype\next\in\currentstate
}
\def\outputtexcs{%
- \expandafter\ifx\csname\the\yytext\defTpostfix\endcsname\relax
- \putother{`\\}\in\toksa
+ \expandafter\ifx\csname\defprefix\the\yytext\defpostfix\endcsname\relax
+ %\putother{`\\}\in\toksa
+ \toksa{\hbox{\sixpoint\tt\char`\\}}%
\concat\texlinetoks\toksa
\concat\texlinetoks\yytext
- \appendr\texlinetoks{\noexpand\hbox{$\noexpand\,$}}%
+ \appendrnx\texlinetoks{\hbox{$\,$}}%
+ \toksb{}% no visual key
\else
- \appendr\texlinetoks{\expandafter\expandafter\expandafter\noexpand\expandafter\csname\the\yytext xTeXmode\endcsname}%
+ \appendr\texlinetoks{\expandafter\noexpand\csname\defprefix\the\yytext\defpostfix\endcsname}%
+ \expandafter\ifx\csname\restorecsxname{index:visual}{.\the\yytext}\endcsname\relax
+ \toksb{}% no visual key
+ \else
+ \toksb\expandafter\expandafter\expandafter{\csname\restorecsxname{index:visual}{.\the\yytext}\endcsname}%
+ \fi
\fi
- \appendr\texidxtoks{%
- \termindex{{\nx\nx\nx\texcsstring{\expandafter\charstonumberse\the\yytext\end}}{\texnspace}{\nx\the\pageno}{\secno}}%
- }%
+ \appendr\texidxtoks{\gidxentryxb{\texcsstring}{\the\yytext}{\the\toksb}}%
}
-% the `calling conventions' for indexing \TeX\ control sequences are too different to use canned indexing macros
-% (the second parameter is a register so it has to be expanded before the \charstonumberse processes it)
-% we therefore invoke the macros by hand
+% indexing of \TeX\ control sequences
\def\texidxdomain{T}
\def\texcsidxrank{2}
+\def\texcstxtidxrank{5}
-\def\writetexidxentry#1{\iftermindex\write\gindex{\nx\nx\expandafter\nx\csname\texidxdomain TI\endcsname\texcsidxrank#1}\fi}
+\def\writetexidxentry#1{\indxe\gindex{{\secno}{{}{\texispace}}{\texidxdomain}{\texcsidxrank}#1}}
+\def\writetextxtidxentry#1{\indxe\gindex{{\secno}{{}{\texispace}}{\texidxdomain}{\texcstxtidxrank}#1}}
\def\appendyybyte{\concat\texlinetoks\yybyte\yygetchar}
\def\appendnext#1{\toksa{#1}\concat\texlinetoks\toksa\yygetchar}
-\def\defTpostfix{xTeXmode}
+\def\defTpostfix{[xTeXmode]}
\def\stripyybyte{%
\expandafter\stripyyb@te\the\yybyte
@@ -239,57 +244,69 @@
\newif\iftracetexpp
\newtoks\textoks
+% the most common way for a \TeX? macro to appear in in the input is being inserted by
+% \CWEB\ itself; in this case \CWEB\ makes sure that the macro is expanded in math mode;
+% this assumption is relied upon in the design of these macros, and violating it may
+% result in sume rather puzzling error messages, resulting from the insertion of
+% \ignorespaces outside of the current group; the warning macro below makes this
+% dependence explicit.
+
+\def\TeXxwarn{%
+ \relax
+ \ifmmode
+ \else
+ \errhelp{Check stash collecting macros.}%
+ \errmessage{\nx\\TeXx macro is used outside of math mode.}%
+ \fi
+}
+
\def\TeXx(#1)#2;{% TODO
- \let\oldttdot\.\relaxcweb
- \textoks{}\let\.\dotcollect
+ \TeXxwarn
+ {}$\let\oldttdot\.\relaxcweb
+ \let\.\dotcollect
+ \textoks{}%
#1%
\restorecweb\let\.\oldttdot
- \expandafter\T@Xx\the\textoks}
+ \expandafter\T@Xx\the\textoks
+ {}${}\aftergroup\ignorespaces}
\def\mypar{\par}
\def\TeXb(#1)#2;{% TeX material begin
- {}$%
+ \TeXxwarn
+ {}$\let\oldttdot\.\relaxcweb
+ \toksa{}\let\.\dotcollectb
+ \textoks{}%
\let\oldsix\6%
\let\6\ignorespaces
\let\oldC\C
\let\C\saveCcomments
- \let\oldttdot\.\relaxcweb
- \textoks{}\toksa{}\let\.\dotcollectb
#1%
\restorecweb\let\.\oldttdot
\dotcollectstripquotes
- ${}}
+ ${}\aftergroup\ignorespaces}
\def\TeXa(#1)#2;{% TeX material add
- {}$%
- \let\oldttdot\.\relaxcweb
+ \TeXxwarn
+ {}$\let\oldttdot\.\relaxcweb
\toksa{}\let\.\dotcollectb
#1%
\restorecweb\let\.\oldttdot
\dotcollectstripquotes
- ${}}
+ ${}\aftergroup\ignorespaces}
\def\TeXf(#1)#2;{% TeX material add
- {}$%
- \let\oldttdot\.\relaxcweb
+ \TeXxwarn
+ {}$\let\oldttdot\.\relaxcweb
\toksa{}\let\.\dotcollectb
\textoks\expandafter{\the\textoks\hbox{\6}}%
#1%
\restorecweb\let\.\oldttdot
\dotcollectstripquotes
- ${}}
-
-\def\TeXo(#1)#2;{% TeX material output
- \let\oldttdot\.\relaxcweb
- \let\.\dotcollect
- \let\6\oldsix
- \let\C\oldC
- #1%
- \restorecweb\let\.\oldttdot
- $\expandafter\T@Xx\expandafter"\the\textoks"$}
+ ${}\aftergroup\ignorespaces}
\def\TeXao(#1)#2;{% TeX material output
+ \TeXxwarn
{}$\let\oldttdot\.\relaxcweb
\toksa{}\let\.\dotcollectb
\let\6\oldsix
@@ -297,9 +314,11 @@
#1%
\restorecweb\let\.\oldttdot
\dotcollectstripquotes
- $\expandafter\T@Xx\expandafter"\the\textoks"${}${}}
+ \expandafter\T@Xx\expandafter
+ "\the\textoks"{}${}\aftergroup\ignorespaces}
\def\TeXfo(#1)#2;{% TeX material output
+ \TeXxwarn
{}$\let\oldttdot\.\relaxcweb
\toksa{}\let\.\dotcollectb
\textoks\expandafter{\the\textoks\hbox{\6}}%
@@ -308,11 +327,14 @@
#1%
\restorecweb\let\.\oldttdot
\dotcollectstripquotes
- $\expandafter\T@Xx\expandafter"\the\textoks"${}${}}
+ \expandafter\T@Xx\expandafter
+ "\the\textoks"{}${}\aftergroup\ignorespaces}
\let\TeXxi\TeXx
-\def\inlineTeXx#1{$\TeXxi(\.{"#1"});$} % for indexing macros
-
+\def\inlineTeXx#1{$\let\writetexidxentry\writetextxtidxentry\TeXxi(\.{"#1"});$} % for indexing macros
+\def\TeXlit{\iffalse{\fi}{\setbox0\lastbox}\removewhitespace
+ \expandafter\.\expandafter{\iffalse}\fi} % to help with \CWEB's @t...@> cleanup
+ % e.g.\ |TeXao(@t\TeXlit"\hbox{\TeX\ stuff}"@>);|
\def\dotcollect#1{\toksa{#1}\concat\textoks\toksa}
\def\dotcollectb#1{\toksb{#1}\concat\toksa\toksb}
\def\dotcollectstripquotes{\expandafter\d@tcollectstripquotes\the\toksa}
@@ -322,7 +344,6 @@
\def\restorecweb{\restorecs{local-namespace}{\)}}
\def\T@Xx"#1"{%
- {}${}%$
\iffalse{\fi % alignment!
\begingroup
% tune up the standard input routines
@@ -336,17 +357,17 @@
\texlinetoks{}\texidxtoks{}\bbalance\z@
\let\bbal\bbalempty
\yytextbackupfalse
+ \let\defpostfix\defTpostfix\let\defprefix\empty
\restorecsxlist\texnspace\alltexsymbols
\let\termindex\writetexidxentry
\yygetchar#1\end
- \toksc{#1}%
\iftracetexpp{\newlinechar=`^^J%
- \errmessage{TeX_ input: \the\toksc^^JTeX_ first pass: \the\texlinetoks}}\fi
+ \toksc{#1}\ferrmessage{TeX_ input: \the\toksc^^JTeX_ first pass: \the\texlinetoks}}\fi
\ifnum\bbalance=\z@
\else
- \bbbalance
+ \bbbalance{#1}%
\fi
- \iftracetexpp\errmessage{TeX_ final pass: \the\texlinetoks}\fi
+ \iftracetexpp\ferrmessage{TeX_ final pass: \the\texlinetoks}\fi
\concat\texlinetoks\texidxtoks
\expandafter
\endgroup
@@ -356,24 +377,35 @@
% otherwise there is a risk that an output routine is called before
% the group is complete and \yyreturn definition is wrong so \yyparse
% will not be able to function
- \expandafter\texlinetoks\expandafter{\the\texlinetoks}%
- \let\bbal\bbalempty\bbalance\z@
- \restorecsxlist\texnspace\alltexsymbols
- \let\termindex\writetexidxentry\tt\chardef\_=`\_\the\texlinetoks
+ \expandafter\T@Xpretypeset\the\texlinetoks
\endgroup
\iffalse}\fi
- {}${}%$
+}
+
+\def\T@Xpretypeset{%
+ \let\bbal\bbalempty\bbalance\z@
+ \let\defpostfix\defTpostfix\let\defprefix\empty
+ \restorecsxlist\texnspace\alltexsymbols
+ \tt\chardef\_=`\_%
}
\def\alltexsymbols{%
- \space\toksa\toksb\toksc\tokse\toksf\the\ifx\ifnum\fi\else
- \def\edef\let\empty\next\switchon\in\concat\appendr\default
- \noexpand\emptyterm\print\relax\yy\inmath\omit\hfil\getfirst
- \getsecond\getthird\getfourth\getfifth\nx\to\hspace\toksd\rhscont
- \rhscnct\rhsbool\table\ifrhsfull\rhsfulltrue\rhsfullfalse
- \yyval\tempca\tempcb\z@\@ne\tw@\m@ne\advance\ifcat\iftracebadchars
- \bb\yylexreturnptr\yylexreturn\yylexreturnval\yylexreturnchar
- \yylexreturntext\yylexnext
+ \space\toksa\toksb\toksc\toksd\tokse\toksf\toksg\toksh\the\ifx
+ \ifnum\fi\else\def\edef\let\empty\next\switchon\in\concat\appendr
+ \default\noexpand\emptyterm\print\relax\yy\inmath\omit\hfil\getfirst
+ \getsecond\getthird\getfourth\getfifth\nx\to\hspace\rhscont\rhscnct
+ \rhsbool\table\ifrhsfull\rhsfulltrue\rhsfullfalse\yyval\tempca
+ \tempcb\z@\@ne\tw@\m@ne\advance\ifcat\iftracebadchars\bb
+ \yylexreturnptr\yylexreturn\yylexreturnval\yylexreturnsym
+ \yylexreturnchar\yylexreturnxchar\yylexreturntext\yylexnext
+ \%\harmlesscomment\\\yyfatal\yywarn\yyBEGIN\yypushstate\yypopstate
+ \yyBEGINr\yylexstate\yypdeprecated
+}
+
+% TODO: make this the mechanism for updating \alltexsymbols
+
+\def\extendcs#1\with#2{%
+ \expandafter\def\expandafter#1\expandafter{#1#2}%
}
\def\collectspaces#1{%
@@ -394,23 +426,34 @@
\def\spacecontainer{\ }
\def\texnspace{texline}
+\def\texvspace{texvisline}
+\def\texispace{index}
\let\defpostfix\defTpostfix
\let\defprefix\empty
-\let\defypreamble\empty % for indexing macros
-\def\defypostamble{ {\rm(\.{\\\thisnamex})}}
-
\let\settgroup\relax
\defx\space{\hbox{$\,$\char`\ $\,$}}{texline}
+\defy\space{\hbox{$\,$\char`\ $\,$}}{index}
-\defx\hspace{\hbox{$\,$\char`\ $\,$}}{texline}
+\defx\hspace{% somewhat precarious definition
+ \hbox{\char`\ }%
+ \def\setegroup{{}$\,${}}%
+ \def\setpgr@up{^{\hbox{\sscmd\the\toksa}}\,$}%
+ \def\setegr@up{\,$}%
+ \def\setpgroup{%
+ ${}_{\hbox{\sscmd\the\toksa}}%
+ \let\setpgroup\setpgr@up
+ \let\setegroup\setegr@up
+ \grabbalanced
+ }\grabbalanced
+}{texline}
\defy\hspace{\hbox{$\,$\char`\ $\,$}}{index}
\defx\advance{%
- $\mathop{\hbox{\bf add}}{}$%
+ $\mathop{\hbox{\bf add}}$%
}{texline}
\defy\advance{%
@@ -425,6 +468,8 @@
$0_{\rm R}$%
}{index}
+\defx\z@{0_R}{index:visual}
+
\defx\@ne{%
$\,1_{\rm R}\,$%
}{texline}
@@ -433,6 +478,8 @@
$1_{\rm R}$%
}{index}
+\defx\@ne{1_R}{index:visual}
+
\defx\tw@{%
$\,2_{\rm R}\,$%
}{texline}
@@ -441,6 +488,8 @@
$2_{\rm R}$%
}{index}
+\defx\tw@{2_R}{index:visual}
+
\defx\m@ne{%
$\,-1_{\rm R}\,$%
}{texline}
@@ -449,151 +498,208 @@
$-1_{\rm R}$%
}{index}
+\defx\m@ne{-1_R}{index:visual}
+
\defx\tempca{%
- ${}t_a{}$%
+ $t_a$%
}{texline}
\defy\tempca{%
$t_a$%
}{index}
+\defx\tempca{t_a}{index:visual}
+
\defx\tempcb{%
- ${}t_b{}$%
+ $t_b$%
}{texline}
\defy\tempcb{%
$t_b$%
}{index}
+\defx\tempcb{t_b}{index:visual}
+
\defx\toksa{%
- {}${}v_a{}${}%
+ {}$v_a${}%
\def\setegroup{}%
\def\setpgroup{%
$\leftarrow\langle\,\hbox{\the\toksa}%
\if\next]%
\else
- \rangle%
+ \,\rangle%
\fi
$}\grabbalanced
}{texline}
+\defx\toksa{va}{index:visual}
+
\defy\toksa{%
- ${}v_a{}$%
+ $v_a$%
}{index}
\defx\toksb{%
- {}${}v_b{}${}%
+ {}$v_b${}%
\def\setegroup{}%
\def\setpgroup{%
$\leftarrow\langle\,\hbox{\the\toksa}%
\if\next]%
\else
- \rangle%
+ \,\rangle%
\fi
$}\grabbalanced
}{texline}
+\defx\toksb{vb}{index:visual}
+
\defy\toksb{%
- ${}v_b{}$%
+ $v_b$%
}{index}
\defx\toksc{%
- {}${}v_c{}${}%
+ {}$v_c${}%
\def\setegroup{}%
\def\setpgroup{%
$\leftarrow\langle\,\hbox{\the\toksa}%
\if\next]%
\else
- \rangle%
+ \,\rangle%
\fi
$}\grabbalanced
}{texline}
+\defx\toksc{vc}{index:visual}
+
\defy\toksc{%
- ${}v_c{}$%
+ $v_c$%
}{index}
\defx\toksd{%
- {}${}v_d{}${}%
+ {}$v_d${}%
\def\setegroup{}%
\def\setpgroup{%
$\leftarrow\langle\,\hbox{\the\toksa}%
\if\next]%
\else
- \rangle%
+ \,\rangle%
\fi
$}\grabbalanced
}{texline}
+\defx\toksd{vd}{index:visual}
+
\defy\toksd{%
- ${}v_d{}$%
+ $v_d$%
}{index}
\defx\tokse{%
- {}${}v_e{}${}%
+ {}$v_e${}%
\def\setegroup{}%
\def\setpgroup{%
$\leftarrow\langle\,\hbox{\the\toksa}%
\if\next]%
\else
- \rangle%
+ \,\rangle%
\fi
$}\grabbalanced
}{texline}
+\defx\tokse{ve}{index:visual}
+
\defy\tokse{%
- ${}v_e{}$%
+ $v_e$%
}{index}
\defx\toksf{%
- {}${}v_f{}${}%
+ {}$v_f${}%
\def\setegroup{}%
\def\setpgroup{%
$\leftarrow\langle\,\hbox{\the\toksa}%
\if\next]%
\else
- \rangle%
+ \,\rangle%
\fi
$}\grabbalanced
}{texline}
+\defx\toksf{vf}{index:visual}
+
\defy\toksf{$v_f$}{index}
+\defx\toksg{%
+ {}$v_g${}%
+ \def\setegroup{}%
+ \def\setpgroup{%
+ $\leftarrow\langle\,\hbox{\the\toksa}%
+ \if\next]%
+ \else
+ \,\rangle%
+ \fi
+ $}\grabbalanced
+}{texline}
+
+\defx\toksg{vg}{index:visual}
+
+\defy\toksg{$v_g$}{index}
+
+\defx\toksh{%
+ {}$v_h${}%
+ \def\setegroup{}%
+ \def\setpgroup{%
+ $\leftarrow\langle\,\hbox{\the\toksa}%
+ \if\next]%
+ \else
+ \,\rangle%
+ \fi
+ $}\grabbalanced
+}{texline}
+
+\defx\toksh{vh}{index:visual}
+
+\defy\toksh{$v_h$}{index}
+
\defx\yyval{%
- {}${}\Upsilon{}${}%
+ {}$\Upsilon${}%
\def\setegroup{}%
\def\setpgroup{%
$\leftarrow\langle\,\the\toksa
\if\next]%
\else
- \rangle%
+ \,\rangle%
\fi
$}\grabbalanced
}{texline}
\defy\yyval{%
- ${}\Upsilon{}$%
+ $\Upsilon$%
}{index}
-\def\setflexreturn#1{%
- \def\setegroup{{\bf return}#1}%
+\defx\yyval{Y}{index:visual}
+
+\def\setcfreturn#1{% more flexible return statement
+ \def\setegroup{{}$\mathop{\hbox{#1}}${}}%
+ \let\settgroup\setegroup
\def\setpgroup{%
{%
- \let\texidxdomain\bisonidxdomain
- \tokse\toksa
- \expandafter\nameproc\expandafter{\the\toksa}%
+ \let\termindex\writeidxentry % the indexed term is a \bison\ token
+ \toksc\toksa
+ \expandafter\nameproc\expandafter{\the\toksa}\with\parsebin
\ifyyparsefail
\edef\next{\toksa{\termmetastyle{%
- \expandafter\gidxentry\expandafter{\expandafter\termvstring\expandafter}\expandafter{\the\toksa}%
+ \gidxentryxb{\termvstring}{\the\toksa}{}%
\let\nx\idxfont\nx\empty\nx\tt\the\toksa\nx\/%
}}}\next
\else
- \expandafter\settermstyle\expandafter{\the\tokse}%
+ \edef\next{\noexpand\settermstyle{\the\toksb}{\the\toksc}}\next
\fi
- {}$\mathop{\hbox{{\bf return}#1}}\hbox{\the\toksa}${}}%
+ {}$\mathop{\hbox{#1}}\hbox{\the\toksa}${}}%
}\grabbalanced
}
+\def\setflexreturn#1{%
+ \setcfreturn{{\bf return}#1}%
+}
+
\defx\yylexreturnptr{%
\setflexreturn{$_p${}}%
}{texline}
@@ -602,14 +708,28 @@
{\bf return$_p$}%
}{index}
+\defx\yylexreturnptr{return_p}{index:visual}
+
+\defx\yylexreturnxchar{%
+ \setflexreturn{$_x${}}%
+}{texline}
+
+\defy\yylexreturnxchar{%
+ \hbox{\bf return$_x$}%
+}{index}
+
+\defx\yylexreturnxchar{return_x}{index:visual}
+
\defx\yylexreturnchar{%
- {\bf return$_c$}%
+ \hbox{\bf return$_c$}%
}{texline}
\defy\yylexreturnchar{%
- {\bf return$_c$}%
+ \hbox{\bf return$_c$}%
}{index}
+\defx\yylexreturnchar{return_c}{index:visual}
+
\defx\yylexnext{%
{\bf continue}%
}{texline}
@@ -618,6 +738,8 @@
{\bf continue}%
}{index}
+\defx\yylexnext{continue}{index:visual}
+
\defx\yylexreturn{%
\setflexreturn{$_l${}}%
}{texline}
@@ -626,6 +748,8 @@
{\bf return$_l$}%
}{index}
+\defx\yylexreturn{return_l}{index:visual}
+
\defx\yylexreturnval{%
\setflexreturn{$_v${}}%
}{texline}
@@ -634,6 +758,18 @@
{\bf return$_v$}%
}{index}
+\defx\yylexreturnval{return_v}{index:visual}
+
+\defx\yylexreturnsym{%
+ \setflexreturn{$_{vp}${}}%
+}{texline}
+
+\defy\yylexreturnsym{%
+ {\bf return$_{vp}$}%
+}{index}
+
+\defx\yylexreturnsym{return_vp}{index:visual}
+
\defx\yylexreturntext{%
{\bf return$_t$}%
}{texline}
@@ -642,10 +778,90 @@
{\bf return$_t$}%
}{index}
-\defx\table{{}${}\Omega{}${}}{texline}
+\defx\yylexreturntext{return_t}{index:visual}
+
+\defx\xcclreturn{%
+ \setcfreturn{\bf set $\Upsilon$ {\rm and} return$^{\rm ccl}$}%
+}{texline}
+
+\defy\xcclreturn{%
+ {\bf set $\Upsilon$ {\rm and} return$^{\rm ccl}$}%
+}{index}
+
+\defx\xcclreturn{set U return^ccl}{index:visual}
+
+\defx\yyflexoptreturn{%
+ \setflexreturn{$^{\rm opt}$}%
+}{texline}
+
+\defy\yyflexoptreturn{%
+ {\bf return$^{\rm opt}$}%
+}{index}
+
+\defx\yyflexoptreturn{return^opt}{index:visual}
+
+\extendcs\alltexsymbols\with{\xcclreturn\yyflexoptreturn}
+
+\defx\yyfatal{%
+ {}$\mathop{\bf fatal}${}%
+ \def\setegroup{}%
+ \def\setpgroup{%
+ $\langle\,\hbox{\the\toksa}%
+ \if\next]%
+ \else
+ \,\rangle%
+ \fi$%
+ }\grabbalanced
+}{texline}
+
+\defx\yyfatal{fatal}{index:visual}
+
+\defy\yyfatal{%
+ {\bf fatal}%
+}{index}
+
+\defx\yywarn{%
+ {}$\mathop{\bf warn}${}%
+ \def\setegroup{}%
+ \def\setpgroup{%
+ $\langle\,\hbox{\the\toksa}%
+ \if\next]%
+ \else
+ \,\rangle%
+ \fi$%
+ }\grabbalanced
+}{texline}
+
+\defx\yywarn{warn}{index:visual}
+
+\defy\yywarn{%
+ {\bf warn}%
+}{index}
+
+\defx\yypdeprecated{%
+ {}$\mathop{\bf deprecated}${}%
+ \def\setegroup{}%
+ \def\setpgroup{%
+ $\langle\,\hbox{\the\toksa}%
+ \if\next]%
+ \else
+ \,\rangle%
+ \fi$%
+ }\grabbalanced
+}{texline}
+
+\defx\yypdeprecated{deprecated}{index:visual}
+
+\defy\yypdeprecated{%
+ {\bf deprecated}%
+}{index}
+
+\defx\table{{}$\Omega${}}{texline}
\defy\table{$\Omega$}{index}
+\defx\table{Omega}{index:visual}
+
\defx\relax{\hbox{$\circ$}}{texline}
\defy\relax{\hbox{$\circ$}}{index}
@@ -662,6 +878,8 @@
\lcenclose{$\cdot$}%
}{index}
+\defx\the{val}{index:visual}
+
\def\thecomaction{%
\raw \toksaxTeXmode\toksbxTeXmode\tokscxTeXmode\toksdxTeXmode\toksexTeXmode\toksfxTeXmode \raw
{%
@@ -728,10 +946,18 @@
{\bf else$\;$}%
}{texline}
+\defy\else{%
+ {\bf else}%
+}{index}
+
\defx\fi{%
{\bf fi$\;$}%
}{texline}
+\defy\fi{%
+ {\bf fi}%
+}{index}
+
\defx\def{%
{\bf def$\;$}%
}{texline}
@@ -748,6 +974,8 @@
{\bf def$_{\rm x}$}%
}{index}
+\defx\edef{def_x}{index:visual}
+
\defx\let{%
{\bf let$\;$}%
}{texline}
@@ -808,6 +1036,10 @@
${}\mapsto{}$%
}{texline}
+\defy\to{%
+ $\mapsto$%
+}{index}
+
\defx\emptyterm{%
\hbox{$\ulcorner\ldots\urcorner$}%
}{texline}
@@ -840,6 +1072,8 @@
$\Upsilon\kern-1pt{}_{\rm?}$%
}{index}
+\defx\yy{Y_?}{index:visual}
+
\def\seeknots#1\bbal{%
\let\setegroup\relax
\ifnum#1>0\relax
@@ -904,6 +1138,8 @@
${}_{\rm?}\kern-2pt\Upsilon$%
}{index}
+\defx\bb{Y_??}{index:visual}
+
\defx\switchon{%
\hbox{\bf switch$\;$}%
\def\setpgroup{{$($}\the\toksa{$)$}$\,$}%
@@ -948,7 +1184,7 @@
\defx\getfirst{%
- {}${}\pi_1${}%
+ {}$\pi_1${}%
\def\setegroup{\relax}%
\def\setpgroup{%
${}(\hbox{\the\toksa}%
@@ -960,14 +1196,16 @@
}{texline}
\defy\getfirst{%
- ${}\pi_1$%
+ $\pi_1$%
}{index}
+\defx\getfirst{pi_1}{index:visual}
+
\defx\getsecond{%
- {}${}\pi_2${}%
+ {}$\pi_2${}%
\def\setegroup{\relax}%
\def\setpgroup{%
- ${}(\hbox{\the\toksa}%
+ $(\hbox{\the\toksa}%
\if\next]%
\else
)%
@@ -976,11 +1214,13 @@
}{texline}
\defy\getsecond{%
- ${}\pi_2$%
+ $\pi_2$%
}{index}
+\defx\getsecond{pi_2}{index:visual}
+
\defx\getthird{%
- {}${}\pi_3${}%
+ {}$\pi_3${}%
\def\setegroup{\relax}%
\def\setpgroup{%
${}(\hbox{\the\toksa}%
@@ -992,14 +1232,16 @@
}{texline}
\defy\getthird{%
- ${}\pi_3$%
+ $\pi_3$%
}{index}
+\defx\getthird{pi_3}{index:visual}
+
\defx\getfourth{%
- {}${}\pi_4${}%
+ {}$\pi_4${}%
\def\setegroup{\relax}%
\def\setpgroup{%
- ${}(\hbox{\the\toksa}%
+ $(\hbox{\the\toksa}%
\if\next]%
\else
)%
@@ -1008,14 +1250,16 @@
}{texline}
\defy\getfourth{%
- ${}\pi_4$%
+ $\pi_4$%
}{index}
+\defx\getfourth{pi_4}{index:visual}
+
\defx\getfifth{%
- {}${}\pi_5${}%
+ {}$\pi_5${}%
\def\setegroup{\relax}%
\def\setpgroup{%
- ${}(\hbox{\the\toksa}%
+ $(\hbox{\the\toksa}%
\if\next]%
\else
)%
@@ -1024,11 +1268,13 @@
}{texline}
\defy\getfifth{%
- ${}\pi_5$%
+ $\pi_5$%
}{index}
+\defx\getfifth{pi_5}{index:visual}
+
\defx\rhscont{%
- {}${}\pi_{\{\}}${}%
+ {}$\pi_{\{\}}${}%
\def\setegroup{\relax}%
\def\setpgroup{%
${}(\hbox{\the\toksa}%
@@ -1040,11 +1286,13 @@
}{texline}
\defy\rhscont{%
- ${}\pi_{\{\}}$%
+ $\pi_{\{\}}$%
}{index}
+\defx\rhscont{pi_brace}{index:visual}
+
\defx\rhscnct{%
- {}${}\pi_{\leftrightarrow}${}%
+ {}$\pi_{\leftrightarrow}${}%
\def\setegroup{\relax}%
\def\setpgroup{%
${}(\hbox{\the\toksa}%
@@ -1056,11 +1304,13 @@
}{texline}
\defy\rhscnct{%
- ${}\pi_{\leftrightarrow}$%
+ $\pi_{\leftrightarrow}$%
}{index}
+\defx\rhscnct{pi_arrow}{index:visual}
+
\defx\rhsbool{%
- {}${}\pi_{\vdash}${}%
+ {}$\pi_{\vdash}${}%
\def\setegroup{\relax}%
\def\setpgroup{%
${}(\hbox{\the\toksa}%
@@ -1072,9 +1322,53 @@
}{texline}
\defy\rhsbool{%
- ${}\pi_{\vdash}$%
+ $\pi_{\vdash}$%
+}{index}
+
+\defx\rhsbool{pi_implies}{index:visual}
+
+\defx\%{%
+ {\.{\harmlesscomment}}%
+}{texline}
+
+\defy\%{%
+ {\.{\harmlesscomment}}\let\defypostamble\relax%
}{index}
+\defx\%{\%}{index:visual}
+
+\defx\harmlesscomment{%
+ {\.{\harmlesscomment}}%
+}{texline}
+
+\defy\harmlesscomment{%
+ {\.{\harmlesscomment}}\let\defypostamble\relax%
+}{index}
+
+\defx\harmlesscomment{\%}{index:visual}
+
+\defx\\{%
+ {\.{\\}}%
+}{texline}
+
+\defy\\{%
+ {\.{\\}}\let\defypostamble\relax%
+}{index}
+
+\defx\\{\\}{index:visual}
+
+\defx\lbchar{%
+ \.{\{}%
+}{texline}
+
+\defy\lbchar{%
+ \.{\{}%
+}{index}
+
+\expandafter\defx\expandafter\lbchar\expandafter{\lbchar lbchar}{index:visual}
+
+\extendcs\alltexsymbols\with\lbchar
+
\def\bbalempty[#1]#2{%
\ifx#2]\relax
\else
@@ -1089,7 +1383,7 @@
\fi
}%
-\def\bbbalance{%
+\def\bbbalance#1{%
\ifnum\bbalance>0
\loop
\advance\bbalance-1\relax
@@ -1107,14 +1401,14 @@
\tempca-\bbalance
\bbalance\tempca
\texlinetoks{}\texidxtoks{}%
- \expandafter\yygetchar\the\toksc\end
+ \yygetchar#1\end
% \errmessage{\the\texlinetoks...\the\toksd...\the\bbalance}%
- \appendl\texlinetoks{\the\toksd}%
+ \concatl\toksd\texlinetoks
\fi
}
\def\grabbalanced{%
- \futurelet\next\gr@bbalanced
+ \futurelet\next\gr@bbalanced
}
\def\gr@bbalanced{%
@@ -1143,3 +1437,113 @@
\fi
\next
}
+
+\defx\yyBEGIN{%
+ \def\setegroup{{\bf enter}}%
+ \def\setpgroup{%
+ {%
+ \let\parsernamespace\flexpseudonamespace
+ \expandafter\nameproc\expandafter{\the\toksa}\with\parsebin
+ \edef\next{%
+ \toksd{\toksd{\the\toksa}\tokse{\the\toksb}}%
+ }\next % a trick to `reshuffle' the output of \nameproc:
+ % the parsed name goes to \toksd and the visual key is put in \tokse
+ \expandafter
+ }\the\toksd
+ \let\termindex\writeidxfsentry
+ \edef\next{{}$\nx\mathop{\hbox{\nx\bf enter}}(\hbox{\the\toksd})${}%
+ \gidxentryxb{\termvstring}{\the\toksa}{\the\tokse}}\next
+ \let\termindex\eatone
+ }\grabbalanced
+}{texline}
+
+\defy\yyBEGIN{%
+ {\bf enter}%
+}{index}
+
+\defx\yyBEGIN{enter}{index:visual}
+
+\defx\yyBEGINr{%
+ {\bf enter$_x\,$}%
+}{texline}
+
+\defy\yyBEGINr{%
+ {\bf enter$_x$}%
+}{index}
+
+\defx\yyBEGINr{enter_x}{index:visual}
+
+\defx\yypushstate{%
+ \def\setegroup{{\bf push state}}%
+ \def\setpgroup{%
+ {%
+ \let\parsernamespace\flexpseudonamespace
+ \expandafter\nameproc\expandafter{\the\toksa}\with\parsebin
+ \edef\next{%
+ \toksd{\toksd{\the\toksa}\tokse{\the\toksb}}%
+ }\next % a trick to `reshuffle' the output of \nameproc:
+ % the parsed name goes to \toksd and the visual key is put in \tokse
+ \expandafter
+ }\the\toksd
+ \let\termindex\writeidxfsentry
+ \edef\next{{}$\nx\mathop{\hbox{\nx\bf push state}}(\hbox{\the\toksd})\,${}
+ \gidxentryxb{\termvstring}{\the\toksa}{\the\tokse}}\next
+ \let\termindex\eatone
+ }\grabbalanced
+}{texline}
+
+\defy\yypushstate{%
+ {\bf push state}%
+}{index}
+
+\defx\yypushstate{push\_state}{index:visual}
+
+\defx\yypopstate{%
+ \def\setegroup{{\bf pop state}}%
+ \def\setpgroup{%
+ {%
+ \let\parsernamespace\flexpseudonamespace
+ \expandafter\nameproc\expandafter{\the\toksa}\with\parsebin
+ \edef\next{%
+ \toksd{\toksd{\the\toksa}\tokse{\the\toksb}}%
+ }\next % a trick to `reshuffle' the output of \nameproc:
+ % the parsed name goes to \toksd and the visual key is put in \tokse
+ \expandafter
+ }\the\toksd
+ \let\termindex\writeidxfsentry
+ \edef\next{{}$\nx\mathop{\hbox{\nx\bf pop state}}(\hbox{\the\toksd})\,${}
+ \gidxentryxb{\termvstring}{\the\toksa}{\the\tokse}}\next
+ \let\termindex\eatone
+ }\grabbalanced
+}{texline}
+
+\defy\yypopstate{%
+ {\bf pop state}%
+}{index}
+
+\defx\yypopstate{pop state}{index:visual}
+
+\defx\yylexstate{%
+ \def\setegroup{{\bf state}}%
+ \def\setpgroup{%
+ {%
+ \let\parsernamespace\flexpseudonamespace
+ \expandafter\nameproc\expandafter{\the\toksa}\with\parsebin
+ \edef\next{%
+ \toksd{\toksd{\the\toksa}\tokse{\the\toksb}}%
+ }\next % a trick to `reshuffle' the output of \nameproc:
+ % the parsed name goes to \toksd and the visual key is put in \tokse
+ \expandafter
+ }\the\toksd
+ \let\termindex\writeidxfsentry
+ \edef\next{{}$\nx\mathop{\hbox{\nx\bf state}}(\hbox{\the\toksd})\,${}%
+ \gidxentryxb{\termvstring}{\the\toksa}{\the\tokse}}\next
+ \let\termindex\eatone
+ }\grabbalanced
+}{texline}
+
+\defy\yylexstate{%
+ {\bf state}%
+}{index}
+
+\defx\yylexstate{state}{index:visual}
diff --git a/support/splint/tex/yyunion.sty b/support/splint/tex/yyunion.sty
index d9749a86b9..7f4937a4e3 100644
--- a/support/splint/tex/yyunion.sty
+++ b/support/splint/tex/yyunion.sty
@@ -1,4 +1,4 @@
-% Copyright 2012-2015, Alexander Shibakov
+% Copyright 2012-2020, Alexander Shibakov
% This file is part of SPLinT
%
% SPLinT is free software: you can redistribute it and/or modify
@@ -21,6 +21,7 @@
\def\yyuniontag{\yyunion}
\def\parserstrictnamespace{parser-strict}
\def\parserprototypesnamespace{parser-strict:headers}
+\def\parserdebugnamespace{parser-debug}
\def\yyunion{\currentyyunionnamespace}
\def\currentyyunionnamespace{generic}
@@ -29,6 +30,11 @@
% therefore they are not included in the yyunion list and only defined once below and redefined later
% permanently
+\def\cwebstreamchars{% characters seen by the input routine
+ \|\`\\\{\}\~\ \_\&\^\$\#\n% the last one is inserted by the preprocessing scripts
+}
+
+
% insidemost
\long\def\stashed#1{} % stashed material (usually \Cee\ code) :: \stashed{tex_string}
@@ -40,23 +46,24 @@
\long\def\strm[#1]#2.[#3]{} % a stream element :: \strm[digits]{\stashed|\format|\formatlocal}.[digits]
-% types returned by the lexer (* marks the types that get removed by the parser in some cases)
+% types returned by the lexer; the integer type (hex vs. decimal) is determined at the lexer level so
+% these are tagged by the lexer as well
-\def\midf#1#2{} % rule separator :: \midf{fptr}{sptr}
-\defp\stringify#1#2#3#4{} % STRING :: \stringify{12string}{tex_string}{fptr}{sptr}
-\defp\idit#1#2#3#4{} % ID :: \idit{12string}{tex_string}{fptr}{sptr}
-\defp\tagit#1#2#3#4{} % TAG :: \tagit{12string}{tex_string}{fptr}{sptr}
-\defp\charit#1#2#3#4{} % CHAR :: \charit{12string}{tex_string}{fptr}{sptr}
\defp\anint#1#2#3{} % INT :: \anint{digits}{fptr}{sptr}
\defp\hexint#1#2#3{} % INT :: \hexint{0[xX][0-9A-F]+}{fptr}{sptr}
+
+% types inserted by the parser (* marks the types that are essentially returned by the lexer
+% and `tagged' by the parser)
+
+\defp\idit#1#2#3#4{} % *ID :: \idit{12string}{tex_string}{fptr}{sptr}
+\defp\charit#1#2#3#4{} % *CHAR :: \charit{12string}{tex_string}{fptr}{sptr}
+\defp\stringify#1#2#3#4{} % *STRING :: \stringify{12string}{tex_string}{fptr}{sptr}
+\defp\tagit#1#2#3#4{} % *TAG :: \tagit{12string}{tex_string}{fptr}{sptr}
\defp\braceit#1#2#3{} % *BRACED_CODE :: \braceit{tex_string}{fptr}{sptr}
+\defp\midf#1#2{} % *rule separator :: \midf{fptr}{sptr}
\defp\preckind#1#2#3{} % *precedence operator :: \preckind{12string}{fptr}{sptr}
+%
\defp\flexoptionpair#1#2{} % a flex option :: \flexoptoinpair{\idit}{\idit|\stringify}
-
-% types inserted by the parser
-
-% insidemost
-
\defp\termname#1#2{} % a production term :: \termname{\idit|\stringify|\charit}{\idit}
\defp\mergeop#1#2#3{} % merge directive :: \mergeop{\tagit}{fptr}{sptr}
\defp\dprecop#1#2#3{} % dprec directive :: \dprecop{\anint|\hexint}{fptr}{sptr}
@@ -89,6 +96,7 @@
\defp\prodprodsep{} % production separator
\defp\prodprodseplarge{} % production separator
\defp\optoptsepsmall{} % separator between options
+\defp\optoptsepnone{} % (trivial) separator between options
\defp\posmark#1#2{} % the position marker :: \posmark{fptr}{sptr}
\defp\tokendecls#1#2#3{} % token declarations :: \tokendecls{[\onesymbol]+}{fptr}{sptr}
\defp\ntermdecls#1#2#3{} % nterm declarations :: \ntermdecls{[\onesymbol]+}{fptr}{sptr}
@@ -96,7 +104,7 @@
\defp\precdecls#1#2#3#4#5{} % precedence declarations :: \precdecls{left|right|nonassoc|precedence}{\tagit}{[\idit\stringify\charit]+}{fptr}{sptr}
\defp\flexsstatedecls#1#2#3{} % flex state declarations (nonexlusive) :: \flexsstatedecls{[\idit\stringify]+}{fptr}{sptr}
\defp\flexxstatedecls#1#2#3{} % flex state declarations (exclusive) :: \flexxstatedecls{[\idit\stringify]+}{fptr}{sptr}
-\defp\flexoptiondecls#1#2#3{} % flex state declarations :: \flexoptiondecls{[\flexoptionpair]+}{fptr}{sptr}
+\defp\flexoptiondecls#1#2#3{} % flex options :: \flexoptiondecls{[\flexoptionpair]+}{fptr}{sptr}
\defp\oneparametricoption#1#2#3#4{} % option :: \oneparametricoption{option-name}{\stringify|\idit}{fptr}{sptr}
\defp\optionflag#1#2#3#4{} % option flag :: \optionflag{flag name}{abbreviated name}{fptr}{sptr}
\defp\paramdef#1#2#3#4{} % parameters :: \paramdef{\braceit}{parameter domain}{fptr}{sptr}
@@ -133,17 +141,276 @@
\newtoks\yystashlocal
\newtoks\yyformatlocal
+% index implementation
+% note that the rank and domain parameters are handed down by the
+% `outer' macro while the `qualifier' (\term...string) is decided
+% at the point of invocation; some auxilary sequences first
+
+% a macro that always produces the current value of the register
+
+\def\thewrap#1#2{%
+ \noexpand\thewrap{\noexpand#1}{\the#1}%
+}
+
+% a macro that always produces the current page number.
+
+\def\selfpageno#1{%
+ \noexpand\selfpageno{\the\pageno}%
+}
+
+% a macro that keeps the (single) argument intact
+
+\def\stickycs#1{\noexpand\stickycs\noexpand#1}
+
+% for finer control over indexing, there are two levels on which
+% the programmer can disable the production of a whatsit node (\write):
+% (1) by setting the \iftermindex conditional to \iffalse, and (2) by defining
+% the \termindex macro to ignore its argument; both of these are expanded
+% at the point where the index entry is made; the intention is that
+% the conditional controls indexing at large (say, the index entries
+% inside the index should not be indexed again), while redefining the macro
+% provides a finer control over the indexing style
+
\newif\iftermindex
-\def\doparse#1{%
- \table{}\typestable{}\prectable{}\opttable{}%
- \parserinit\yyparse#1\yyeof\yyeof\endparseinput\endparse
+\let\termindex\eatone
+
+% the index is split into different domains: say, the \bison\ domain contains
+% the entries for the terms of a grammar;
+
+\def\bisonidxdomain{B} % marker for the domain (section of the index)
+
+\def\defidxrank{0} % index rank of definitions is lowest so they are listed first
+\def\headeridxrank{1} % index rank of lhs
+\def\termidxrank{2} % ordinary term rank
+
+% the expansion of the various components of an index entry must be carefully
+% controlled: it is not possible to predict how many times the entry will be expanded;
+% there are four types of expandable entries in general:
+% o the entries that must be expanded at the point of invocation (say, \secno)
+% o the entries that must be expanded only when the \write is inside a \box that is
+% being shipped out (say, the \pageno)
+% o the `lazy' entries that can be expanded any time (although at least one expansion
+% must take place)
+% o finally, the entries that must be expanded at a specific point between the point
+% of invocation and the \shipout
+% the indexing macro below treats the first three cases for the entries that the macro
+% below produce; the last case can be implemented by redefining the \stickycs macro
+% at the appropriate point
+
+\def\indxe#1#2{% index entry:
+ % #1 is the output stream
+ % #2 is the entry (see below for the proper form)
+ \expandafter\ind@@\expandafter#2\end{#1}%
+}
+
+\def\ind@@#1\end#2{%
+ \ind@e{#2}{#1}%
+}
+
+\def\ind@e#1#2{% #1 is the output stream
+ % #2 is a 8-parameter sequence, see below
+ \write#1{\in@@e#2\in@@ecomment#2}%
+}
+
+\def\in@@e#1#2#3#4#5#6#7#8{% #1: early expandable (like \secno)
+ % #2: auxilary info (expandable, invariant)
+ % #3: domain
+ % #4: rank
+ % #5: type1
+ % #6: type2
+ % #7: key1
+ % #8: key2
+ \i@@@e{#1}{\errmessage{\noexpand\\in@@e error: expanded page number placeholder}}%
+ {#2}{#3}{#4}{#5}{#6}{\charstonumberse#7\end}{\charstonumberse#8\end}%
+}
+
+\def\in@@ecomment#1#2#3#4#5#6#7#8{% #1: early expandable (like \secno)
+ % #2: auxilary info (expandable, invariant)
+ % #3: domain
+ % #4: rank
+ % #5: type1
+ % #6: type2
+ % #7: key1
+ % #8: key2
+ \harmlesscomment\space\charstocharsx#7\end :: \charstocharsx#8\end%
+}
+
+\def\i@@@e#1#2#3#4#5#6#7#8#9{% #1: early expandable (like \secno)
+ % #2: page number placeholder
+ % #3: auxilary info
+ % #4: domain
+ % #5: rank
+ % #6: type1
+ % #7: type2
+ % #8: key1
+ % #9: key2
+ \noexpand\i@@@e{#1}{\the\pageno}{#3}{#4}{#5}{\noexpand#6}{\noexpand#7}{#8}{#9}%
+}
+
+\def\appendfitotoksa{\toksa\expandafter{\the\toksa\else<>\fi}} % hide \fi inside the loop
+
+% defining expandable macros for string transformations
+
+\tempca\@ne
+\toksa{\ifcase#1<NUL>}
+\tempcb=\uccode`.
+
+\bloop
+\uccode`.=\tempca
+\uppercase{\toksb\expandafter{.}}%
+\toksa\expandafter\expandafter\expandafter{\expandafter\the\expandafter\toksa\expandafter\or\the\toksb}%
+\advance\tempca by\@ne
+\ifnum\tempca>"FF
+ \appendfitotoksa
+\else
+\repeat
+
+\def\charstocharsx#1\end{% expandable version of a `safety' macro, ascii characters only, no tricky space characters
+ \yystartsinspace{#1.}{%
+ \space\ch@rstocharsx#1\end
+ }{%
+ \yystringempty{#1}{}{%
+ \ch@rst@charsx#1\end
+ }%
+ }%
+}
+
+\def\ch@rstocharsx#1 #2\end{\charstocharsx#2\end}
+
+\def\ch@rst@charsx#1#2\end{\asciiprint{`#1}\charstocharsx#2\end}
+
+\edef\next{\toksa{\def\noexpand\asciiprint##1{\the\toksa}}}\next
+\the\toksa
+
+\def\writeidxhentry#1{%
+ \indxe\gindex{{\secno}{{\currentrulecontext}{\hostparsernamespace}}{\bisonidxdomain}{\headeridxrank}#1}%
+}
+
+\def\writeidxentry#1{%
+ \indxe\gindex{{\secno}{{\currentrulecontext}{\hostparsernamespace}}{\bisonidxdomain}{\termidxrank}#1}%
+}
+
+\def\writetokenidxentry#1{%
+ \indxe\gindex{{\secno}{{\currentrulecontext}{\hostparsernamespace}}{\bisonidxdomain}{\defidxrank}#1}%
+}
+
+\def\gidxentry#1#2#3{% a generic index entry:
+ % #1 is the type processor,
+ % #2 is the key
+ % #3 is the visual key
+ \iftermindex
+ \termindex{{}{#1}{#2}{#3}}%
+ \fi
+}
+
+% a convenient shortcut, as many visual keys come in a token register
+
+\def\gidxentryxv#1#2#3{% a generic index entry, e(x)pand (v)isual key:
+ % #1 is the type processor,
+ % #2 is the key
+ % #3 is the visual key
+ \expandafter\gidx@ntryxv\expandafter{#3}{#1}{#2}%
+}
+
+\def\gidxentryxb#1#2#3{% a generic index entry, e(x)pand (b)oth keys:
+ % #1 is the type processor,
+ % #2 is the key
+ % #3 is the visual key
+ \expandafter\gidx@ntryxb\expandafter{#2}{#3}{#1}%
+}
+
+\def\gidx@ntryxb#1#2#3{%
+ \expandafter\gidx@ntryxv\expandafter{#2}{#3}{#1}%
+}
+
+\def\gidx@ntryxv#1#2#3{%
+ \gidxentry{#2}{#3}{#1}%
+}
+
+\def\tidxentry#1#2{% a text index entry, TODO: expand \currentrulecontext
+ \iftermindex
+ \indxe\gindex{{\secno}{{\currentrulecontext}{\indexpseudonamespace}}{\bisonidxdomain}{\termidxrank}{}{#1}{#2}{}}%
+ \fi
+}
+
+\def\idxinline#1{% index the term in text
+ \edef\next{\tidxentry{\termidstring}{#1}}\next
+}
+
+\def\gatherstash#1#2\strm[#3]#4.[#5]{% #1 contains the stash gathered
+ \yystringempty{#3}{ #1}%
+ {%
+ \expandafter\g@therstash\expandafter{\romannumeral0\unstash#4}{#1}%
+ }%
+}
+
+% stash processing wrapper macros
+
+\def\g@therstash#1#2{\gatherstash{#2#1}}
+
+\def\unstash#1#2{\expandafter\space#2}% #1 is \stashed or \sflush
+
+\def\yyreadstash#1\to#2\in#3\with#4{%
+ \yyreadfifo#1\to#2\in#3%
+ #4{#3}%
+ \setbox\z@=\vbox{
+ \hsize\maxdimen\emergencystretch\maxdimen
+ \rightskip\z@ plus 1fill
+ \insertstash{#3}%
+ \ifmmode
+ {}$\aftergroup\yyr@adstash % $o that the box can be finished
+ \else
+ \aftergroup\eatthree
+ \fi
+ }{#1}{#2}{#3}%
+}
+
+\def\yyr@adstash#1#2#3{%
+ #3\expandafter{\the#3{}$}% $
+ \appendlnx#1{\strm[NaN]{\stashed{{}${}}}.[NaN]}% {}, in case \yystash ends with $
+}
+
+% the sequence below may be redefined so that the #2 parameter to \yyreadstash may be a list of
+% token registers
+
+\def\insertstash#1{\the#1\relax}
+
+\def\readstash#1{\yyreadstash\yystash\to#1\in\yystashlocal\with\unpackstash}
+
+\def\readstashwredirect#1#2#3{% helper macro to read the stash when the stash and the format pointers appear together
+ % #1(the format pointer) is ignored
+ % #2 is the stash marker
+ % #3 is the local stash register
+ \yyreadstash\yystash\to#2\in#3\with\unpackstash
+}
+
+\def\unpackstash#1{#1\expandafter{\romannumeral0\expandafter\unp@ckstash\the#1\strm[].[]}}
+
+\def\unp@ckstash{\gatherstash{}}
+
+\def\unwrapstash#1{% to use where only the removal of \strm and \stashed is needed
+ #1\expandafter{\romannumeral0\expandafter\unwr@pstash\the#1\strm[].[]}%
}
-\long\def\strm[#1]#2.[#3]{#2}
+\def\unwr@pstash{\gatherstash{}}
+
+% parser invocation
+
+\def\newparserstateextra{}
+
+\def\d@parse#1{\yyparse#1\yyeof\yyeof\endparseinput\endparse}
+
+\def\astarraylastcs{\expandafter\noexpand\romannumeral\gettopofstackcsx\astarray}
+
+\long\def\strm[#1]#2.[#3]{#2} % this is used with both the format and the stash streams; TODO: deprecate
+
\long\def\inmath#1{$#1$}
-\long\def\stashed#1{\toksa\expandafter{\the\toksa#1}}
+%\long\def\stashed#1{\toksa\expandafter{\the\toksa#1}} % to be used with unpackaged stash
+%\long\def\stashed#1{\toksa\expandafter\expandafter\expandafter{\expandafter\the\expandafter\toksa#1}} % to use with AST array
+\long\def\stashed#1{\errmessage{making \noexpand\stashed\space expandable is deprecated}}
+
\long\def\sflush#1#2{}
\def\ntt{\noexpand\ntt@} % a convenient shortcut
@@ -157,15 +424,6 @@
\let\termindex\eatone
}
-\def\headeridxrank{1} % index rank of lhs
-
-\def\writeidxhentry#1{\write\gindex{%
- \nx\nx
- \expandafter
- \nx
- \csname\bisonidxdomain TI\endcsname\headeridxrank#1}%
-}
-
\def\prodhead@r#1#2{%
\let\idit\prodhdridit
#1\relax\concat\table\toksa\hrhss@p
@@ -229,45 +487,32 @@
\let\stringify\termnamestringify
\let\optstrextra\optstrextraesc
\let\termindex\writeidxentry
- #1\relax\concat\table\toksa
+ \termnam@{#1}{#2}%
\let\termindex\eatone
}
-\def\bisonidxdomain{B} % marker fo the domain (section of the index)
-\def\termidxrank{2} % rank (affects the order in which the entries are
- % listed in the index and the listing style)
-
-\def\writeidxentry#1{\write\gindex{%
- \nx\nx
- \expandafter
- \nx
- \csname\bisonidxdomain TI\endcsname\termidxrank#1}%
-}
+\def\termnam@#1#2{\toksa{}\toksb{}\toksc{}#1\expandafter\termn@m@\expandafter{\the\toksa}{#2}}
-\let\termindex\eatone
+\def\termn@m@#1#2{\toksa{}\toksb{}\toksc{}#2\expandafter\t@rmn@m@\expandafter{\the\toksa}{#1}}
-% index implementation
-% note that the rank and domain parameters are handed down by the
-% `outer' macro while the `qualifier' (\term...string) is decided
-% at the point of invocation
+% several versions of term typesetting
-\def\gidxentry#1#2{% a generic index entry
- \iftermindex
- \termindex{%
- {\nx\nx\nx#1{\charstonumberse#2\end}}%
- {\hostparsernamespace}{\nx\the\pageno}{\secno}%
- }%
- \fi
+\def\t@rmn@m@#1#2{% the termname is #2, the bracketed part is in #1
+ \yystringempty{#1}{\toksa{#2}}{\toksa{#2\hbox{$\langle${}#1{}$\rangle$}}}%
+ \concat\table\toksa
}
-\def\tidxentry#1#2{% a text index entry
- \iftermindex
- \write\gindex{%
- \nx\nx\expandafter\nx\csname\bisonidxdomain TI\endcsname\termidxrank
- {\nx\nx\nx#1{\charstonumberse#2\end}}%
- {\indexpseudonamespace}{\nx\the\pageno}{\secno}%
- }%
- \fi
+\newif\ifbracketedvisible % decide whether to show the bracketed name in productions
+
+\def\t@rmn@m@#1#2{% the termname is #2, the bracketed part is in #1
+ \yystringempty{#1}{\toksa{#2}}{%
+ \ifbracketedvisible
+ \toksa{#2\hbox{$\,\cdot$#1}}%
+ \else
+ \toksa{#2}%
+ \fi
+ }%
+ \concat\table\toksa
}
%
@@ -278,77 +523,46 @@
\yyreadfifo\yyformat\to#3\in\yyformatlocal
\restorecs{table-render}{\strm}%
#5% accumulate all the directives
- \edef\next{\the\bdirects}%
- \ifx\next\empty
- \else
+ \yytoksempty\bdirects{}{%
\edef\next{\bdirects{%
$\vtop{\halign{\nx\quad####\nx\hfil&####\nx\hfil\cr\the\bdirects}}$}}\next
- \fi
+ }%
\the\yyformatlocal
\actbrac@s{#1}{#2}{#4}%
}
\def\actbrac@s#1#2#3{%
- \yyreadfifo\yystash\to#3\in\yystashlocal
- \unmathstash{#3}%
- \edef\next{\toksa{\the\bdirects&\the\yystashlocal\cr}}\next
+ \readstash{#3}%
+ \appendr\table{\the\bdirects&\toksa{\the\yystashlocal}\cr}%
\bdirects{}%
- \concat\table\toksa
-}
-
-\def\unmathstash#1{%
- \setbox\z@=\vbox{
- \hsize\maxdimen\emergencystretch\maxdimen
- \rightskip\z@ plus 1fill
- \let\TeXx\relax\let\stashed\copystashed
- \the\yystashlocal\relax
- \ifmmode
- {}$\aftergroup\unm@thstash % $o that the box can be finished
- \else
- \aftergroup\eatone
- \fi}{#1}%
-}
-
-\def\copystashed#1{#1}
-
-\def\unm@thstash#1{%
- \toksa{\strm[NaN]{\stashed{{}$}}.[NaN]}% $o it cannot be matched if \yystashlocal is read again
- \concat\yystashlocal\toksa
- \toksa{\strm[#1]{\stashed{${}}}.[#1]}%$
- \appendl\yystash{\the\toksa}%
}
\def\bpredicate#1#2#3#4#5\bdend{%
\yyreadfifo\yyformat\to#3\in\yyformatlocal
\restorecs{table-render}{\strm}%
#5% accumulate all the directives
- \edef\next{\the\bdirects}%
- \ifx\next\empty
+ \yytoksempty\bdirects{%
\bdirects{\quad$\dashv\ \nx\vdash$}%
- \else
+ }{%
\edef\next{\bdirects{%
$\vtop{\halign{\nx\quad####\nx\hfil&####\nx\hfil\cr$\dashv\ $&\omit\nx\hfil$\nx\vdash$\cr
\the\bdirects}}$}}\next
- \fi
+ }%
\the\yyformatlocal
\bpredicat@{#1}{#2}{#4}%
}
-\def\bpredicat@#1#2#3{%
- \yyreadfifo\yystash\to#3\in\yystashlocal
- \unmathstash{#3}%
- \edef\next{\toksa{\the\bdirects&\the\yystashlocal\cr}}\next
+\def\bpredicat@#1#2#3{%
+ \readstash{#3}%
+ \appendr\table{\the\bdirects&\toksa{\the\yystashlocal}\cr}%
\bdirects{}%
- \concat\table\toksa
}
\def\bdirective#1#2#3#4{%
\savecslist{local-namespace}\yyunion
\restorecslist{table-render:directives}\yyunion
- \toksa{}%
- #2% make a directive list
- \edef\next{\toksa{$\nx\langle${\ntt #1} &\the\toksa$\nx\rangle$\cr}}\next
- \concat\bdirects\toksa
+ \toksa{}#2% make a directive list
+ \appendr\bdirects{$\nx\langle${\ntt #1} &\the\toksa$\nx\rangle$\nx\cr}%
\restorecslist{local-namespace}\yyunion
}
@@ -379,34 +593,43 @@
\let\currentrulecontext\empty
-\def\emptyterm{%
- \edef\next{\toksa{$\nx\circ$\tidxentry{\termidstring}{emptyrhs}}}\next
- \concat\table\toksa
-}
+% an empty left hand side is indexed in the index pseudonamespace and not in the main
+% parser namespace, since the name parser never encounters this term (as the \emptyterm
+% control sequence is inserted by the main parser) while typesetting productions;
+% because of this it would be unnatural to define a \prettywordpair sequence for it in the main
+% parser namespace; using a special non-\bison\ name should avoid any confusion with
+% the regular grammar terms
+\def\emptyterm{\appendr\table{$\nx\circ$\tidxentry{\termexception}{emptyrhs&}}}
\def\termnameidit#1#2#3#4{%
\yyreadfifot\yyformat\to#3\in\yyformatlocal\with\formatsort\relax
\the\yyformatlocal
- \nameproc{#2}%
- \peekstash{#4}%
- \settermstyle{#1}%
+ \nameproc{#2}\with\parsebin
+ \peekstash{#4}% does not clobber \toksa and \toksb
+ \expandafter\settermstyle\expandafter{\the\toksb}{#1}%
}
-\def\settermstyle#1{%
- \edef\next{\toksa{\termmetastyle{%
- \gidxentry{\termidstring}{#1}%
- \let\nx\idxfont\nx\empty\nx\it\the\toksa\nx\/%
- }}}\next
-}
-
-\def\idxinline#1{% index the term in text
- \edef\next{\tidxentry{\termidstring}{#1}}\next
+\def\settermstyle#1#2{% put the \whatsit node (\write) at the end so that the
+ % term macros can remove the whitespace preceeding it
+ \edef\next{%
+ \toksa{%
+ \termmetastyle{%
+ \let\nx\idxfont\nx\empty\nx\it\the\toksa
+ \gidxentry{\termidstring}{#2}{#1}\nx\/%
+ }%
+ }%
+ }\next
}
\def\termnamestringify#1#2#3#4{%
- \nameproc{#2}%
+ \nameproc{#2}\with\parsebin
+ \ifyyparsefail
+ \toksb{"#1"}\toksc{\termstring}%
+ \else
+ \toksc{\termidstring}%
+ \fi
\edef\next{\toksa{{%
- \gidxentry{\termstring}{#1}%
+ \expandafter\gidxentryxv\expandafter{\the\toksc}{#1}{\the\toksb}%
\ntt\the\toksa
}}}\next
}
@@ -418,31 +641,39 @@
\newif\ifinheader
\def\prodhdridit#1#2#3#4{%
- \setrulecontext{}%
- \nameproc{#2}%
- \expandafter\setrulecontext\expandafter{\the\toksc}%
+ \setrulecontext{}% TODO: ?
+ \nameproc{#2}\with\parsebin
+ \setrulecontext{#1}%
\edef\next{\toksa{{%
- \gidxentry{\termhdrstring}{#1}%
+ \gidxentryxv{\termidstring}{#1}{\the\toksb}%
\nx\inheadertrue\let\nx\idxfont\nx\bf\nx\itbold\the\toksa\nx\/%
}}}\next
}
\def\charit#1#2#3#4{%
- \expandafter\ifx\csname'parser'\hostparsernamespace#1\endcsname\relax
- \edef\next{\toksa{{\ntt #1}\gidxentry{\termvstring}{'#1'}}}%
+ \expandafter\ifx\csname\prettynamecs\hostparsernamespace{#1}\endcsname\relax
+ \toksa{#1}\sansfirst\toksa
+ \edef\next{\toksa{{\ntt\the\toksa}\gidxentryxb{\termvstring}{\the\toksa}{}}}% remove the possible \\
\else
+ \expandafter\ifx\csname\viskeyref\hostparsernamespace{#1}\endcsname\relax
+ \tokse{#1}% we are stripping the quotes so the visible key is adjusted
+ \else
+ \edef\next{\tokse{\expandafter\expandafter\csname\viskeyref
+ \hostparsernamespace{#1}\endcsname\expandafter{\currentrulecontext}}}\next
+ \fi
\edef\next{\expandafter\toksa\expandafter{\expandafter\noexpand
- \csname'parser'\hostparsernamespace#1\endcsname{\currentrulecontext}\gidxentry{\termvstring}{'#1'}}}%
+ %\csname\prettynamecs\hostparsernamespace{#1}\endcsname{\currentrulecontext}\gidxentryxv{\termvstring}{'#1'}{\the\tokse}}}%
+ \csname\prettynamecs\hostparsernamespace{#1}\endcsname{\currentrulecontext}\gidxentryxv{\termidstring}{'#1'}{\the\tokse}}}%
\fi
\next
}
\def\anint#1#2#3{%
- \toksa{#1}\concat\table\toksa
+ \appendrnx\table{#1}%
}
\def\hexint#1#2#3{%
- \toksa\expandafter{\eattwo#1$_{16}$}\concat\table\toksa
+ \expandafter\appendrnx\expandafter\table\expandafter{\eattwo#1$_{16}$}%
}
\def\optoptsepnone{%
@@ -451,22 +682,22 @@
\def\optoptsepsmall{% keep the alignment going but insert a small space
\concat\opttable\postoks
- \toksa{\noalign{\smallskip}}\concat\opttable\toksa
+ \appendrnx\opttable{\noalign{\smallskip}}%
}
\def\prodprodsepsmall{%
\pushothertables
- \toksa{\noalign{\penalty-150 \smallskip}}\concat\table\toksa
+ \appendrnx\table{\noalign{\penalty-150 \smallskip}}%
}
\def\prodprodsep{%
\pushothertables
- \toksa{\noalign{\medskip}}\concat\table\toksa
+ \appendrnx\table{\noalign{\medskip}}%
}
\def\prodprodseplarge{%
\pushothertables
- \toksa{\noalign{\bigskip}}\concat\table\toksa
+ \appendrnx\table{\noalign{\bigskip}}%
}
\def\separatorswitcheq{%
@@ -532,28 +763,22 @@
\def\posmark#1#2{%
% \yyreadfifo\yyformat\to#1\in\yyformatlocal
-% no formattig for locations currently
- \restorecs{table-render}{\strm}%
+% no formatting for locations currently
% \the\yyformatlocal
\posm@rk{#2}%
}
\def\posm@rk#1{%
- \yyreadfifo\yystash\to#1\in\yystashlocal
- \edef\next{\the\yystashlocal}%
- \ifx\next\empty
- \postoks{}%
- \else
- \unmathstash{#1}%
- % TODO: move this out
- \toksa{}\the\yystashlocal\cleanstash\stripstash
+ \readstash{#1}%
+ \yytoksempty\yystashlocal{\postoks{}}{%
+ \toksa\expandafter{\the\yystashlocal}\cleanstash\stripstash
\setbox\z@=\vbox{\setlazyc\the\toksa}%
\ifnum\ht\z@=\z@
\postoks{}%
\else
- \edef\next{\postoks{\noalign{\indent\toksa{}\the\yystashlocal\nx\makestashbox}}}\next
+ \edef\next{\postoks{\noalign{\indent\toksa{\the\yystashlocal}\nx\makestashbox}}}\next
\fi
- \fi
+ }%
}
\def\codeoptionlist{%
@@ -608,29 +833,13 @@
\def\pushothertables{%
%token's
- \edef\next{\the\tokdectoks}%
- \ifx\next\empty
- \else
- \attachtokentable
- \fi
+ \yytoksempty\tokdectoks{}{\attachtokentable}%
%type's
- \edef\next{\the\typestable}%
- \ifx\next\empty
- \else
- \attachtypestable
- \fi
+ \yytoksempty\typestable{}{\attachtypestable}%
%precedence's
- \edef\next{\the\prectable}%
- \ifx\next\empty
- \else
- \attachprectable
- \fi
+ \yytoksempty\prectable{}{\attachprectable}%
% options
- \edef\next{\the\opttable}%
- \ifx\next\empty
- \else
- \attachoptionstable
- \fi
+ \yytoksempty\opttable{}{\attachoptionstable}%
\concat\table\postoks
} %
@@ -643,8 +852,7 @@
\savecslist{local-namespace}{\yyunion\termindex}%
\restorecslist{table-render:token-declarations}\yyunion
\let\termindex\writetokenidxentry
- \displaytokenrawtrue
- \let\currenttokentype\empty#1%
+ \let\currenttokentype\empty#1%
\restorecslist{local-namespace}{\yyunion\termindex}%
}
@@ -652,31 +860,29 @@
\savecslist{local-namespace}{\yyunion\termindex}%
\restorecslist{table-render:type-declarations}\yyunion
\let\termindex\writetokenidxentry
- \typesset{}%
- #2\relax#1%
- \edef\next{\typestable{\the\typestable\nx\onetype{\the\toksa}{\the\typesset}}}\next
+ \typesset{}#2\relax#1%
+ \appendr\typestable{\nx\onetype{\the\toksa}{\the\typesset}}%
\restorecslist{local-namespace}{\yyunion\termindex}%
}
% \onetype is a typeseting macro defined elsewhere
+% TODO: move these to the \flex\ section
\def\flexsstatedecls#1#2#3{%
\savecslist{local-namespace}{\yyunion\termindex}%
\restorecslist{table-render:flex-state-declarations}\yyunion
- \let\termindex\writetokenidxentry
- \typesset{}%
- #1\relax
- \edef\next{\typestable{\the\typestable\nx\flexsstatelist{\the\typesset}}}\next
+ \let\termindex\writeidxfsdentry%\writetokenidxentry
+ \typesset{}#1\relax
+ \appendr\typestable{\nx\flexsstatelist{\the\typesset}}%
\restorecslist{local-namespace}{\yyunion\termindex}%
}
\def\flexxstatedecls#1#2#3{%
\savecslist{local-namespace}{\yyunion\termindex}%
\restorecslist{table-render:flex-state-declarations}\yyunion
- \let\termindex\writetokenidxentry
- \typesset{}%
- #1\relax
- \edef\next{\typestable{\the\typestable\nx\flexxstatelist{\the\typesset}}}\next
+ \let\termindex\writeidxfsdentry%\writetokenidxentry
+ \typesset{}#1\relax
+ \appendr\typestable{\nx\flexxstatelist{\the\typesset}}%
\restorecslist{local-namespace}{\yyunion\termindex}%
}
@@ -685,9 +891,8 @@
\def\flexoptiondecls#1#2#3{%
\savecslist{local-namespace}{\yyunion\termindex}%
\restorecslist{table-render:flex-option-definitions}\yyunion
- \let\termindex\writetokenidxentry
- \toksa{}%
- #1\relax
+ \let\termindex\writeidxfsrnentry%\writetokenidxentry
+ \toksa{}#1\relax
\restorecslist{local-namespace}{\yyunion\termindex}%
}
@@ -700,8 +905,8 @@
\restorecslist{table-render:prec-declarations}\yyunion
\setrulecontext{*#1}%
\let\termindex\writetokenidxentry
- \typesset{}#3\toksa{}#2%
- \edef\next{\prectable{\the\prectable\noexpand\oneprec{#1}{\the\toksa}{\the\typesset}}}\next
+ \typesset{}#3\toksa{}#2%
+ \appendr\prectable{\nx\oneprec{#1}{\the\toksa}{\the\typesset}}%
\restorecslist{local-namespace}{\yyunion\termindex}%
\setrulecontext{}%
}
@@ -712,52 +917,45 @@
\def\oneparametricoption#1#2#3#4{%
\restorecs{table-render:token-declarations}{\braceit\stringify\idit\anint\hexint}%
- \toksa{}\toksb{}\toksc{}%
- #2%
- \edef\next{\noexpand\oneparametricopti@n{#1}{\the\toksa}{\the\toksb}{\the\toksc}}\next
+ \toksa{}\toksb{}\toksc{}#2%
+ \edef\next{\nx\oneparametricopti@n{#1}{\the\toksa}{\the\toksb}{\the\toksc}}\next
}
\def\oneparametricopti@n#1#2#3#4{%
- \edef\next{#2}%
- \ifx\next\empty % there is no identifier
- \def\next{#4}%
- \ifx\next\empty % there is no digit
+ \yystringempty{#2}{% there is no identifier
+ \yystringempty{#4}{% there is no digit
\edef\next{\toksa{{\ntt"\the\toksb"}}}\next
- \else
+ }{%
\edef\next{\toksa{{\nx\rm\the\toksc}}}\next
- \fi
- \else
- \nameproc{#2}%
- \fi % now \toksa contains the value of the parameter
+ }%
+ }{%
+ \nameproc{#2}\with\parsebin
+ }% now \toksa contains the value of the parameter
\toksb{#1}%
\let\termindex\writetokenidxentry
- \edef\next{\toksa{\gidxentry{\termostring}{#1}$\nx\langle${\nx\bf\the\toksb}$\nx\rangle$&\the\toksa\nx\/\nx\cr}}\next
+ \appendr\opttable{\gidxentry{\termostring}{#1}{}$\nx\langle${\nx\bf\the\toksb}$\nx\rangle$&\the\toksa\nx\/\nx\cr}%
\let\termindex\eatone
- \concat\opttable\toksa
}
\def\paramdef#1#2#3#4{%
\restorecs{table-render:token-declarations}\braceit
\let\termindex\writetokenidxentry
- \edef\next{\toksa{\gidxentry{\termostring}{#2}}}\next
- \toksb\expandafter{\the\toksa$\langle${\bf #2}$\rangle$}\toksa{}%
- #1%
+ \appendr\opttable{\gidxentry{\termostring}{#2}{}}%
\let\termindex\eatone
- \concat\toksb\toksa
- \concat\opttable\toksb
+ \appendrnx\opttable{$\langle${\bf #2}$\rangle$}%
+ \toksa{}#1%
+ \concat\opttable\toksa
}
\def\optionflag#1#2#3#4{%
- \def\next{#2}%
- \ifx\next\empty
- \toksb{}%
- \else
- \toksb{ {\rm(set as $\langle${\bf#2}$\rangle$)}}%
- \fi
\let\termindex\writetokenidxentry
- \edef\next{\toksa{\gidxentry{\termostring}{#1}$\nx\langle${\nx\bf#1}$\nx\rangle$\nx\rlap{$\nx\,\star$}&\the\toksb\cr}}\next
+ \appendr\opttable{\gidxentry{\termostring}{#1}{}}%
\let\termindex\eatone
- \concat\opttable\toksa
+ \yystringempty{#2}{%
+ \appendrnx\opttable{$\langle${\bf#1}$\rangle$\rlap{$\,\star$}&\cr}%
+ }{%
+ \appendrnx\opttable{$\langle${\bf#1}$\rangle$\rlap{$\,\star$}& {\rm(set as $\langle${\bf#2}$\rangle$)}\cr}%
+ }%
}
\def\codepropstype#1#2#3#4#5#6#7{%
@@ -768,21 +966,18 @@
}
\def\codepropstyp@#1#2#3#4{%
- \yyreadfifo\yystash\to#4\in\yystashlocal
- \unmathstash{#4}%
+ \readstash{#4}%
\restorecs{table-render:type-declarations}{\idit\stringify\hspace}%
\let\termindex\writetokenidxentry
- \typesset{}%
- #2% collect all the symbols in \typesset
- \edef\next{\toksa{\gidxentry{\termostring}{#3}$\nx\langle${\nx\bf #3}$\nx\rangle$&%
- \toksa{}\the\yystashlocal\nx\makestashbox\nx\hfil\cr
- \noalign{\nx\smallskip}%
- \noalign{\indent$\nx\rlap{\hbox to2em{\nx\hfil$\nx\star$\nx\hfil}}\vcenter{
- \advance\hsize by-\parindent
- \emergencystretch10pt\nx\raggedright\noindent\hangafter\z@\hangindent2em\nx\strut\the\typesset\nx\strut}$}%
- }}\next
+ \typesset{}#2% collect all the symbols in \typesset
+ \appendr\opttable{\gidxentry{\termostring}{#3}{}$\nx\langle${\nx\bf #3}$\nx\rangle$&%
+ \toksa{\the\yystashlocal}\nx\makestashbox\nx\hfil\cr
+ \noalign{\nx\smallskip}%
+ \noalign{\indent$\nx\rlap{\hbox to2em{\nx\hfil$\nx\star$\nx\hfil}}\vcenter{
+ \advance\hsize by-\parindent
+ \emergencystretch10pt\nx\raggedright\noindent\hangafter\z@\hangindent2em\nx\strut\the\typesset\nx\strut}$}%
+ }%
\let\termindex\eatone
- \concat\opttable\toksa
}
\def\codeassoc#1#2#3#4#5#6#7{%
@@ -793,20 +988,15 @@
}
\def\codeass@c#1#2#3#4{%
- \yyreadfifo\yystash\to#4\in\yystashlocal
- \unmathstash{#4}%
+ \readstash{#4}%
\let\idit\termnameidit
\let\termindex\writetokenidxentry
- \toksa{}% in case #1 is empty
- #2% put the typeset form of the identifie in \toksa
- \toksb\toksa
- \edef\next{\toksa{\yystringempty{#1}{}{\gidxentry{\termostring}{#1}}%
- $\nx\langle${\nx\bf #1}$\nx\rangle$\nx\quad{\the\toksb}&%
- \toksa{}\the\yystashlocal
- \nx\makestashbox
- \nx\hfil\cr
- }}\next
- \concat\opttable\toksa
+ \toksa{}#2% put the typeset form of the identifier in \toksa
+ \appendr\opttable{%
+ \yystringempty{#1}{}{\gidxentry{\termostring}{#1}{}}%
+ $\nx\langle${\nx\bf #1}$\nx\rangle$\nx\quad{\the\toksa}&%
+ \toksa{\the\yystashlocal}\nx\makestashbox\nx\hfil\cr
+ }%
\let\termindex\eatone
}
@@ -821,35 +1011,29 @@
\let\idit\termnameidit
\let\stringify\termnamestringify
\let\termindex\writetokenidxentry
- #1% put the typeset form of the identifier or string in \toksa
- \toksb\toksa
- \savecslist{local-namespace}\yyunion
- \restorecslist{table-render:variable-definitions}\yyunion
- \toksa{}% in case #2 is empty
- #2% put the value in toksa
- \toksc\toksa
- \restorecslist{local-namespace}\yyunion
+ #1% put the typeset form of the identifier or string in \toksa
+ \toksb\toksa
+ \savecslist{local-namespace}\yyunion
+ \restorecslist{table-render:variable-definitions}\yyunion
+ \toksa{}#2% put the value in toksa
+ \toksc\toksa
+ \restorecslist{local-namespace}\yyunion
\let\termindex\eatone
- \edef\next{\toksa{$\nx\langle${\nx\bf define}$\nx\rangle$\nx\quad{\the\toksb}&%
- \the\toksc\cr
- }}\next
- \concat\opttable\toksa
+ \appendr\opttable{$\nx\langle${\nx\bf define}$\nx\rangle$\nx\quad{\the\toksb}&\the\toksc\cr}%
}
\def\prologuecode#1#2#3#4#5{% similar to \actbrac@s
- \yyreadfifo\yystash\to#5\in\yystashlocal
- \unmathstash{#5}%
- \restorecs{table-render}{\strm\stashed}%
- \toksa{}\the\yystashlocal
- \edef\next{\toksa{\omit\span\omit\nx\cdotfill\cr
- \omit\span\omit\toksa{\the\toksa}\nx\makestashbox\nx\cr
- \omit\span\omit\nx\cdotfill\cr}}\next
- \concat\opttable\toksa
+ \readstash{#5}%
+ \appendr\opttable{%
+ \omit\span\omit\nx\cdotfill\cr
+ \omit\span\omit\toksa{\the\yystashlocal}\nx\makestashbox\nx\cr
+ \omit\span\omit\nx\cdotfill\cr
+ }%
}
\def\yyunion@tablerender{%
- \strm\stashed\rarhss@p\rrhss@p\prodhead@r\hrhss@p\arhss@p\actbrac@s\hspac@\codepropstyp@\vard@f\stopproduction
- \termmetastyle\peekstash
+ \strm\stashed\rarhss@p\rrhss@p\prodhead@r\hrhss@p\arhss@p\termnam@\termn@m@\t@rmn@m@
+ \actbrac@s\hspac@\codepropstyp@\vard@f\termmetastyle\peekstash\stopproduction
}
\savecslist{table-render}\yyunion
@@ -868,10 +1052,16 @@
#1%
}
\let\formatlocal\format
+\let\formatbegin\format
+\let\formatp\format
\newtoks\yystashlastcontent % contents of the last action
\newif\ifshowlastaction % if true, show the last action of a flattened set of rules
+% flatten: omit the actions, just list all the rules in a single line;
+% if \showlastactiontrue show just the last action, otherwise display \actionfiller
+% instead
+
\def\flatten{%
\let\stopproduction\stopproduction@flatten
\let\actbrac@s\actbrac@s@flatten
@@ -881,45 +1071,44 @@
}
\def\actbrac@s@flatten#1#2#3{% do everything but add the stash contents to the table
- \yyreadfifo\yystash\to#3\in\yystashlocal
- \unmathstash{#3}%
- \yystashlastcontent\yystashlocal
+ \readstash{#3}%
+ \yystashlastcontent\yystashlocal % keep the contents of the braces
+ % in case we want to show the last action
\futurelet\actsep\actbrac@s@fl@tten
}
+% see the remarks before \emptyterm above for the reasons for choosing the index
+% pseudonamespace for this term
\def\actbrac@s@fl@tten{%
\ifx\actsep\arhssep
- \edef\next{%
- \toksa{$\nx\ \nx\diamond\nx\ $\tidxentry{\termidstring}{inline_action}}}\next
- \concat\table\toksa
+ \appendr\table{$\nx\ \nx\diamond\nx\ $\tidxentry{\termexception}{inline_action&}}%
\fi
}
\def\rrhss@p@flatten{%
- \toksa{$\ \vert\ $}\concat\table\toksa
+ \appendrnx\table{$\ \vert\ $}%
}%
\def\stopproduction@flatten{%
\ifshowlastaction
- \toksa\yystashlastcontent
+ \yystashlastcontent\expandafter{\expandafter\toksa\expandafter{\the\yystashlastcontent}}%
\else
- \toksa{\actionfiller}%
+ \yystashlastcontent{\actionfiller}%
\fi
- \toksa\expandafter{\expandafter&\expandafter&\the\toksa\cr}\concat\table\toksa
+ \appendr\table{&&\the\yystashlastcontent\nx\cr}%
}
+% fold: resume normal display
+
\def\fold{%
\restorecs{table-render}{\actbrac@s\rrhss@p\arhss@p\rarhss@p\stopproduction}%
- \ifshowlastaction
- \toksa\yystashlastcontent
- \else
- \toksa{\actionfiller}%
- \fi
- \toksa\expandafter{\expandafter&\expandafter&\the\toksa\cr}\concat\table\toksa
+ \stopproduction@flatten
}
\def\actionfiller{\omit\quad$\ldots$\hfil}
+% inline: put the left hand side of the production on the same line as the rule
+
\def\inline{%
\let\prodhead@r\prodhead@r@inline
\let\hrhss@p\hrhss@p@inline
@@ -928,10 +1117,10 @@
\def\prodhead@r@inline#1#2{%
\let\idit\prodhdridit
#1\relax
+ \concat\table\toksa
\setbox\z@=\hbox{\strut\the\toksa\/$\,$\rm:\quad}%
\tempda=\wd\z@\relax
\advance\tempda-2em
- \edef\next{\table{\the\table{\the\toksa}}}\next
\hrhss@p
}
@@ -940,18 +1129,45 @@
\def\termspostformat{\ifsquashterms\aftergroup\noexpand\squashtermstrue\fi}
\def\hrhss@p@inline{%
- \edef\next{\toksa{&\termspostformat\hbox to \the\tempda{\hss}}}\next\concat\table\toksa
+ \appendr\table{&\termspostformat\hbox to \the\tempda{\hss}}%
}
+% breakline: break the production line
+
\def\breakline{%
\let\hspac@\hspac@@breakline
}
\def\hspac@@breakline{%
- \toksa{{$\,\hookleftarrow$}&\omit\hfil&\omit\hfil\cr\omit\hfil&\hbox to 2em{\hfil}}\concat\table\toksa
+ \appendrnx\table{{$\,\hookleftarrow$}&\omit\hfil&\omit\hfil\cr\omit\hfil&\hbox to 2em{\hfil}}%
\restorecs{table-render}\hspac@
}
+% breakahead: break the production line after #1 terms
+% use: \breakahead{[0-9]+}
+
+\newcount\breakaheadcount
+
+\def\breakahead#1{%
+ \let\bahspac@\hspac@
+ \let\hspac@\hspac@@breakahead
+ \breakaheadcount#1\relax
+}
+
+\def\hspac@@breakahead{%
+ \ifnum\breakaheadcount=\@ne
+ \yybreak{%
+ \appendrnx\table{{$\,\hookleftarrow$}&\omit\hfil&\omit\hfil\cr\omit\hfil&\hbox to 2em{\hfil}}%
+ \let\hspac@\bahspac@
+ }%
+ \else
+ \advance\breakaheadcount by \m@ne
+ \yybreak{\bahspac@}%
+ \yycontinue
+}
+
+% skipheader: do not show the left hand side
+
\def\skipheader{%
\let\prodhead@r\prodhead@r@skipheader
\let\hrhss@p\hrhss@p@skipheader
@@ -961,34 +1177,85 @@
\hrhss@p
}
-\def\hrhss@p@skipheader{\toksa{\omit\hbox to 2em{\hfil}&\termspostformat}\concat\table\toksa\restorecs{table-render}{\hrhss@p}}
+\def\hrhss@p@skipheader{\appendrnx\table{\omit\hbox to 2em{\hfil}&\termspostformat}\restorecs{table-render}{\hrhss@p}}
\def\stashtoterm#1{% in case one needs to insert previous stash as a term
% usage: \let\peekstash\stashtoterm
- \yyreadfifo\yystash\to#1\in\yystashlocal
- \unmathstash{#1}%
- \edef\next{\toksb{{%
- \nx\restorecs{table-render}{\nx\stashed\nx\strm}%
- \toksa{}\the\yystashlocal\nx\makestashbox}}}\next
- \def\termmetastyle##1{\the\toksb}%
+ \readstash{#1}%
+ {\edef\next{\toksc{{\toksa{\the\yystashlocal}\nx\makestashbox}}}\expandafter}\next
+ \let\termmetastyle\xtoksc
\restorecs{table-render}\peekstash
}
+\def\xtoksc#1{\the\toksc}%
+
+% resetf: resume normal formatting
+
\def\resetf{%
\restorecs{table-render}{\prodheader\prodhead@r\hrhss@p\rrhss@p\arhss@p\rhs\termname\actbraces\actbrac@s\rarhss@p\hspac@\rules
\oneproduction\emptyterm\stringify\idit\charit\prodprodsep\onesymbol\strm\stopproduction}%
\squashtermsfalse
}
-\def\prodstyle#1{% to typeset token names in text
+\def\prodstyle#1{% to typeset token names in text;
+ % CAUTION: when many parsers are at play at the same time,
+ % one should use the version of this macro below that takes a
+ % namespace as a parameter, to make sure the term is typeset properly
+ % when another namespace might be in effect (such as when section names are output)
{%
\let\optstrextra\optstrextraesc
- \nameproc{#1}%
- \settermstyle{#1}%
+ \def\termidxrank{5}%
+ \let\termindex\writeidxentry
+ \nameproc{#1}\with\parsebin
+ \edef\next{%
+ \toksa{%
+ \termmetastyle{%
+ \let\nx\idxfont\nx\empty\nx\it\the\toksa
+ \expandafter\gidxentryxv\expandafter{\romannumeral
+ \ifyyparsefail
+ \yybreak{0 \termidstring}%
+ \else
+ \yybreak{\expandafter\tssextract\the\toksa\end}%
+ \yycontinue}{#1}{\the\toksb}\nx\/%
+ }%
+ }%
+ }\next
+ \let\_\uscore
\the\toksa\nobreak
}%
}
+\def\tssextract#1#2#3\end{%
+ \yystringempty{#2}{0 \termidstring}{0 #2}%
+}
+
+\def\prodtstyle#1{% to typeset terminal string names in text;
+ {%
+ \let\optstrextra\optstrextraesc
+ \def\termidxrank{5}%
+ \let\termindex\writeidxentry
+ \nameproc{#1}\with\parsebin
+ \yytoksempty\toksb{\toksb{"#1"}}{}%
+ \edef\next{%
+ \toksa{%
+ \termmetastyle{%
+ \let\nx\idxfont\nx\empty\ntt\the\toksa
+ \gidxentryxv{\termstring}{#1}{\the\toksb}%
+ }%
+ }%
+ }\next
+ \let\_\uscore
+ \the\toksa\nobreak
+ }%
+}
+
+\def\prodstylens#1#2{% to typeset token names in text, in a predefined namespace
+ {%
+ \def\hostparsernamespace{#2}%
+ \prodstyle{#1}%
+ }%
+}
+
% macros used in typesetting the result of the prologue parsing
%type declarations
@@ -1007,7 +1274,7 @@
}
\def\hspace#1#2{%
- \appendr\typesset{ }%
+ \appendrnx\typesset{ }%
}
\def\charit#1#2#3#4{%
@@ -1044,11 +1311,8 @@
}
\def\braceit#1#2#3{% similar to \actbrac@s
- \yyreadfifo\yystash\to#3\in\yystashlocal
- \unmathstash{#3}%
- \restorecs{table-render}{\strm\stashed}%
- \toksa{}\the\yystashlocal
- \edef\next{\toksa{&\toksa{\the\toksa}\nx\makestashbox\nx\cr}}\next
+ \readstash{#3}%
+ \edef\next{\toksa{&\toksa{\the\yystashlocal}\nx\makestashbox\nx\cr}}\next
}
\def\onesymbol#1#2#3{% #1 is the macro name used internally by bison (\idit{}{}{}{})
@@ -1056,42 +1320,42 @@
% #3 is the string value (\stringify{}{}{}{})
\toksa{}\toksb{}\toksc{}%
#1#2#3\relax
- \edef\next{\noexpand\onesymb@l{\the\toksa}{\the\toksc}{\the\toksb}}\next
+ \edef\next{\nx\onesymb@l{\the\toksa}{\the\toksc}{\the\toksb}}\next
}
\def\onesymb@l#1#2#3{% #1 is the macro name used internally by bison
% #2 is the integer value
% #3 is the string value
\let\optstrextra\optstrextraesc
- \yystringempty{#3}{}{\nameproc{#3}\tokstoks\toksa}%
- \yystringempty{#1}{}{\nameproc{#1}}%
- \iftracetokennames\derrmessage{token: \the\toksa, string: \the\tokstoks}\fi
+ \tokse{}\toksf{}\toksg{}% these registers will contain the appropriate visual keys
+ % and index entry processing control sequences
+ \yystringempty{#3}{}{%
+ \nameproc{#3}\with\parsebin
+ \ifyyparsefail % if the parsing failed, create a visible key, process the
+ % index entry as a \.{\\tt} string
+ \tokse{"#3"}\toksf{\termstring}%
+ \else % otherwise use the value of the string as the visual key,
+ % process the string as a \bison\ identifier
+ \tokse\toksb\toksf{\termidstring}%
+ \fi
+ \tokstoks\toksa
+ }%
+ \yystringempty{#1}{}{\nameproc{#1}\with\parsebin\toksg\toksb}%
+ \iftracetokennames\ferrmessage{token: \the\toksa, string: \the\tokstoks}\fi
\toksb\expandafter{\currenttokentype}%
- \edef\next{%
- \tokdectoks{\the\tokdectoks
- \noexpand\toksdefline
- {\the\toksa}%
- {%
- \yystringempty{#1}{}{\gidxentry{\termidstring}{#1}}%
- \yystringempty{#3}{}{\gidxentry{\termstring}{#3}}%
- }%
- {\yytoksempty\toksb{auto}{\the\toksb}}%
- {#2}%
- {\the\tokstoks}%
- }%
- }\next
+ \appendr\tokdectoks{\nx\toksdefline
+ {\the\toksa}%
+ {%
+ \yystringempty{#1}{}{\gidxentryxv{\termidstring}{#1}{\the\toksg}}%
+ \yystringempty{#3}{}{\expandafter\gidxentryxv\expandafter{\the\toksf}{#3}{\the\tokse}}%
+ }%
+ {\yytoksempty\toksb{auto}{\the\toksb}}%
+ {#2}%
+ {\the\tokstoks}%
+ }%
\restorecs{nameparser}{\optstrextra}%
}
-\def\defidxrank{0} % index rank of definitions
-
-\def\writetokenidxentry#1{\write\gindex{%
- \nx\nx
- \expandafter
- \nx
- \csname\bisonidxdomain TI\endcsname\defidxrank#1}%
-}
-
\toyyunion{table-render:token-declarations}
%precedence declarations
@@ -1109,29 +1373,35 @@
}
\def\charit#1#2#3#4{%
- \expandafter\ifx\csname'parser'\hostparsernamespace#1\endcsname\relax
- \edef\next{\toksa{{\ntt #1}\gidxentry{\termvstring}{'#1'}}}%
+ \expandafter\ifx\csname\prettynamecs\hostparsernamespace{#1}\endcsname\relax
+ \toksa{#1}\sansfirst\toksa
+ \edef\next{\toksa{{\ntt\the\toksa}\gidxentryxb{\termvstring}{\the\toksa}{}}}% remove the possible \\
\else
+ \expandafter\ifx\csname\viskeyref\hostparsernamespace{#1}\endcsname\relax
+ \tokse{#1}%
+ \else
+ \edef\next{\tokse{\expandafter\expandafter\csname\viskeyref
+ \hostparsernamespace{#1}\endcsname\expandafter{\currentrulecontext}}}\next
+ \fi
\edef\next{\expandafter\toksa\expandafter{\expandafter\noexpand
- \csname'parser'\hostparsernamespace#1\endcsname{\currentrulecontext}\gidxentry{\termvstring}{'#1'}}}%
+ %\csname\prettynamecs\hostparsernamespace{#1}\endcsname{\currentrulecontext}\gidxentryxv{\termvstring}{'#1'}{\the\tokse}}}%
+ \csname\prettynamecs\hostparsernamespace{#1}\endcsname{\currentrulecontext}\gidxentryxv{\termidstring}{'#1'}{\the\tokse}}}%
\fi
\next
\concat\typesset\toksa
}
\def\anint#1#2#3{%
- \edef\next{\toksa{${}=\hbox{\ntt#1}$}}\next
- \concat\typesset\toksa
+ \appendrnx\typesset{${}=\hbox{\ntt#1}$}%
}
\def\hexint#1#2#3{%
\toksa\expandafter{\eattwo#1}%
- \edef\next{\toksa{${}=\hbox{\ntt\the\toksa}_{16}$}}\next
- \concat\typesset\toksa
+ \appendr\typesset{${}=\hbox{\ntt\the\toksa}_{16}$}%
}
\def\hspace#1#2{%
- \appendr\typesset{ }%
+ \appendrnx\typesset{ }%
}
\def\tagit#1#2#3#4{%
@@ -1153,11 +1423,8 @@
\def\stringify#1#2#3#4{\toksa{#2}}
\def\bracedvalue#1#2#3{% similar to \actbrac@s
- \yyreadfifo\yystash\to#3\in\yystashlocal
- \unmathstash{#3}%
- \restorecs{table-render}{\strm\stashed}%
- \toksa{}\the\yystashlocal
- \edef\next{\toksa{\toksa{\the\toksa}\nx\makestashbox}}\next
+ \readstash{#3}%
+ \edef\next{\toksa{\toksa{\the\yystashlocal}\nx\makestashbox}}\next
}
\toyyunion{table-render:variable-definitions}
@@ -1193,12 +1460,11 @@
\restorecslist{parser-strict}\yyunion
\def\idit#1#2#3#4{%
- \nameproc{#2}%
- \edef\next{\toksa{{%
- \gidxentry{\termttstring}{#1}%
+ \nameproc{#2}\with\parsebin
+ \appendr\typesset{{%
+ \gidxentryxv{\termttstring}{#1}{\the\toksb}%
\ntt\the\toksa
- }}}\next
- \concat\typesset\toksa
+ }}%
}
\def\hspace#1#2{%
@@ -1213,17 +1479,21 @@
\def\flexoptionpair#1#2{%
#1%
- \edef\next{#2}%
- \ifx\next\empty % there is no rihgt hand side
- \edef\next{\toksa{$\nx\langle${\ntt\the\toksa}$\nx\rangle_{\rm f}\,\star$&\cr}}\next
- \else
+ \yystringempty{#2}{% there is no right hand side
+ \appendr\opttable{$\nx\langle${\ntt\the\toksa}$\nx\rangle_{\rm f}\,\star$&\cr}%
+ }{%
\toksb\toksa\toksa{}#2%
- \edef\next{\toksa{$\nx\langle${\ntt\the\toksb}$\nx\rangle_{\rm f}$&\nx\it\the\toksa\nx\/\nx\cr}}\next
- \fi
- \concat\opttable\toksa
+ \appendr\opttable{$\nx\langle${\ntt\the\toksb}$\nx\rangle_{\rm f}$&\nx\it\the\toksa\nx\/\nx\cr}%
+ }%
}
-\def\idit#1#2#3#4{\toksa{#2}}
+\def\idit#1#2#3#4{%
+ \toksa{#2}%
+ \edef\next{\toksa{{%
+ \gidxentry{\termfsopstring}{#2}{}%
+ \ntt\the\toksa
+ }}}\next
+}
\def\stringify#1#2#3#4{\toksa{{\ntt@"#2"}}}
@@ -1244,10 +1514,13 @@
\edef\next{\toksc{\numname:}\toksd{\noexpand\lhs{\the\lastlastname}{\the\lastname}}}\next
}
-\def\rrhssep#1#2{}
-\def\arhssep#1#2{}
-\def\rarhssep#1#2{}
-\def\hspace#1#2{}
+% the macros below are defined in `parser-prototypes'
+%\def\rrhssep#1#2{}
+%\def\arhssep#1#2{}
+%\def\rarhssep#1#2{}
+%\def\hspace#1#2{}
+%\def\prodprodsep{}
+%\def\onesymbol#1#2#3{}
\def\rhs#1#2#3{%
\concat\toksa\toksc
@@ -1317,10 +1590,6 @@
\lastname{'#1'}%
}
-\def\prodprodsep{}
-
-\def\onesymbol#1#2#3{}
-
\def\anint#1#2#3{%
\lastname{#1}%
}
@@ -1342,119 +1611,72 @@
\savecslist{symbols}\yyunion
-% name parser macros
+%% token typesetting macros
-\def\idstr#1#2{%
- \toksb{#1}%
- \concat\toksa\toksb
- \toksb{#2}%
- \concat\toksc\toksb
-}
+\def\prettynamecs#1#2{'parser'#1#2} % naming convention for token typesetting alternatives
-\def\chstr#1#2{%
- \toksb{{\ntt@#1}}%
- \concat\toksa\toksb
- \toksb{#2}%
- \concat\toksc\toksb
+\def\setsafe#1{\def\saferword{#1}\setspecialcharsfrom\saferword}
+\def\prettyword#1{\setsafe{#1}\expandafter\edef\csname\prettynamecs\parsernamespace\saferword\endcsname##1{{\ntt\lowercase{\saferword}}}}
+\def\prettytoken#1{\setsafe{#1}\expandafter\edef\csname\prettynamecs\parsernamespace\saferword\endcsname##1{{\ntt\saferword}}}
+\def\prettytoken@#1{\toksa{}\numberstocharsandspaces#1\end\expandafter\edef
+ \csname\prettynamecs\parsernamespace{\the\toksa}\endcsname##1{{\ntt\the\toksa}}%
}
-\def\sfxi#1#2{\toksb{\/${}_{\idxfont#1}$}\concat\toksa\toksb}
-
-\def\sfxn#1#2{\toksb{#1}\concat\toksa\toksb}
+\def\prettywordpair@@#1#2{\setsafe{#1}\expandafter\def\csname\prettynamecs\parsernamespace\saferword\endcsname##1{#2}}
-\def\dotsp{\futurelet\next\d@tsp}
+\def\prettywordpair#1#2{\prettywordpair@@{#1}{{\ntt@#2}}}
-\def\d@tsp{%
- \ifx\next\sfxi
- \else
- \ifx\next\qual
- \else
- \toksb{.}\concat\toksa\toksb
- \fi
- \fi
+\def\prettywordpair@#1#2{% a `weak symbol' version of the above macro, so that the new typesetting can be overriden
+ \setsafe{#1}\toksa{}\numberstocharsandspaces#2\end\expandafter\nameproc\expandafter{\the\toksa}\with\parsebin
+ \expandafter\edef\csname\prettynamecs\parsernamespace\saferword\endcsname##1{%
+ \noexpand\ifdisplaytokenraw
+ {\ntt\saferword}% \ntt expands to \noexpand\ntt@
+ \noexpand\else
+ {\ntt\def\noexpand\_{\char`\noexpand\_}\the\toksa}%
+ \noexpand\fi
+ }%
}
-\def\optstr#1#2{%
- \toksb\expandafter{\eatone#1}%
- \optstrextra
- \concat\toksa\toksb
- \toksb{#2}%
- \concat\toksc\toksb
+\def\prettywordpairwvis#1#2#3{%
+ \prettywordpair{#1}{#2}%
+ \expandafter\def\csname\viskeyref\parsernamespace{\saferword}\endcsname##1{#3}%
}
-\def\optstrextra{%
- \edef\next{\toksb{{$\nx\ulcorner$\ntt\the\toksb$\nx\urcorner$}}}\next
+\def\prettywordpair@wvis#1#2#3{%
+ \prettywordpair@{#1}{#2}%
+ \expandafter\def\csname\viskeyref\parsernamespace{\saferword}\endcsname##1{#3}%
}
-\def\optstrextraesc{%
- \edef\next{\toksb{{$\nx\langle$\ntt\the\toksb$\nx\rangle$}}}\next
+\def\prettywordpair@@wvis#1#2#3{%
+ \prettywordpair@@{#1}{#2}%
+ \expandafter\def\csname\viskeyref\parsernamespace{\saferword}\endcsname##1{#3}%
}
-\def\qual#1#2{\toksb{\/${}_{\rm#2}$}\concat\toksd\toksb}
-
-\let\idxfont\relax
-
-\savecs{nameparser}{\idstr\chstr\sfxi\sfxn\qual\optstr\dotsp\optstringextra\idxfont}
+% a control sequence to reuse the token definition file for typesetting
-\newtoks\namechars
+\newif\iftraceprettytokens % display prettyfying control sequences
-\newif\iftracebadnames
-\newif\iftracenames
-
-\def\nameproc#1{%
- \ifbootstrapmode
- \toksa{}%
+\def\tokeneqpretty#1#2{%
+ \setsafe{#1}\toksa{}\numberstocharsandspaces#2\end
+ \expandafter\nameproc\expandafter{\the\toksa}\with\parsebin
+ \ifyyparsefail
+ \toksc{{}$_{\rm m}${}}\toksd\toksa
\else
- \savecs{local-namespace}\getcurrentparser
- \tosmallparser
- \basicparserinit
- \yyparse#1\yyeof\yyeof\endparseinput\endparse
- \ifyyparsefail
- \iftracebadnames
- \ferrmessage{bad name: #1}%
- \fi
- \toksa{#1}\toksc{}%
- \else
- \toksa{}\toksb{}\toksc{}\toksd{}%
- \iftracenames
- \ferrmessage{parsed name: \the\namechars}%
- \fi
- \the\namechars\relax
- \iftracenames
- \ferrmessage{processed name: \the\toksa<identifier>, \the\toksb<suffices>, \the\toksc<hash name>, \the\toksd<options>}%
- \fi
- \expandafter\ifx\csname'parser'\hostparsernamespace\the\toksc \endcsname\relax
- \else
- \toksa\expandafter{\csname'parser'\hostparsernamespace\the\toksc \endcsname}%
- \appendr\toksa{{\currentrulecontext}}%
- \fi
- \concat\toksa\toksd
- \fi
- \restorecs{local-namespace}\getcurrentparser
- \getcurrentparser
+ \toksc{}\toksd\toksb % quotes should trigger the creation of a visible key
\fi
-}
-
-%% token typesetting macros
-
-\def\setsafe#1{\def\saferword{#1}\setspecialcharsfrom\saferword}
-\def\prettyword#1{\setsafe{#1}\expandafter\edef\csname'parser'\parsernamespace\saferword\endcsname##1{{\ntt\lowercase{\saferword}}}}
-\def\prettytoken#1{\setsafe{#1}\expandafter\edef\csname'parser'\parsernamespace\saferword\endcsname##1{{\ntt\saferword}}}
-\def\prettytoken@#1{\toksa{}\numberstocharsandspaces#1\end\expandafter\edef
- \csname'parser'\parsernamespace\the\toksa\endcsname##1{{\ntt\the\toksa}}%
-}
-\def\prettywordpair#1#2{\setsafe{#1}\expandafter\def\csname'parser'\parsernamespace\saferword\endcsname##1{{\ntt@#2}}}
-\def\prettywordpair@#1#2{%
- \setsafe{#1}\toksa{}\numberstocharsandspaces#2\end\expandafter\nameproc\expandafter{\the\toksa}%
- \expandafter\edef\csname'parser'\parsernamespace\saferword\endcsname##1{%
+ \expandafter\edef\csname\prettynamecs\parsernamespace\saferword\endcsname##1{%
\noexpand\ifdisplaytokenraw
{\ntt\saferword}%
\noexpand\else
- {\ntt\def\noexpand\_{\char`\noexpand\_}\the\toksa}%
+ {\ntt\def\noexpand\_{\char`\noexpand\_}\the\toksa\the\toksc}%
\noexpand\fi
}%
+ \expandafter\edef\csname\viskeyref\parsernamespace{\saferword}\endcsname##1{\the\toksd}%
+ \iftraceprettytokens
+ \message{token: \expandafter\meaning\csname\prettynamecs\parsernamespace\saferword\endcsname}%
+ \message{visual key: \expandafter\meaning\csname\viskeyref\parsernamespace{\saferword}\endcsname}%
+ \fi
}
-\def\prettywordpair@@#1#2{\setsafe{#1}\expandafter\def\csname'parser'\parsernamespace\saferword\endcsname##1{{#2}}}
% the bootstrap macros
@@ -1471,7 +1693,7 @@
\def\idit#1#2#3#4{\toksb{#1}}
%\def\anint#1#2#3{\toksc{#1}}% this definition is not needed as all
- %information is extracted from yytname
+ % the information is extracted from yytname
% note that the definitions below do not handle cases such as
%token '{' "left brace" since the lexer knows how to return '{'
@@ -1509,15 +1731,923 @@
\savecslist{bootstrap:flex-state-declarations}\yyunion
-\def\charstonumberse#1\end{%
- \yystringempty{#1}{}%
- {\yystartsinspace{#1}{{\number`\ }\charstonumber@@#1\end}{\charstonumbers@#1\end}}%
+% correct a few macros for debugging
+
+\restorecslist{parser-debug}\yyunion
+
+\defc\actbraces{% action braces :: \actbraces{tex_string}{\idit|<nothing>}{fptr}{sptr}directive*\bdend
+ \noexpand\actbraces{#1}{#2}{#3}{#4}#5\noexpand\bdend
+}
+
+\defc\bpredicate{% predicate :: \bpredicate{tex_string}{<nothing>}{fptr}{sptr}directive*\bdend
+ \noexpand\bpredicate{#1}{}{#3}{#4}#5\noexpand\bdend
+}
+
+\defc\rhs{% a `right-hand side' :: \rhs{[\termname\hspace\rarhssep\arhssep\actbraces]+}{\arhssep|<nothing>}{\ifrhsfull}
+ \noexpand\rhs{#1}{#2}{}% omit setting the conditional
+}
+
+\toyyunion{parser-debug}
+
+% \romannumeral-expandable macros for character translation
+
+\def\charstonumbersre#1\end{\charstonumbersr@0\end#1\end}
+
+\def\charstonumbersr@#1\end#2\end{%
+ \yystringempty{#2}{#1}%
+ {\yystartsinspace{#2}{\expandafter\charstonumbers@@swap\expandafter{\number`\ }{#1}#2\end}{\charstonumb@rsr@#1\end#2\end}}%
}
-\def\charstonumbers@#1{%
- {\number`#1}\charstonumberse
+\def\charstonumb@rsr@#1\end#2{%
+ \expandafter\charstonumbersr@swap\expandafter{\number`#2}{#1}%
}
-\def\charstonumber@@#1 {\charstonumberse}
+\def\charstonumbersr@swap#1#2{\charstonumbersr@#2{#1}\end}
+
+\def\charstonumbers@@swap#1#2 {\charstonumbersr@#2{#1}\end}
+
+% variations: set \toksa to the expansion, \edef-expandable version
+
+\def\charstonumbers#1\end{\toksa\expandafter{\romannumeral\charstonumbersre#1\end}}
+\def\charstonumberse#1\end{\romannumeral\charstonumbersre#1\end}
+
+% name parser macros: currently only one suffix is handled, the very last one
+
+\def\yyuniontag{\yynpunion}
+\def\parserstrictnamespace{nameparser-strict}
+\def\parserprototypesnamespace{nameparser-strict:headers}
+\def\parserdebugnamespace{nameparser-debug}
+
+\def\yynpunion{\currentyyunionnamespace}
+
+\defp\idstr#1#2{} % idenifier ::
+\defp\bidstr#1#2{} % bison variable ::
+\defp\chstr#1#2{} % character ::
+\defp\sfxi#1#2{} % literal suffix ::
+\defp\sfxn#1#2{} % integer suffix ::
+\defp\dotsp{} % suffix separator ::
+\defp\optstr#1#2{} % option ::
+\defp\qual#1#2{} % qualifier ::
+\defp\visflag#1#2{} % visible key change flag ::
+
+\toyyunion{nameparser-prototypes}
+
+\defc\idstr{%
+ \appendrnx\toksa{#1}%
+ \appendrnx\toksc{#2}%
+ \toksb{}%
+}
+
+\defc\bidstr{%
+ \appendrnx\toksa{{}$\Upsilon${}}%
+ \appendrnx\toksc{#2}%
+ \toksb{}%
+}
+
+\defc\chstr{%
+ \appendrnx\toksa{{\ntt@#1}}%
+ \appendrnx\toksc{#2}%
+ \toksb{}%
+}
+
+% the \toksb, set in the next two macros is used by \optstr later
+
+\defc\sfxi{\toksb{\/${}_{\idxfont#1}$}\appendrnx\toksa{\/${}_{\idxfont#1}$}}
+
+\defc\sfxn{\toksb{#1}\appendrnx\toksa{#1}}
+
+\defc\dotsp{\futurelet\next\d@tsp}
+
+\def\d@tsp{%
+ \ifx\next\sfxi
+ \else
+ \ifx\next\qual
+ \else
+ \appendrnx\toksa{.}%
+ \fi
+ \fi
+}
+
+\defc\optstr{%
+ \toksb\expandafter{\eatone#1}%
+ \optstrextra
+ \concat\toksa\toksb
+ \appendrnx\toksc{#2}%
+ \toksb{}%
+}
+
+\def\optstrextra{%
+ \edef\next{\toksb{{$\nx\ulcorner$\ntt\the\toksb$\nx\urcorner$}}}\next
+}
+
+\def\optstrextraesc{%
+ \edef\next{\toksb{{$\nx\langle$\ntt\the\toksb$\nx\rangle$}}}\next
+}
+
+\defc\qual{\appendrnx\toksd{\/${}_{\rm#2}$}\toksb{}}
+
+\let\idxfont\relax
+
+\defc\visflag{\toksf{#1}\appendrnx\tokse{#1}}% flag visible key change
+ % \toksf contains the typesetting hint sequence
+
+\toyyunion{nameparser}
+
+\newtoks\namechars
+
+\newif\iftracebadnames
+\newif\iftracenames
+
+\def\viskeyref#1#2{% getting the possible visual key from the index key
+ % #1 is the namespace of the original key
+ % #2 is the key
+ \restorecsname{[nameparser:visual]}{.\prettynamecs{#1}{#2}}%
+}
+
+% ignore explicit (\ ) spaces while parsing names
+% the macro will be called whenever \tosmallparser is executed (see yyinit.sty);
+% this is neccessary due to a shortcut taken by the macros that display
+% \bison\ productions in text (see \beginprod macros in yyinit.sty).
+
+\def\ignoreexplicitspace{\yyinput}
+
+% the main name processing routine
+% does not have any side effects;
+% the parsed term is returned as #1 of the sequence in #2; #2 of #2 will hold a visual key if
+% one exists, otherwise it will be empty; #3 is \yyparsefailtrue or empty
+% #4 is the prettyfied version of the term if one exists; #5 is the typesetting hint from \visflag sequences;
+% the version below prettifies tokens only if the parsing was successful; if
+% needed, prettyfication may be applied after the parsing is complete
+
+\def\nameproc#1\with#2{%
+ {% keeping all changes local
+ \iftracenames
+ \toksa{#1}\ferrmessage{original name: \the\toksa}%
+ \fi
+ \tosmallparser\basicparserinit\d@parse{#1}%
+ \ifyyparsefail
+ \iftracebadnames
+ \toksa{#1}\ferrmessage{bad name: \the\toksa}%
+ \fi
+ \toksb{#2{#1}{}{\yyparsefailtrue}{}{}}%
+ \else
+ \npbuildnames{#2}%
+ \fi
+ \expandafter
+ }\the\toksb
+}
+
+\def\npbuildnames#1{%
+ \iftracenames
+ \ferrmessage{parsed name (namespace: \parsernamespace): \the\namechars}%
+ \fi
+ \toksa{}\toksb{}\toksc{}\toksd{}\tokse{}\toksf{}%
+ \restorecslist{nameparser}\yynpunion
+ \the\namechars\relax
+ \iftracenames
+ \ferrmessage{processed name: \the\toksa<identifier>, \the\toksb<suffices>, %
+ \the\toksc<hash name>, \the\toksd<options>, \the\tokse<visible key>}%
+ \fi
+ \expandafter\npsetkeys\expandafter{\the\toksc}%
+ \iftracenames
+ \ferrmessage{final name: \the\toksa\yytoksempty\toksc{}{, prettyfied name: \the\toksc}%
+ \yytoksempty\toksf{}{, hint: \the\toksf}%
+ \yytoksempty\tokse{}{, visual key: \the\tokse}, %
+ parsing \ifyyparsefail failed\else successful\fi
+ }%
+ \fi
+ \toksb{#1}%
+ \edef\next{%
+ \toksb{%
+ \the\toksb
+ {\the\toksa}% the parsed name
+ {\the\tokse}% the visual key
+ {}% parseflag
+ {\the\toksc}% the prettified name
+ {\the\toksf}% the typesetting hint
+ }%
+ }\next
+}
+
+\def\npsetkeys#1{%
+ \expandafter\ifx\csname\prettynamecs\hostparsernamespace{#1}\endcsname\relax
+ \toksc{}%
+ \else
+ \toksc\expandafter{\csname\prettynamecs\hostparsernamespace{#1}\endcsname}%
+ \appendr\toksc{{\currentrulecontext}\the\toksb\the\toksd}%
+ \toksf{\termidstring}%
+ \fi
+ \concat\toksa\toksd % changes \toksa and \toksc, no need for \toksb or \toksd after this
+ \expandafter\ifx\csname\viskeyref\hostparsernamespace{#1}\endcsname\relax
+ % no special visual key for this token
+ \yybreak{%
+ \yytoksempty\tokse{}{\makeviskeydirect}% if the visual key changed, output the key,
+ % attempt to compute it form the parsed output
+ }%
+ \else
+ \yybreak{\makeviskeyfrompretty{#1}}% modify the production of the visible key to use the
+ % prettified version
+ \yycontinue % changes \toksb, \toksd, and \tokse
+}
+
+% standard postprocessing function
+
+\def\parsebin#1#2#3#4#5{%
+ \yystringempty{#4}{%
+ \yystringempty{#3}{\toksa{\eatone{#5}#1}}{\toksa{#1}}%
+ }{%
+ \yystringempty{#3}{\toksa{\eatone{#5}#4}}{\toksa{#4}}%
+ }%
+ \toksb{#2}%
+ \yystringempty{#3}{\yyparsefailfalse}{\yyparsefailtrue}%
+}
+
+% creating a visual key from the stored visual key and the sufixes
+
+\restorecslist{nameparser-prototypes}\yynpunion % make most sequences do nothing
+
+\defc\qual{\toksb{#2}\concat\toksd\toksb}
+
+\toyyunion{nameparser:vispretty}
+
+\def\makeviskeyfrompretty#1{%
+ \edef\next{\tokse{\expandafter\expandafter\csname\viskeyref
+ \hostparsernamespace{#1}\endcsname\expandafter{\currentrulecontext}}}\next
+ \restorecslist{nameparser:vispretty}\yynpunion%
+ \toksd{}%
+ \the\namechars
+ \yytoksempty\toksd{}{\appendr\tokse.\concat\tokse\toksd}%
+}
+
+% creating a visual key directly from parsed output
+
+\restorecslist{nameparser-strict}\yynpunion
+
+\defc\idstr{\toksb{#2}\concat\tokse\toksb}
+
+\defc\bidstr{\toksb{#2}\concat\tokse\toksb}
+
+\defc\chstr{\toksb{#2}\concat\tokse\toksb}
+
+\defc\sfxi{\toksb{#2}\concat\tokse\toksb}
+
+\defc\sfxn{\toksb{#2}\concat\tokse\toksb}
+
+\defc\dotsp{\appendr\tokse.}
+
+\defc\optstr{\toksb{#2}\concat\tokse\toksb}
+
+\defc\qual{\toksb{#2}\concat\tokse\toksb}
+
+\defc\visflag{}
+
+\toyyunion{nameparser:visdirect}
+
+\def\makeviskeydirect{%
+ \tokse{}%
+ \restorecslist{nameparser:visdirect}\yynpunion
+ \the\namechars
+}
+
+\restorecslist{nameparser-strict}\yynpunion
+
+% \flex\ regex typesetting routine and \flex\ parser value stack types
+
+\def\frexproc#1\with#2{%
+ {% keeping all changes local
+ \iftracenames
+ \toksa{#1}\ferrmessage{original regex: \the\toksa}%
+ \fi
+ \toflexreparser
+ \basicparserinit
+ \flexreparserinit
+ \flexreparserdatainit
+ \d@parse{\ #1}% the parsed regex is put in the \table register
+ \ifyyparsefail
+ \iftracebadnames
+ \toksa{#1}\ferrmessage{bad regex: \the\toksa}%
+ \fi
+ \toksb{#2{#1}{}{\yyparsefailtrue}}%
+ \else
+ \toksd{#1}%
+ \frebuildx{#2}%
+ \fi
+ \expandafter
+ }\the\toksb
+}
+
+\def\frebuildx#1{%
+ \toksb{#1}\toksc{}%
+ \restorecslist{flexparser-re}\yyflunion
+ \the\table % typeset the regex (appears in \toksc)
+ \edef\next{%
+ \toksb{%
+ \the\toksb % the name of the processing routine
+ {\the\toksd}% the original regex
+ {\the\toksc}% processed regex (or empty)
+ {}% parse flag
+ }%
+ }\next
+}
+
+\def\ppregex#1#2#3{%
+ \toksc{#2}%
+}
+
+\def\setregextable{%
+ \restorecslist{flexparser-sect2}\yyflunion
+}
+
+\def\setregexdeftable{%
+ \restorecslist{flexparser-sect1}\yyflunion
+}
+
+% \flex\ parser indexing macros
+
+\def\flexidxdomain{F}
+\def\fstatedefidxrank{0}
+\def\fstateidxrank{1}
+\def\fregexidxrank{2}
+\def\ftextrefrank{5}
+
+\def\writeidxfsentry#1{% \flex\ state reference entry
+ \indxe\gindex{{\secno}{{}{\flexpseudonamespace}}{\flexidxdomain}{\fstateidxrank}#1}%
+}
+
+\def\writeidxfstextentry#1{% \flex\ state reference in text
+ \indxe\gindex{{\secno}{{}{\flexpseudonamespace}}{\flexidxdomain}{\ftextrefrank}#1}%
+}
+
+\def\writeidxfsdentry#1{% \flex\ state definition entry
+ \indxe\gindex{{\secno}{{}{\flexpseudonamespace}}{\flexidxdomain}{\fstatedefidxrank}#1}%
+}
+
+\def\writeidxfsrdentry#1{% \flex\ regex name definition entry
+ \indxe\gindex{{\secno}{{}{\flexpseudorenamespace}}{\flexidxdomain}{\fstatedefidxrank}#1}%
+}
+
+\def\writeidxfsrnentry#1{% \flex\ regex name entry
+ \indxe\gindex{{\secno}{{}{\flexpseudorenamespace}}{\flexidxdomain}{\fregexidxrank}#1}%
+}
+
+\def\writeidxfscclentry#1{% \flex\ chracter class name entry
+ \indxe\gindex{{\secno}{{}{\flexpseudonamespace}}{\flexidxdomain}{\fregexidxrank}#1}%
+}
+
+% \flex\ parser typesetting macros and stack types
+
+\def\yyuniontag{\yyflunion}
+\def\parserstrictnamespace{flexparser-strict}
+\def\parserprototypesnamespace{flexparser-strict:headers}
+\def\parserdebugnamespace{flexparser-debug}
+
+\def\yyflunion{\currentyyunionnamespace}
+
+\defp\flnametok#1#2{} % named definition :: \flnametok{matched text}{formatting command}, the text is \{text\}\ *
+%
+\defp\flcclexpr#1#2#3#4{} % character class expression :: \flcclexpr{matched text}{ccl token}{fptr}{sptr}
+\defp\flchar#1#2#3#4{} % character :: \flchar{char}{char12}{fptr}{sptr}
+\defp\flstring#1#2#3{} % string :: \flstring{{fptr}{sptr}}{\flchar{...}*}{{fptr}{sptr}}
+\defp\flcclrnge#1#2{} % character range :: \flcclrnge{/flchar{...}}{/flchar{...}}
+\defp\flbraceccl#1#2#3{} % character class :: \flbraceccl{{fptr}{sptr}}{ccl}{{fptr}{sptr}}
+\defp\flbracecclneg#1#2#3{} % negative character class :: \flbracecclneg{{fptr}{sptr}}{ccl}{{fptr}{sptr}}
+\defp\flcclunion#1#2{} % union of character classes :: \flcclunion{ccl}{ccl}
+\defp\flccldiff#1#2{} % difference of character classes :: \flccldiff{ccl}{ccl}
+\defp\flrepeat#1{} % asterisk operation :: \flrepeat{re}
+\defp\flrepeatstrict#1{} % plus operation :: \flrepeatstrict{re}
+\defp\flrepeatonce#1{} % ? operation :: \flrepeatonce{re}
+\defp\flrepeatnm#1#2#3{} % {n, m} operation :: \flrepeatnm{re}{num}{num}
+\defp\flrepeatgen#1#2{} % {n,} operation :: \flrepeatgen{re}{num}
+\defp\flrepeatn#1#2{} % {n} operation :: \flrepeatn{re}{num}
+\defp\flparens#1#2#3#4{} % parenthesized regular expression :: \flparens{{fptr}{sptr}}{re}{{fptr}{sptr}}{formatting command}
+\defp\fldot#1#2{} % dot expression :: \fldot{fptr}{sptr}
+\defp\flor#1#2{} % `|' expression :: \flor{fptr}{sptr}
+\defp\fltrail#1#2{} % regular expression sans trailing suffix :: \fltrail{re}{{fptr}{sptr}}
+\defp\flretrail#1#2#3{} % regular expression with a trailing context :: \flretrail{re}{{fptr}{sptr}}{re}
+\defp\flreateol#1#2#3{} % regular expression with the end of line as a trailing context :: \flreateol{re}{fptr}{sptr}
+\defp\flrule#1#2{} % full regular expression :: \flrule{re}{formatting command}
+\defp\flbolrule#1#2{} % full regular expression at the beginning of the line :: \flbolrule{re}{formatting command}
+\defp\fleof#1#2{} % end of file rule :: \fleof{fptr}{sptr}
+\defp\flsconlist#1#2#3{} % start condition list :: \flsconlist{{fptr}{sptr}}{\flname...}{{fptr}{sptr}}
+\defp\flsconuniv#1#2{} % universal start condition :: \flsconuniv{fptr}{sptr}
+\defp\flnamesep#1#2{} % separator between names :: \flnamesep{fptr}{sptr}
+\defp\flname#1#2#3#4{} % name :: \flname{name}{name12}{fptr}{sptr}
+\defp\flopt#1#2#3#4#5{} % \flex option :: \flopt{option}{text}{text12}{fptr}{sptr}
+\defp\floptions#1{} % \flex options :: \floptions{\flopt ...}
+\defp\flscondecl#1#2#3#4{} % start condition declarations :: \flscondecl{x|s}{fptr}{sptr}{\flname ...}
+\defp\flaction#1#2#3#4#5#6#7{} % \flex action :: \flaction{\flsconlist...}{\fl..rule ...}{fptr}{sptr}{fptr}{sptr}{formatting command}
+\defp\flactionc#1#2#3#4#5#6#7{} % \flex continued action :: \flaction{\flsconlist...}{\fl..rule ...}{fptr}{sptr}{fptr}{sptr}{formatting command}
+\defp\flactiongroup#1#2#3#4#5#6{} % a group of \flex actions :: \flactiongroup{\flsconlist...}{fptr}{sptr}{\flaction...}{fptr}{sptr}
+\defp\flbareaction#1#2#3#4#5#6{} % bare action :: \flbareaction{fptr}{sptr}
+\defp\flptropt#1#2{} % %ponter directive :: \flptropt{fptr}{sptr}
+\defp\flarrayopt#1#2{} % %array directive :: \flarrayopt{fptr}{sptr}
+\defp\fltopopt#1#2#3#4{} % %top directive :: \fltopopt{fptr}{sptr}{fptr}{sptr}
+\defp\flredef#1#2#3#4#5#6#7#8{} % regular expression definition :: \flredef{name}{name12}{fptr}{sptr}{text}{text12}{fptr}{sptr}
+
+\toyyunion{flexparser-prototypes}
+
+\restorecslist{flexparser-strict}\yyflunion
+
+\defc\flrule{%#1#2% full regular expression :: \flrule{re}{formatting command}
+ {\toksc{}#1#2\expandafter}\expandafter\toksd\expandafter{\the\toksc}%
+ \concat\toksc\toksd
+}
+
+\newif\iftextre % check if this is a free standing regular expression or appears in the definitions table
+
+\defc\flbolrule{%#1#2% full regular expression at the beginning of the line :: \flbolrule{re}{formatting command}
+ {\toksc{}#1#2\appendlnx\toksc{\raise0.5pt%
+ \iftextre\yybreak{\hbox}\else\yybreak{\llap}\yycontinue{\sscmd$\dashv$\ }}\expandafter}\expandafter%
+ \toksd\expandafter{\the\toksc}\concat\toksc\toksd
+}
+
+\let\astformat@flrule\empty
+
+\def\inscomment#1{% insert a comment before the rule
+ \def\astformat@flrule{%
+ \appendlnx\toksc{\noalign{#1}}%
+ }%
+}
+
+\def\insrulealign#1#2{%
+ \def\astformat@flrule{%
+ \tokse{#1}\toksf{#2}%
+ \concatl\tokse\toksc
+ \concat\toksc\toksf
+ }%
+}
+
+\def\rulealigntemplate{% to hide the hash symbols from \\edef operators
+ \vbox\bgroup\halign\bgroup##\hfil&##\hfil\cr
+}
+
+% regular expression symbols
+
+\defc\flstring{%#1#2#3% string :: \flstring{{fptr}{sptr}}{\flchar{...}*}{{fptr}{sptr}}
+% \toksc\expandafter{\the\toksc\hbox{#2}}%
+ #2%
+}
+
+\defc\flnametok{%#1#2% named definition :: \flnametok{matched text}{formatting command}, the text is \{text\}\ *
+ \let\termindex\writeidxfsrnentry
+ \fln@metok#1\end{#2}%
+ \let\termindex\eatone
+}
+
+\def\fln@metok\{#1\}#2\end#3{%
+ {%
+ \let\hostparsernamespace\flexpseudorenamespace
+ \nameproc{#1}\with\parsebin
+ \edef\next{%
+ \toksd{\toksd{\the\toksa}\tokse{\the\toksb}}%
+ }\next % a trick to `reshuffle' the output of \nameproc:
+ % the parsed name goes to \toksd and the visual key is put in \tokse
+ \expandafter
+ }\the\toksd
+ \toksf{}\toksg{}%
+ #3%
+ \edef\next{%
+ \toksc{\the\toksc\the\toksf{}\nx\flexrendisplay{\the\toksd}%
+ \gidxentryxv{\termfsrestring}{#1}{\the\tokse}\the\toksg
+ }%
+ }\next
+}
+
+\def\insnamealign#1#2{%
+ \def\astformat@flnametok{%
+ \toksf{#1}%
+ \toksg{#2}%
+ }%
+}
+
+\let\astformat@flnametok\empty
+
+\defc\flchar{%#1#2#3#4% character :: \flchar{char}{char12}{fptr}{sptr}
+ \yystringempty{#2}{#1}{\flch@r#2\end}%
+}
+
+\def\flch@r#1#2\end{%
+ \ifnum`#1=`\\
+ \fl@h@r#2\end
+ \else
+ \toksc\expandafter{\the\toksc{\ntt#1#2}}%
+ \fi
+}
+
+\def\fl@h@r#1#2\end{% process the sequence after an escape
+ {%
+ \let\default\flescdefault
+ \tokse{#1}\toksd{#2}%
+ \switchon{\the\tokse}\in\flesccharswitch
+ \edef\next{\toksc{\toksc{\the\toksc\the\toksd}}}\next
+ \expandafter
+ }\the\toksc
+}
+
+\def\flesccharswitch{% recognizing different types of escape sequences
+01234567
+ {% octal constant
+ \edef\next{\toksd{\nx\.{\the\tokse\the\toksd}$_8${}}}\next
+ }
+nfrtabv
+ {% \Cee\ escape sequence
+ \edef\next{\toksd{{\nx\sscmd\nx\sscmd$\nx\langle$\nx\.{\the\tokse\the\toksd}$\nx\rangle$}}}\next
+ }
+x
+ {% hexadecimal constant
+ \edef\next{\toksd{\nx\.{\the\toksd}$_{16}${}}}\next
+ }
+}
+
+\def\flescdefault{%
+ \edef\next{\toksd{\nx\.{\the\tokse\the\toksd}}}\next
+}
+
+\setspecialcharsfrom\flesccharswitch
+
+\defc\fldot{%#1#2% dot expression :: \fldot{fptr}{sptr}
+ \toksc\expandafter{\the\toksc.}%
+}
+
+\defc\flparens{%#1#2#3#4% parenthesized regular expression :: \flparens{{fptr}{sptr}}{re}{{fptr}{sptr}}{format command}
+ {\toksc{}#2\expandafter}\expandafter\toksd\expandafter
+ {\the\toksc{\rm)}}%
+ \toksf{}\toksg{}#4%
+ \tokse\expandafter{\the\toksf{\rm(}}%
+ \concatl\tokse\toksd
+ \concat\toksc\toksd
+ \concat\toksc\toksg
+}
+
+\def\insparensalign#1#2{%
+ \def\astformat@flparens{%
+ \toksf{#1}%
+ \toksg{#2}%
+ }%
+}
+
+\let\astformat@flparens\empty
+
+\defc\flrepeat{%#1% asterisk operation :: \flrepeat{re}
+ {\toksc{}#1\expandafter}\expandafter\toksd\expandafter
+ {\the\toksc{{}${}_{*}$}}%
+ \flselectiveseparator
+ \concat\toksc\toksd%
+}
+
+\defc\flrepeatn{%#1#2% {n} operation :: \flrepeatn{re}{num}
+ {\toksc{}#1\expandafter}\expandafter\toksd\expandafter
+ {\the\toksc{{}${}_{\{\yyfirstoftwo#2\}}$}}%
+ \flselectiveseparator
+ \concat\toksc\toksd%
+}
+
+\defc\flrepeatnm{%#1#2#3% {n, m} operation :: \flrepeatnm{re}{num}{num}
+ {\toksc{}#1\expandafter}\expandafter\toksd\expandafter
+ {\the\toksc{{}${}_{\{\yyfirstoftwo#2,\yyfirstoftwo#3\}}$}}%
+ \flselectiveseparator
+ \concat\toksc\toksd%
+}
+
+\defc\flrepeatonce{%#1% ? operation :: \flrepeatonce{re}
+ {\toksc{}#1\expandafter}\expandafter\toksd\expandafter
+ {\the\toksc{{}${}_{?}$}}%
+ \flselectiveseparator
+ \concat\toksc\toksd%
+}
+
+\defc\flrepeatstrict{%#1% plus operation :: \flrepeatstrict{re}
+ {\toksc{}#1\expandafter}\expandafter\toksd\expandafter{\the\toksc{{}${}_{+}$}}%
+ \flselectiveseparator
+ \concat\toksc\toksd%
+}
+
+\def\flselectiveseparator{%
+ \yytoksempty\toksc{}{%
+ \tokse{{{}$\,$}}%
+ \concatl\tokse\toksd
+ }%
+}
+
+\defc\flcclrnge{%#1#2% character range :: \flcclrnge{\flchar{...}}{\flchar{...}}
+% \toksd{#1}\getfirst\toksd\to\toksd
+% \tokse{#2}\getfirst\tokse\to\tokse
+ #1\appendr\toksc{{\nx\rm--}}#2%
+% \edef\next{\toksc{\the\toksc\the\toksd{\nx\rm--}\the\tokse}}\next
+}
+
+\defc\flcclexpr{%#1#2#3#4% character class expression :: \flcclexpr{matched text}{ccl token}{fptr}{sptr}
+ {%
+ \let\hostparsernamespace\flexpseudonamespace
+ \nameproc{#2}\with\parsebin
+ \edef\next{%
+ \toksd{\toksd{\the\toksa}\tokse{\the\toksb}}%
+ }\next % a trick to `reshuffle' the output of \nameproc:
+ % the parsed name goes to \toksd and the visual key is put in \tokse
+ \expandafter
+ }\the\toksd
+ \let\termindex\writeidxfscclentry
+ \edef\next{\toksc{\the\toksc{\the\toksd}%
+ \gidxentryxv{\termidstring}{#2}{\the\tokse}%
+ }}\next
+ \let\termindex\eatone
+}
+
+\defc\flbraceccl{%#1#2#3% character class :: \flbraceccl{{fptr}{sptr}}{ccl}{{fptr}{sptr}}
+ \appendrnx\toksc{{}$[${}}%
+ #2%
+ \appendrnx\toksc{{}$]${}}%
+}
+
+\def\flbraceccldemo#1#2#3{% character class :: \flbraceccl{{fptr}{sptr}}{ccl}{{fptr}{sptr}}
+ % a demo version without the beginning bracket
+ \appendrnx\toksc{{}$\ldots${}}%
+ #2%
+ \appendrnx\toksc{{}$]${}}%
+}
+
+\defc\flccldiff{%#1#2% difference of character classes :: \flccldiff{ccl}{ccl}
+ #1%
+ \appendr\toksc{${}\nx\setminus{}$}%
+ #2%
+}
+
+\defc\flbracecclneg{%#1#2#3% negative character class :: \flbracecclneg{{fptr}{sptr}}{ccl}{{fptr}{sptr}}
+ \appendr\toksc{{}$[${}}%
+ #2%
+ \appendr\toksc{{}$]^c${}}%
+}
+
+\defc\fleof{%#1#2% end of file rule :: \fleof{fptr}{sptr}
+ \let\termindex\writeidxfsrnentry
+ \edef\next{\toksc{\the\toksc{}\nx\flexrendisplay{EOF}%
+ \gidxentry{\termfsrestring}{EOF}{EOF}}}\next
+ \let\termindex\eatone
+}
+
+\defc\flor{%#1#2% `|' expression :: \flor{fptr}{sptr}
+ \appendr\toksc{{}${}\nx\mid{}${}}%
+}
+
+\defc\flsconuniv{%#1#2% universal start condition :: \flsconuniv{fptr}{sptr}
+ \let\termindex\writeidxfsentry
+ \edef\next{\toksb{\the\toksb{}$\langle*\rangle${}%
+ \gidxentryxv{\termvstring}{*}{*}}}\next % TODO: create a separate name space for state names
+ \let\termindex\eatone
+}
+
+\defc\fltrail{%#1#2% regular expression sans trailing suffix :: \fltrail{re}{{fptr}{sptr}}
+ \errmessage{\nx\fltrail\space macro has not been implemented (see yyunion.sty).}
+}
+
+\defc\flretrail{%#1#2#3% regular expression with a trailing context :: \flretrail{re}{{fptr}{sptr}}{re}
+ \errmessage{\nx\flretrail\space macro has not been implemented (see yyunion.sty).}
+}
+
+\defc\flreateol{%#1#2#3% regular expression with the end of line as a trailing context :: \flreateol{re}{fptr}{sptr}
+ {\toksc{}#1\expandafter}\expandafter\toksd\expandafter{\the\toksc{\raise0.5pt\rlap{\sscmd\ $\vdash$}}}%
+ \concat\toksc\toksd%
+}
+
+\toyyunion{flexparser-re}
+
+\def\flexsndisplay#1{% state name typesetting style
+ \hbox{\tt#1}%
+}
+
+\def\flexrendisplay#1{% regular expression name typesetting style
+ \penalty-100 \hbox{$\langle$\tt#1$\rangle$}%
+}
+
+\def\flexsnstyle#1{% typesetting \flex\ state names in text
+ {%
+ \let\parsernamespace\flexpseudonamespace
+ \nameproc{#1}\with\parsebin
+ \edef\next{%
+ \toksd{\the\toksa}\tokse{\the\toksb}%
+ }\next % a trick to `reshuffle' the output of \nameproc:
+ % the parsed name goes to \toksd and the visual key is put in \tokse
+ \let\termindex\writeidxfstextentry
+ \edef\next{\toksd{\nx\flexsndisplay{\the\toksd}%
+ \gidxentryxv{\termvstring}{#1}{\the\tokse}}}\next
+ \expandafter
+ }\the\toksd
+}
+
+\def\flexrenstyle#1{% typesetting \flex\ regular expression names in text
+ {%
+ \let\parsernamespace\flexpseudorenamespace
+ \nameproc{#1}\with\parsebin
+ \edef\next{%
+ \toksd{\the\toksa}\tokse{\the\toksb}%
+ }\next % a trick to `reshuffle' the output of \nameproc:
+ % the parsed name goes to \toksd and the visual key is put in \tokse
+ \let\termindex\writeidxfstextentry
+ \edef\next{\toksd{\nx\flexrendisplay{\the\toksd}%
+ \gidxentryxv{\termfsrestring}{#1}{\the\tokse}}}\next
+ \expandafter
+ }\the\toksd
+}
+
+\def\flexrestyle#1{% typesetting \flex\ regular expressions in text
+ {%
+ \frexproc{#1}\with\ppregex
+ \edef\next{\toksc{\toksc{\the\toksc}}}\next
+ \expandafter
+ }\the\toksc
+ \hbox{\textretrue\tt\the\toksc}%
+}
+
+\defc\flactiongroup{% #1#2#3#4#5#6% a group of \flex actions :: \flactiongroup{\flsconlist...}{fptr}{sptr}{\flaction...}{fptr}{sptr}
+ \toksb{}#1% collect all the state name information in \toksb
+ % gather the preceeding stash
+ \readstash{#3}% read stash late, after \flsconslist (ignore it)
+ \edef\next{%
+ \toksb{\noalign{\hbox to\nx\hsize{\hskip\the\rgindent
+ \nx\flexsndisplay{\the\toksb}:\toksa{\relax\the\toksg}\nx\makestashbox\nx\hfil}}}%
+ }\next
+ \yytoksempty\table{}{\appendrnx\table{\noalign{\medskip}}}%
+ \concat\table\toksb
+ \advance\rgindent by\parindent
+ #4%
+ \advance\rgindent by-\parindent
+}
+
+\defc\flsconlist{% #1#2#3% start condition list :: \flsconlist{{fptr}{sptr}}{\flname...}{{fptr}{sptr}}
+ \readstashwredirect#1\toksg % save the stash preceeding the conditions list to reinsert later
+ #2% collect the state names (and the stash in between)
+ \readstashwredirect#3\toksf
+ \appendr\toksb{\nx\rm\toksa{\the\toksf}\nx\makestashbox}%
+}
+
+\defc\flname{% #1#2#3#4% name :: \flname{name}{name12}{fptr}{sptr}
+ {%
+ \let\parsernamespace\flexpseudonamespace
+ \nameproc{#2}\with\parsebin
+ \edef\next{%
+ \toksd{\toksd{\the\toksa}\tokse{\the\toksb}}%
+ }\next % a trick to `reshuffle' the output of \nameproc:
+ % the parsed name goes to \toksd and the visual key is put in \tokse
+ \expandafter
+ }\the\toksd
+ \let\termindex\writeidxfsentry
+ \readstashwredirect{}{#4}\toksf % do not touch \yystashlocal
+ \appendr\toksb{{\nx\rm\toksa{\the\toksf}\nx\makestashbox}%
+ \the\toksd\gidxentryxv{\termvstring}{#1}{\the\tokse}}%
+ \let\termindex\eatone
+}
+
+\defc\flnamesep{%#1#2% separator between names :: \flnamesep{fptr}{sptr}
+ \toksb\expandafter{\the\toksb\ }%
+}
+
+\newskip\rgindent
+
+\rgindent=\parindent
+
+\defc\flaction{%#1#2#3#4#5#6#7% \flex action :: \flaction{\flsconlist...}{\fl..rule ...}{fptr}{sptr}{fptr}{sptr}{formatting command}
+ \toksb{}#1%
+ \toksc{}#2%
+ #7% apply formatting
+ \readstash{#6}% read stash late, after \flsconlist and \fl...rule
+ \yytoksempty\toksb{%
+ \appendr\table{\hskip\the\rgindent\hbox{\nx\tt\nx\strut\the\toksc}}%
+ }{%
+ \appendr\table{%
+ \hskip\the\rgindent
+ \vbox{%
+ {\nx\sscmd\nx\expandafter}\nx\expandafter\baselineskip\nx\the\baselineskip
+ \halign{&####\hfil\cr
+ \hbox to\rgindent{\nx\sscmd\nx\tt\nx\strut\the\toksb\hss}\cr
+ \nx\tt\nx\strut\the\toksc\cr
+ }%
+ }%
+ }%
+ }%
+ \appendr\table{&\toksa{\relax\the\yystashlocal}\nx\cr}%
+}
+
+\defc\flactionc{%#1#2#3#4#5#6#7% \flex continued action :: \flaction{\flsconlist...}{\fl..rule ...}{fptr}{sptr}{fptr}{sptr}{formatting command}
+ \toksb{}#1%
+ \toksc{}#2%
+ \readstash{#6}% read stash late, after \flsconlist and \fl...rule
+ #7% apply formatting
+ \yytoksempty\toksb{%
+ \appendr\table{\hskip\the\rgindent\hbox{\nx\tt\nx\strut\the\toksc}}%
+ }{%
+ \appendr\table{%
+ \hskip\the\rgindent
+ \vbox{%
+ {\nx\sscmd\nx\expandafter}\nx\expandafter\baselineskip\nx\the\baselineskip
+ \halign{&####\hfil\cr
+ \hbox to\rgindent{\nx\sscmd\nx\tt\nx\strut\the\toksb\hss}\cr
+ \nx\tt\nx\strut\the\toksc\cr
+ }%
+ }%
+ }%
+ }%
+ \appendr\table{&\toksa{{}$\nx\hookleftarrow$\relax\the\yystashlocal}\nx\cr}% in the event \cr has been redefined
+}
+
+\def\inscomment#1{%
+ \def\astformat@flaction{%
+ \toksd{#1}%
+ \appendr\table{\noalign{\nx\smallskip\noindent\hskip\the\rgindent
+ $\nx\triangleright\;$\the\toksd\nx\smallskip}}%
+ }%
+}
+
+\let\astformat@flaction\empty
+
+\toyyunion{flexparser-sect2}
+
+% \flex\ setion~1 typesetting
+% currently, all \flex\state declarations are handled by an extended \bison\ parser
+% to collect the state data; we thus only implement regular expression definitions;
+
+\restorecslist{flexparser-strict}\yyflunion
+
+\defc\flredef{%#1#2#3#4#5#6#7#8% regular expression definition :: \flredef{name}{name12}{fptr}{sptr}{text}{text12}{fptr}{sptr}
+ \let\termindex\writeidxfsrdentry
+ {%
+ \let\hostparsernamespace\flexpseudorenamespace
+ \nameproc{#1}\with\parsebin
+ \edef\next{%
+ \toksd{\toksd{\the\toksa}\tokse{\the\toksb}}%
+ }\next % a trick to `reshuffle' the output of \nameproc:
+ % the parsed name goes to \toksd and the visual key is put in \tokse
+ \expandafter
+ }\the\toksd
+ \frexproc{#5}\with\ppregex
+ \appendr\table{{}$\nx\langle\hbox{\ntt\the\toksd}\nx\rangle${}%
+ \gidxentryxv{\termfsrestring}{#1}{\the\tokse}&\the\toksc\cr% TODO: make a special type processor for regex names
+ }%
+ \let\termindex\eatone
+}
+
+\defc\flopt{%#1#2#3#4#5% \flex option :: \flopt{option}{text}{text12}{fptr}{sptr}
+ \csname flex@ption_#1\endcsname{#2}{#3}%
+}
+
+\expandafter\def\csname flex@ption_deprecated\endcsname#1#2{%
+ \flex@opt@deprecated#2%
+}
+
+\def\flex@opt@deprecated#1#2#3^^J{%
+ \let\termindex\writeidxfsrnentry
+ \appendr\table{$\langle${\nx\tt #2}$\rangle_{\rm f}$\gidxentryxv{\termfsopstring}{#2}{#2}%
+ \the\toksg&\number\flexgetnumber#3.\nx\cr}%
+ \let\termindex\empty
+}
+
+\def\flexgetnumber#1{%
+ \ifnum`#1<"3A
+ \yybreak{%
+ \ifnum`#1>"2F
+ \yybreak{#1\flexgetnumber}%
+ \else
+ \yybreak{%
+ \ifnum`#1="20
+ \yybreak{\flexgetnumber}%
+ \else
+ \yybreak{}%
+ \yycontinue
+ }
+ \yycontinue
+ }%
+ \else
+ \yybreak{}%
+ \yycontinue
+}
+
+\toyyunion{flexparser-sect1}
+
+% correct a few sequences for debugging purposes
+
+\restorecslist{flexparser-debug}\yyflunion
+
+\defc\flnametok{%#1#2% named definition :: \flnametok{matched text}{formatting command}, the text is \{text\}\ *
+ \noexpand\flnametok{#1}{}%
+}
+
+\defc\flparens{%#1#2#3#4% parenthesized regular expression :: \flparens{{fptr}{sptr}}{re}{{fptr}{sptr}}{formatting command}
+ \noexpand\flparens{#1}{#2}{#3}{}%
+}
+
+\defc\flrule{%#1#2% full regular expression :: \flrule{re}{formatting command}
+ \noexpand\flrule{#1}{}%
+}
+
+\defc\flbolrule{%#1#2% full regular expression at the beginning of the line :: \flbolrule{re}{formatting command}
+ \noexpand\flbolrule{#1}{}%
+}
+
+\defc\flaction{%#1#2#3#4#5#6#7% \flex action :: \flaction{\flsconlist...}{\fl..rule ...}{fptr}{sptr}{fptr}{sptr}{formatting command}
+ \noexpand\flaction{#1}{#2}{#3}{#4}{#5}{#6}{}%
+}
+
+\defc\flactionc{%#1#2#3#4#5#6#7% \flex continued action :: \flaction{\flsconlist...}{\fl..rule ...}{fptr}{sptr}{fptr}{sptr}{formatting command}
+ \noexpand\flactionc{#1}{#2}{#3}{#4}{#5}{#6}{}%
+}
-\def\charstonumbers#1\end{\edef\next{\toksa{\charstonumberse#1\end}}\next}
+\toyyunion{flexparser-debug}
diff --git a/support/splint/tex/yyxunion.sty b/support/splint/tex/yyxunion.sty
deleted file mode 100644
index fb0d2460b3..0000000000
--- a/support/splint/tex/yyxunion.sty
+++ /dev/null
@@ -1,33 +0,0 @@
-% Copyright 2012-2015, Alexander Shibakov
-% This file is part of SPLinT
-%
-% SPLinT is free software: you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation, either version 3 of the License, or
-% (at your option) any later version.
-%
-% SPLinT is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
-
-% the original, minimal bootstrapping macros were designed to process
-% \prodstyle{\%token} declarations only and are enough to establish the
-% interface between the \bison\ parser and the \bison\ lexer; to serve
-% the secondary task of providing typesetting information to
-% the \bison\ parser, all forms of token declarations must be processed.
-
-\restorecslist{bootstrap}\yyunion % get the original bootstrap macros
-
-\def\precdecls#1#2#3#4#5{#3}
-
-\def\symbolprec#1#2{%
- \toksa{}\toksb{}%
- #1%
- \yytoksempty\toksb{}{\immediate\write\tokendefs{\noexpand\tokenpp{\the\toksb}}}%
-}
-
-\savecslist{bootstrap}\yyunion