<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">% Copyright 2012-2024, 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 &lt;http://www.gnu.org/licenses/&gt;.

% creating a sequence containing all pairs from the two given sequences;
% the (long) string produced by the \diagprod macro
% lists all the elements so that each ordered pair ab where a and b are
% different elements from each of the two sets appears exactly once;
% a simple strategy for creating such strings is to build them recursively so that if
% S is a string that lists n values in this manner and s is a new item type,
% start with sSs and then add each symbol from S on either side 
% in such a way that among any two consecutive symbols exactly one is s

% these macros are used to create switch statements that use such ordered pairs
% and are not particularly general or robust; 
% they are supposed to be used once in the setup stage;
% the assumption made by these mactos is that `.' or `;' never appear as elements 
% of the two sets

\def\gnxtelem#1\to#2\and#3{%
    \expandafter\gnxtel@m\expandafter#2\expandafter#3\the#1.;%
}

\def\gnxtel@m#1#2#3#4;{%
    \def\next{#4}%
    \ifx\next\empty
        #1{}%
    \else
        #1{#3}%
        \gnxt@l@m#2#4%
    \fi
}

\def\gnxt@l@m#1#2.{%
    #1{#2}%
}

\def\pairup{%
    \gnxtelem\toksa\to\toksc\and\toksa % get the first remaining element of set A (\toksa)
    \edef\elemofA{\the\toksc}%
    \ifx\elemofA\empty % no more elements in A
         \let\next\relax
    \else
        \ifx\elemofA\lastelemofB % the current element of A is the same as the last element of B
            \edef\next{\the\toksa}%
            \ifx\next\empty % it is the last remaining element of A
                \expandafter\p@ir@p\the\toksb.% form all pair of \the\toksc with elements in B except the first one
            \else
                \concat\toksa\toksc % move it to the end of A
            \fi
            \let\next\pairup
        \else
            \expandafter\pair@p\the\toksb.% form all pairs of \the\toksc with elements in B
            \let\next\pairup
        \fi
    \fi
    \next
}

\def\dotcontainer{.}

\def\pair@p#1{%
    \def\next{#1}%
    \ifx\next\elemofA % the next element of B is the current element of A
        \ifx\next\lastelemofB % it is the last element of B
                              % we can arrive here only if 1) B has more than one element and 
                              % 2) \elemofA is the last remaining element of A
            \edef\next{\toksd{\the\toksd\the\tokse}}\next
            \let\next\eatone % eat the remaining dot     
        \else
            \removeelem\elemofA\from\toksb % remove it from B
            \let\next\pair@p
        \fi
    \else
        \ifx\next\dotcontainer % no more elements in B
            \let\next\relax
        \else
            \toksf{#1}%
            \edef\next{\toksd{\the\toksd\the\toksc\the\toksf}}\next
            %\showthe\toksd
            \let\next\pair@p
        \fi
    \fi
    \next
}

\def\p@ir@p#1{%
    \def\next{#1}%
    \ifx\next\elemofA % the next element of B is the current element of A
                      % this can only happen if B consists of a single element
        \let\next\eatone
    \else
        \toksf{#1}%
        \edef\next{\toksd{\the\toksd\the\toksf}}\next
        \let\next\pair@p
    \fi
    \next
}

\def\removeelem#1\from#2{% #1 should be a sequence containing the element
                         % #2 is the token register
    \expandafter\def\expandafter\r@moveelem\expandafter##\expandafter1#1##2.{%
        \def\next{##2}%
        \ifx\next\empty % there was no such element
            \errmessage{Could not find \expandafter\string#1 in \the#2}%
        \else
            \expandafter\def\expandafter\r@mov@elem\expandafter####\expandafter1#1{%
                #2{##1####1}%
            }\r@mov@elem##2%
       \fi
    }%
    \expandafter\expandafter\expandafter\r@moveelem\expandafter\the\expandafter#2#1.%
}

% the intersection of A and B should be at the end of A:

\def\pushintersect{%
    \gnxtelem\toksf\to\toksc\and\toksf % get the first remaining element of set A (\toksa)
    \edef\next{\the\toksc}%
    \ifx\next\empty % there are no elements left in A
        \let\next\relax
    \else
        \expandafter\def\expandafter\p@shintersect\expandafter##\expandafter1\the\toksc##2.{%
            \def\next{##2}%
            \ifx\next\empty % there was no such element in the other set
                \edef\next{\toksa{\the\toksc\the\toksa}}\next % append it to the front
            \else
                \edef\next{\toksa{\the\toksa\the\toksc}}\next % append it to the back
            \fi
        }%
        \expandafter\expandafter\expandafter\p@shintersect\expandafter\the\expandafter\toksb\the\toksc.%
        \let\next\pushintersect
    \fi
    \next
}

\def\diagprod#1#2\in#3{%
    \toksa\expandafter{#1}%
    \toksb\expandafter{#2}%
    \gnxtelem\toksb\to\tokse\and\toksb % \tokse is a selected element in set B (\toksb)
    \concat\toksb\tokse % now \tokse is the last element of B 
    \toksf\toksa\toksa{}%
    \pushintersect % prepare the sequence representing set A so that the intersection elements are in the tail
    \edef\lastelemofB{\the\tokse}% the last element of B
    \toksd\expandafter{\the\tokse}% future sequence pairs
    \pairup
    \edef#3{\the\toksd}%
}

% namespace management for macros
% note that if one of the sequences, say \name, were made \let\name. the macros would break;
% this can be fixed by using a more sophisticated comparison but was decided against
% in the interests 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{%
    \ifx#2.%
        \yybreak{}%
    \else
        \yybreak{%
            \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{%
    \ifx#2.%
        \yybreak{}%
    \else
        \yybreak{%
            \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{%
  \ifx#1.%
      \yybreak{}%
  \else
      \yybreak{%
          \let#1\relax
          \h@decs
      }%
  \yycontinue
}

\def\hidecslist#1{\expandafter\hidecs\expandafter{#1}}

\def\savehcs#1#2{\savecs{#1}{#2}\hidecs{#2}}

\def\savehcslist#1#2{%
    \expandafter\s@vehcslist\expandafter{#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.} % there is no \savecsxlist macro

\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\csname\expandafter\defprefix\expandafter\eatone\string#2\defpostfix\endcsname#2{#1}%
          \s@vecsx{#1}%
      }%
  \yycontinue
}

\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\restorecsxname{#1}{#2}\endcsname
          \r@storecsx{#1}%
      }%
  \yycontinue
}

\def\restorecsxlist#1#2{%
    \expandafter\r@storecsxlist\expandafter{#2}{#1}%
}

\def\r@storecsxlist#1#2{%
    \restorecsx{#2}{#1}%
}

\def\r@storecsxlet#1{%
  \expandafter\let\csname\expandafter\defprefix\expandafter\eatone\string#1\defpostfix\endcsname
}

\def\hidecsx#1{\h@decsx#1.}

\def\h@decsx#1{%
  \ifx#1.%
      \yybreak{}%
  \else
      \yybreak{%
          \expandafter\let\csname\expandafter\defprefix\expandafter\eatone\string#1\defpostfix\endcsname\relax
          \h@decsx
      }%
  \yycontinue
}

\def\savehcsx#1#2{\savecsx{#1}{#2}\hidecsx{#2}}

\def\defx#1{% defining sequences as above
  \toksa\expandafter{%
  \csname\expandafter\defprefix\expandafter\eatone\string#1\defpostfix\endcsname}%
  \afterassignment\d@fx
  \expandafter\def\the\toksa
}

\def\d@fx#1{%
  \toksb{#1}\edef\next{\noexpand\savehcs{\the\toksb}\the\toksa}\next
}

\def\defy#1#2#{% in addition to the definition of the contorl sequence
               % 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
  \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}%
  \afterassignment\d@f@
  \toksd=%
}

\def\d@f@{%
   \tokse{\defypreamble}%
   \concatl\tokse\toksd
   \concatl\toksf\toksd
   \tokse{\defypostamble}%
   \concat\toksd\tokse
   \toksd\expandafter{\expandafter{\the\toksd}}%
   \concat\toksc\toksd
   \afterassignment\d@fy
   \the\toksc
}

\def\d@fy#1{%
  \toksb{#1}\edef\next{\noexpand\savehcs{\the\toksb}\the\toksa}\next
}

% dynamic typing macros
%
% (1) define a macro prototype, this also defines a few other macros to be used in
%     special circumstances, such as for error checking (strict), and to use where
%     expansion must be suppressed (such as diagnostic output)

\def\defp#1#2#{% flexible dynamic type checking
    \toksa\expandafter\expandafter\expandafter{\yyuniontag#1}%
    \expandafter\edef\yyuniontag{\the\toksa}% add the sequence to the current union
    \def#1#2{\errmessage{unexpected type: \string#1 in namespace &lt;\currentyyunionnamespace&gt;}}%
    \savecs\parserstrictnamespace#1%
    \toksa{#2}%
    \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%
}

% (2) define the macro (#1) with an automatic prototype (if the parameter list is empty) or
%     with prototype checking; the prototype should have been defined earlier with \.{\\defp}

\def\defc#1#2#{%
    \restorecs\parserprototypesnamespace#1%
    \toksa{#2}%
    \edef\next{\the\toksa}%
    \ifx\next\empty
        \yybreak{\expandafter\def\expandafter#1#1}%
    \else
        \ifx\next#1%
            \yybreak@{\expandafter\def\expandafter#1#1}%
        \else
            \yybreak@{%
                \toksb\expandafter{#1}%
                {%
                    \newlinechar=`^^J%
                    \edef\next{%
                        \errhelp{the prototype of \string#1 is from &lt;\parserprototypesnamespace&gt;^^J%
                                 you might want to look for a \expandafter\string\expandafter\defp\string#1... line somewhere}%
                    }\next
                    \errmessage{macro definition of \string#1 does not match its prototype:^^J 
                                \the\toksa\space (should be \the\toksb)}%
                }%
            }%
        \fi
    \yycontinue
}

% (3) once a set of macros have been defined, all current definitions are added to the
%     \.{\\yyunion} list in a namespace of your choosing by the \.{\\toyyunion} command

\def\t@yyunion#1#2{\def\currentyyunionnamespace{#2}\savecslist{#2}#1}
\def\toyyunion#1{\expandafter\t@yyunion\yyuniontag{#1}}

% this command sequence provides a standard set of parameters for the scheme above
% to work; note that these settings will stay unchanged till the next command

\def\yyuniondeclare#1#2{% #1 is the command sequence that holds the union
                        % #2 is the root of the namespace
    \def#1{\currentyyunionnamespace}% subset of the global union that deals with footnotes
    \def\yyuniontag{#1}%
    \def\parserstrictnamespace{#2:strict}%
    \def\parserprototypesnamespace{#2:headers}%
    \def\parserdebugnamespace{#2:debug}%
}

{\catcode`\ =13 \aftergroup\def\aftergroup\activespace\aftergroup{\aftergroup \aftergroup}}% active space
{\catcode`\% =12 \aftergroup\def\aftergroup\harmlesscomment\aftergroup{\aftergroup%\aftergroup}}% not really a comment
{\catcode`\{ =12 \catcode`\[=1 \aftergroup\def\aftergroup\lbchar\aftergroup[\aftergroup{\aftergroup}}% not really a brace
{\catcode`\} =12 \catcode`\]=2 \aftergroup\def\aftergroup\rbchar\aftergroup{\aftergroup}\aftergroup]]% not really a brace
{\catcode`\_=12 \aftergroup\def\aftergroup\uscoreletter\aftergroup{\aftergroup_\aftergroup}}
{\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

\def\doascii#1{%
  \tempca=\z@ \tempcb=\@cclvi
  \let\yyasciicc\empty
  \let\sts\relax
  \loop
      \edef\yyasciicc{\sts{\the\catcode\tempca}\yyasciicc}%
      \catcode\tempca=#1
      \advance\tempca\@ne
  \ifnum\tempca&lt;\tempcb\relax
  \repeat
  \catcode`\ =10 % keep normal spaces (otherwise \string will convert the category to 10)
  %\catcode`\^^M=5 % if newline is to be preserved
  \catcode`\^^M=12 % to match \eolletter
}

\def\undoascii{%
  \tempca=\@cclv
  \let\sts\undoacatcode
  \yyasciicc\def\yyasciicc{}%
}

\def\undoacatcode#1{\catcode\tempca=#1\advance\tempca\m@ne}

% yytname macros

\def\endcontainer{\end}%
\def\aaddname{\addname}

\def\addname{%
    \toksb{}%
    \@ddname
}

\def\@ddname#1{%
    \def\next{#1}%
    \ifx\next\aaddname
        \expandafter\edef\csname term\parsernamespace\the\toksb \endcsname{\the\tempca}%
        \appendtoyytname
        \advance\tempca1\relax
        \let\next\addname
    \else
        \ifx\next\endcontainer
            \expandafter\edef\csname term\parsernamespace\the\toksb \endcsname{\the\tempca}%
            \appendtoyytnamelast
            \let\next\relax
        \else
            \ifnum#1=`\_\relax
                \uccode`\.=#1\relax
                \uppercase{\toksa{.}}%
                \uccode`\.=`\.%
            \else
                \ifnum#1=`\-\relax
                    \toksa{-}%
                \else
                    \ifnum#1=`\ \relax
                        \toksa{ }%
                    \else
                        \uccode`\@=#1\relax
                        \uppercase{\toksa{@}}%
                        \uccode`\@=`\@\relax
                    \fi
                \fi
            \fi
            \concat\toksb\toksa
            \let\next\@ddname
        \fi
    \fi
    \next
}

\def\appendtoyytname{%
    \concat\yytname\toksb
    \toksa{\or}%
    \concat\yytname\toksa
}

\def\appendtoyytnamelast{%
    \concat\yytname\toksb
}

\def\print#1{{\endlinechar=`\^^J\immediate\write16{#1}}}

% token and state setup
% these are defined for a specific (though dynamic) namespace only

\def\tokenset#1#2{%
    \expandafter\edef\csname token\parsernamespace \fgetelemof{yytname}\at{#1}\endcsname{#2}%
}

\def\settokens{%
    \tempca=1\relax
    \loop
        \tempcb=\fgetelemof{yytranslate}\at\tempca\relax % important \relax!
        \tokenset\tempcb{\the\tempca}%
        \advance\tempca\@ne
    \ifnum\YYTRANSLATESIZE&gt;\tempca
    \repeat
    \relax
}

\def\stateset#1#2{%
    \expandafter\def\csname flexstate\parsernamespace #1\endcsname{#2}%
}

% token equivalence for bootstrap

\def\tokeneq#1#2{%
    \toksa{}%
    \numberstochars#2\end
    \toksa\expandafter{\csname token\parsernamespace\the\toksa\endcsname}%
    \toksb\expandafter{\csname token\parsernamespace#1\endcsname}%
    \edef\next{\let\the\toksb\the\toksa}\next
}%

\def\tokenpp#1{} % ignore \prodstyle{\%prec}-like declarations

\def\numberstochars#1{%
    \ifx\end#1%
        \yybreak{}%
    \else
        \uccode`.=#1\relax
        \uppercase{\toksa\expandafter{\the\toksa.}}%
        \uccode`.=`\.%
        \yybreak{\numberstochars}%
    \yycontinue
}

\def\numberstocharsandspaces#1{% same as above but turn \number`\ into a real space token
    \ifx\end#1%
        \yybreak{}%
    \else
        \ifnum#1=` \relax
            \yybreak@{%
                \expandafter\expandafter\expandafter
                \toksa\expandafter\expandafter\expandafter{\expandafter\the\expandafter\toksa\space}\numberstocharsandspaces}%
        \else
            \uccode`.=#1\relax
            \uppercase{\toksa\expandafter{\the\toksa.}}%
            \uccode`.=`\.%
        \fi
        \yybreak{\numberstocharsandspaces}%
    \yycontinue
}

% packing \write lines to avoid unnecessary expansions; it is \outer
% because it would be pretty useless inside a macro since all the category
% codes have already been set

\outer\def\packliteral{%
  \begingroup
  \catcode`\\=\other
  \catcode`\{=\other
  \catcode`\}=\other
  \catcode`\$=\other
  \catcode`\&amp;=\other
  \catcode`\#=\other
  \catcode`\%=\other
  \catcode`\~=\other
  \catcode`\^=\other
  \catcode`\_=\other
  \catcode`\|=\other
  \catcode`\ =\other
  \catcode`\^^M=\other
  \p@ckliteral
}

{\catcode`\%=\other\gdef\p@ckliteral#1%{\toksa{#1}\expandafter\endgroup\expandafter\p@ckl@teral\expandafter{\the\toksa}}}

\def\p@ckl@teral#1#2{#2{#1}}

% example of use: \packliteral {\crazy\sequence }% \toksa % this will save ` \crazy...' as cat 12 code characters in \toksa

% a (relatively) safe way to turn a command sequence into its name (sans the escape character) made up of nonletters

\def\csstring{%
    \ifnum\escapechar&gt;-1
        \yybreak{\cs@tring}%
    \else
        \yybreak{}%
    \yycontinue
}

\def\cs@tring{%
    \ifnum\escapechar&gt;255
        \yybreak{}%
    \else
        \yybreak{\expandafter\eatone\string}%
    \yycontinue
}

% other parser and lexer variables

\newtoks\pinittoks % a token register to hold the code that switches the parser to a different namespace

% tables

\def\newtable@full#1{%
    \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=%
}

\let\newtable\newtable@full % optimization can change this

% constants

\def\constset#1#2{%
    % a \mathchardef would be nicer but it cannot handle negative numbers
    \expandafter\def\csname #1\parsernamespace\endcsname{#2}%
    \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 %
    \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%
    \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{% 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{% 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{%
    \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&lt;count&gt;}% this is only (as well as the only action that is) needed for the accelerated stack
}

\def\setcurrentcs#1{%
    \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}%
  \setcntreg{yyn}%
  \setcntreg{yylen}%
  %
  \setcntreg{yyilen}% depth of stack before an inline action
  % \yyval and \yylval will be token registers
  \settokreg{yyval}%
  \settokreg{yylval}%
  \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
  \settokreg{yytextseenpure}%  % as \yytext et al except they collect characters
  \settokreg{yybytepure}%      % with category code 11 (letter) and the same character code
  %
  \setcntreg{yycurrentstate}%
  \setcntreg{yycurrentstatelocal}% a state variable used in eob macros
  \setcntreg{yyc}%
  \setcntreg{yyclocal}% another eob macro variable
  \setcntreg{yyact}%
  \setcntreg{yyg@yyinit}%
  \setcntreg{yyg@yystart}%
  \setcntreg{yyg@yylastacceptingstate}%
  \setcntreg{yycp@}%
  \setcntreg{YYATBOL}%
  \setcntreg{yychar}%
  %
  \setcntreg{yytextlastchar}%
  \setcntreg{yytextseenlastchar}%
  %
  \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
}

% 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;
%
% 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 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&lt;\@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}
}

\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}%
}

\def\setoptopt#1{%
    \expandafter\let\csname optopt[#1]\parsernamespace\endcsname\end
}

% optimization options

\def\optimizeall{%
        % lexer
    \ifnum\optimization&gt;\z@
        \optimize{yynxt}%
        \optimize{yyaccept}%
        \optimize{yydef}%
        \optimize{yychk}%
        \optimize{yybase}%
        \optimize{yyec}%
        \optimize{yymeta}%
        \tracingstats=\@ne
    \fi
        % parser
    \ifnum\optimization&gt;\@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{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
    \expandafter\yystringempty\expandafter{#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

%% character class checking: #1 is the character, #2 is the character class control sequence

\newif\ifinclass

\def\ifclassof#1\is#2{%
  \tempca#1\relax
  \expandafter\checkclass#2\end
}

\def\checkclass#1{%
  \ifx#1\end
      \let\next\relax
      \inclassfalse
  \else
      \ifnum`#1=\tempca
          \let\next\classend
          \inclasstrue
      \else
          \let\next\checkclass
      \fi
  \fi
  \next
}

\tempca=\catcode`\^^A
\catcode`\^^A=12 % so that the characters inside sequences get the appropriate catcodes

\def\classend#1\end{}

\def\setspecialchars#1{%
  \toksa{}%
  \tempca=`\ %
  \loop
      \advance\tempca\@ne
      \tempcb=\fgetelemof{yytranslate}\at\tempca\relax
      \ifnum\tempcb&gt;\tw@
          \tempcb=\uccode`^^A\uccode`^^A=\tempca
          \uppercase{\edef\next{\toksa{\the\toksa^^A}}}\next
          \uccode`^^A=\tempcb
      \fi
  \ifnum\tempca&lt;\@cclv
  \repeat
  \edef#1{\the\toksa}%
}

\newif\iftraceswitchlabels
\traceswitchlabelstrue

\def\setspecialcharsfrom#1{%
  \toksb\expandafter{#1}%
  \iftraceswitchlabels
      \edef\next{\toksa{\expandafter\noexpand\csname &lt;state: \expandafter\eatone\string#1&gt;\endcsname}}\next
      \expandafter\let\the\toksa\empty
  \else
      \toksa{}%
  \fi
  \tempcb=\uccode`\^^A\relax
  \expandafter\s@tspecialcharsfrom\the\toksb\end
  \edef#1{\the\toksa}%
  \uccode`\^^A=\tempcb
}

\def\s@tspecialcharsfrom{%
  \futurelet\next\s@tsp@cialcharsfrom
}%

\def\s@tsp@cialcharsfrom{%
  \ifcat\space\noexpand\next
      \expandafter
      \s@tsp@cialch@rsfr@m
  \else
      \expandafter
      \s@tsp@cialch@rsfrom
  \fi
}

\def\s@tsp@cialch@rsfr@m{%
  \afterassignment\s@tspecialcharsfrom\let\next= % this is the optional space
}

\def\s@tsp@cialch@rsfrom#1{%
  \toksb{#1}%
  \ifx\next\bgroup % this is an action group
      \edef\next{\toksa{\the\toksa{\the\toksb}}}\next
      \let\next\s@tspecialcharsfrom
  \else
      \let\default\specchardefault
      \iftracedfa % to avoid conflicts while tracing actions
          \tracedfafalse
          \switchon{\the\toksb}\in\speccharswitch
          \tracedfatrue
      \else
          \switchon{\the\toksb}\in\speccharswitch
      \fi           
  \fi
  \next
}%

\def\speccharswitch{%
    \end {%
        \let\next\relax
    }
    \raw \rawcode \classexpand \meanit \statecomment {%
        %
    }
}

\def\specchardefault{%
    \uccode`\^^A\expandafter`\the\toksb
    \uppercase{\edef\next{\toksa{\the\toksa^^A}}}\next
    \let\next\s@tspecialcharsfrom
}

\def\raw#1\raw{%
  \toksb{#1}%
  \concat\toksa\toksb
  \s@tspecialcharsfrom
}

\def\rawcode#1{%
  \ifx#1\rawcode
      \let\next\s@tspecialcharsfrom
  \else
      \uccode`\^^A=#1\relax
      \uppercase{\edef\next{\toksa{\the\toksa^^A}}}\next
      \let\next\rawcode
  \fi
  \next
}

\def\classexpand#1{%
  \toksb\expandafter{#1}%
  \concat\toksa\toksb
  \s@tspecialcharsfrom
}

\def\meanit#1{%
  \toksb\expandafter{\meaning#1}%
  \concat\toksa\toksb
  \s@tspecialcharsfrom
}

\def\statecomment#1\statecomment{\edef\next{\toksa{\the\toksa
    \expandafter\noexpand\csname (#1)\endcsname}}\next\s@tspecialcharsfrom}

\def\putother#1\in#2{%
    {%
        \uccode`\^^A=#1\relax
        \uppercase{\edef\next{#2{^^A}}}%
        \expandafter
    }\next
}

% listing all the rules in a macro

\def\listrules{%
  \tempcb=\tw@ % start with a user-set rule
  \loop
      \listrule
  \ifnum\tempcb&lt;\YYNRULES\relax
      \advance\tempcb\@ne
  \repeat
}

\catcode`\$=11

\def\listrule{%
  \tempcc=\fgetelemof{yyrone}\at\tempcb\relax % get the symbol this rule derives
  \edef\next{\toksa{\fgetelemof{yytname}\at\tempcc}}\next
  \expandafter\checkforimplicit\the\toksa $@\end%$
  \ifimplicit
      \edef\next{\toksc{\noexpand\ih{\the\toksa}}}\next
      \edef\next{\toksa{\noexpand\implicitrule[\the\toksa]}}\next
  \else
      \edef\next{\toksa{\the\tempcc}}\next
      \toksc{}%
  \fi
  \appendr\toksa{:}%
  \toksb{}%
  \tempcc=\fgetelemof{yyprhs}\at\tempcb\relax
  \tempcd=\fgetelemof{yyrhs}\at\tempcc\relax
  \listr@le
  \edef\next{\newsymswitch{\the\newsymswitch\the\toksa\def{\the\toksc:\the\tempcb}\noexpand\ruleor}}\next
}

\def\implicitsymbol#1{}%

\newif\ifimplicit

\def\listr@le{%
  \ifnum\tempcd&gt;\m@ne
      \ifnum\tempcd&lt;\YYNTOKENS\relax % it is a terminal
          \edef\next{\toksb{\the\tempcd}}\next
      \else
          \edef\next{\toksb{\fgetelemof{yytname}\at\tempcd}}\next
          \expandafter\checkforimplicit\the\toksb $@\end%$
          \ifimplicit
              \appendl\toksc{\noexpand\imn{\the\toksb}}
              \toksb{@implicit@}%
          \else
              \edef\next{\toksb{\the\tempcd}}\next
          \fi
      \fi
      \appendr\toksa{ }\concat\toksa\toksb
      \advance\tempcc\@ne
      \tempcd=\fgetelemof{yyrhs}\at\tempcc\relax
      \let\next\listr@le
  \else % this is the end of the rhs
      \let\next\relax
  \fi
  \next
}

\def\checkforimplicit#1$@#2\end{% $
  \def\next{#1}%
  \ifx\next\empty
      \implicittrue
  \else
      \implicitfalse
  \fi
}
\catcode`\$=3

% symbol switch macros

\newtoks\oneimplicitrule

% inline explicit symbolic names

\def\itermstack#1#2{%
  \toksa=\oneimplicitrule
  \appendl\toksa{\noexpand\lhs{#1}{#2}}%
  \expandafter
    \yypush
  \expandafter
    {\the\toksa}\on\yyirulestack
  \appendr\oneimplicitrule{\noexpand\implicitterm{#1}{#2}}%
}

\def\makeisymnames#1:#2\end{%
  \tempcc=#2\relax
  \def\next{#1}%
  \ifx\next\empty
      \relax
  \else
      \let\imn\assigninames
  \fi
  #1%
}

\def\assigninames#1{%
  \yypop\yyirulestack\into\toksc
  \def\sts##1{##1}%
  \savehcs{symn}{\term\lhs\implicitterm\onerule}%
  \edef\next{\noexpand\onerule{\the\toksc}}%
  \edef\next{\toksc{\next}}\next
  \toksb{\implicitrule[#1]:\def}%
  \yyreplacestring\toksb\in\newsymswitch\with\toksc
  \restorecs{symn}{\term\lhs\implicitterm\onerule}%
}

\def\oneruleid#1#2{%
  \oneimplicitrule{}%
  \yyinitstack\yyirulestack
  \toksb{#1}%
  #1%
  \makeisymnames#2\end
}

\def\termexsymname#1#2{%
  \appendr\oneimplicitrule{\noexpand\term{#1}{#2}}%
}

\def\iruleplaceholder#1:\def#2{}

\def\setexplicitinlinerules#1{%
  \let\onerule\oneruleid
  \let\term\termexsymname
  \let\lhs\eattwo
  \let\implicitterm\itermstack
  \let\ruleor\relax
  \let\ih\eatone
  \let\imn\eatone
  \let\implicitrule\iruleplaceholder
  \the#1% set explicit names  
}

\catcode`\^^A=\tempca

\def\makesymrefs#1{% #1 is the symbolic rule switch
    \let\ruleor\or
    \nameflagtoks{}%
    \edef\next{\setsncommands{\noexpand\or\space\harmlesscomment\space (rule 0)^^J%
                              \noexpand\or\space\harmlesscomment\space (rule 1)^^J}}\next
    \edef\next{\unsetsncommands{\noexpand\or\space\harmlesscomment\space (rule 0)^^J%
                                \noexpand\or\space\harmlesscomment\space (rule 1)^^J}}\next
    \yyn=\tw@
    \loop
        \yylen=\fgetelemof{yyrtwo}\at\yyn\relax
        \ifnum\yylen&gt;\z@
        \else 
            \yylen=\fgetelemof{yyrthree}\at\yyn\relax
        \fi
        \xm@kesymrefs#1%
        \xm@k@symrefs#1%
        \addseparator
    \ifnum\yyn&lt;\YYNRULES
        \advance\yyn\@ne
    \repeat
}

% these macros are here to hide \else and \fi tokens

\def\xm@kesymrefs#1{\expandafter\m@kesymrefs\expandafter\yyn\the#1\else\fi} % explicit names
\def\xm@k@symrefs#1{\expandafter\m@k@symrefs\expandafter\yyn\the#1\else\fi} % implicit names

\def\m@kesymrefs#1{%
  \let\onerule\rulesymsetup
  \ifcase#1\or\or % skip the first two rules
}

\def\m@k@symrefs#1{%
  \let\onerule\r@lesymsetup
  \ifcase#1\or\or % skip the first two rules
}

\def\addseparator{%
    \sprintrule\yyn\to\toksa
    \edef\next{\setsncommands{\the\setsncommands\noexpand\or\space\harmlesscomment\the\toksa^^J}}\next
    \edef\next{\unsetsncommands{\the\unsetsncommands\noexpand\or\space\harmlesscomment\the\toksa^^J}}\next
    \the\nameflagtoks
    \nameflagtoks{}%
}

\def\rulesymsetup#1#2{%
  \let\term\termsymname
  \let\lhs\lhssymname
  \let\implicitterm\term
  \tempca\@ne
  #1% set explicit names
}

\newtoks\setsncommands
\newtoks\unsetsncommands

\def\termsymname#1#2{% set the symbolic name, if it is nonempty
  \def\next{#2}%
  \ifx\next\empty
  \else % there is a symbolic name
      \expandafter\ifx\csname$[#2]\endcsname\relax% i$ this name unassigned? 
          \setnameflag{#2}\end % ... this name has been explicitly set
          \setuprefs{#2}{\the\tempca}%
      \else
          \errmessage{ambiguous symbolic name: #2}%
      \fi
  \fi
  \advance\tempca\@ne
}

\newtoks\nameflagtoks

\def\setnameflag#1#2{%
    \toksa\expandafter{\csname$[#1]sym\endcsname}% $
    \edef\next{\let\the\toksa\noexpand#2}\next
    \appendr\nameflagtoks{\noexpand\unsetnameflag{#1}}%
}

\def\unsetnameflag#1{%
    \toksa\expandafter{\csname$[#1]sym\endcsname}% $
    \edef\next{\let\the\toksa\relax}\next
}

\def\unsetsymname#1{%
    \toksa\expandafter{\csname$[#1]\endcsname}% $
    \edef\next{\let\the\toksa\relax}\next
}

\def\unsetsym#1{%
    \toksa\expandafter{\csname$[#1]\endcsname}% $
    \toksb\expandafter{\csname$$[#1]\endcsname}% $
    \edef\next{\let\the\toksa\relax\let\the\toksb\relax}\next
}

\def\lhssymname#1#2{% set an explicit symbolic name for the left hand side
  \setuplhsref{#2}%
  \setnameflag{#2}\end % signal that this name has ben explicitly set
}

% the code below is just an example. One has to figure out how to record percent symbols and other 
% dangerous \TeX\ symbols; it is rather slow, a faster two stage scheme can be envisioned 
% where the first stage builds the command while iterating over the rule numbers; this is left as an exercise. 

\let\hc\harmlesscomment
\let\uu\space
\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
    \edef\next{\toksb{\space\space\noexpand\setsym{\the\toksa}{#2}\hc^^J\uu\uu\hc\hc\hc\uu#1 --&gt; #2^^J}}\next
    \edef\next{\toksc{\space\space\noexpand\unsetsym{\the\toksa}\hc^^J\uu\uu\hc\hc\hc\uu#1 --&gt; \relax^^J}}\next
    \concat\setsncommands\toksb
    \concat\unsetsncommands\toksc
}%

\def\setuplhsref#1{%
    \def\next{#1}%
    \ifx\next\empty
    \else
        \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
        \edef\next{\toksb{\uu\uu\noexpand\setlhs{\the\toksa}\hc^^J\uu\uu\hc\hc\hc\uu#1 --&gt; $$^^J}}\next
        \edef\next{\toksc{\uu\uu\noexpand\unsetsym{\the\toksa}\hc^^J\uu\uu\hc\hc\hc\uu#1 --&gt; \relax^^J}}\next
        \concat\setsncommands\toksb
        \concat\unsetsncommands\toksc
    \fi
}%

\def\sprintrule#1\to#2{%
    \tempcc=#1\relax  
    \tempcd=\fgetelemof{yyrone}\at\tempcc\relax
    \edef\ruleline{\space(rule \number#1)\space\fgetelemof{yytname}\at\tempcd:}%
    \tempcd=\fgetelemof{yyprhs}\at\tempcc\relax
    \tempcc=\fgetelemof{yyrhs}\at\tempcd\relax
    \ifnum\tempcc&gt;\m@ne
        \fillruleline
    \else
        \edef\ruleline{\ruleline\space&lt;empty&gt;}%
    \fi
    #2\expandafter{\ruleline}%
}

\def\fillruleline{%
    \edef\ruleline{\ruleline\space\fgetelemof{yytname}\at\tempcc}%
    \advance\tempcd\@ne
    \tempcc=\fgetelemof{yyrhs}\at\tempcd\relax
    \ifnum\tempcc&gt;\m@ne
        \let\next\fillruleline
    \else
        \let\next\relax
    \fi
    \next
}

\def\r@lesymsetup#1#2{%
  \let\term\termsymextra
  \let\lhs\lhssymextra
  \let\implicitterm\term
  \tempca=\@ne
  #1% set implicit names
}

\def\termsymextra#1#2{% set an implicit symbolic name: 
                      %   1) if it has not been defined yet, define it
                      %   2) if it is defined implicitly, make it \def
  \expandafter\let\expandafter\next\csname$[#1]\endcsname% $ this is the name we are trying to define
  \ifx\next\relax % it is not defined yet
      \setuprefs{#1}{\the\tempca}%
  \else % already defined
      \expandafter\ifx\csname$[#1]sym\endcsname\end % it i$ an existing explicit symbolic name, done
      \else
          \expandafter\ifx\csname$[#1]sym\endcsname\noindent % it i$ an existing implicit symbolic name of lhs, overwrite it
              \setuprefs{#1}{\the\tempca}%
          \else
              \edef\next{\toksa{\space\space\noexpand\locksymname{#1}\harmlesscomment^^J}}\next
              \edef\next{\toksb{\space\space\noexpand\unlocksymname{#1}\harmlesscomment^^J}}\next
              \concat\setsncommands\toksa % symbolic name defined implicitly, disallow it
              \concat\unsetsncommands\toksb
          \fi
      \fi
  \fi
  \advance\tempca\@ne
}

\def\locksymname#1{\expandafter\let\csname$[#1]\endcsname\def} %$
\def\unlocksymname#1{\expandafter\let\csname$[#1]\endcsname\relax} %$

\def\lhssymextra#1#2{% set the name of the left hand side implicitly
  \expandafter\let\expandafter\next\csname$[#1]\endcsname%$
  \ifx\next\relax % not defined yet
      \setuplhsref{#1}%
      \setnameflag{#1}\noindent % this lhs name has been implicitly set
  \fi % it is already defined
}

\catcode`\^^A=\tempca

% the number below (15) is not chosen randomly but is designed to follow the conventions
% outlined in plain.tex:
%
% The following counters are reserved:
%       ...
%       10  count allocation
%       11  dimen allocation
%       12  skip allocation
%       13  muskip allocation
%       14  box allocation
%       15  toks allocation
%       ...
%
% Here it is given a symbolic name for convenience. Note that this allocation is
% needed even if only the yyfaststack.sty stack macros are used (it is used in the
% mechanism that makes \yy0{\the\yy1\the\yy2} assignments possible).

\countdef\toptoks=15 % register responsible for token allocations 

% value and state stack access macros: these may be replaced by the macros in yyfaststack.sty

\def\yyreadvstack#1\upto#2{% assume that #2 &gt; 0
    \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&lt;\@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 &gt; 0
    \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&lt;\@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 read the stack in `natural order' (see also yyfaststack.sty)
\def\yypeekustack#1{% we do not compute anything unless the postprocessor
                    % detected an implicit rule
    \ifnum\number\yycomputeilength{\number\yyn}&gt;\z@
        \yybreak{\edef\sts{\noexpand\peelstackreverse{1}{\expandafter
                 \xincrement\expandafter{\number\toptoks}}}#1\relax}%
    \else
        \yybreak{}%
    \yycontinue
}

\long\def\peelstackreverse#1#2#3{%
    \ifnum#2&lt;\@cclvi % we have not reached the maximum allocated number of token registers
        \expandafter\toksdef\csname$$$'#1\endcsname=#2 
        \toks#2{#3}%
    \fi
    \ifnum\number\yycomputeilength{\number\yyn}&gt;#1 %
        \edef\sts{\noexpand\peelstack{\xincrement{#1}}{\xincrement{#2}}}%
    \else
        \let\sts\eatone
    \fi
}

\def\yyimplicitlengthset#1#2{\expandafter\def\csname ilength$$[#1]\endcsname{#2}}

\def\yycomputeilength#1{%
    \expandafter\ifx\csname ilength$$[#1]\endcsname\relax
        \yybreak{0 }%
    \else
        \yybreak{\csname ilength$$[#1]\endcsname\space}%
    \yycontinue
}

% macros to support new printing routines

\def\yypeeksstack#1\upto#2\withprefix#3{% assume #2 &gt; 0
    \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
}

% stack variable access

\def\ym#1){%
  \ifnum#1&lt;\@ne
      \putyyvalt
  \else
      \ifnum#1&gt;\yyilen
          \errmessage{parameter out of range (#1\space out of\space \the\yyilen)}%
      \else
          \expandafter\putyytoksx\csname$$'#1\endcsname
      \fi
  \fi
}

\def\yn#1#{%
  \ifnum#1&lt;\@ne
      \putyyval
  \else
      \ifnum#1&gt;\yyilen
          \errmessage{parameter out of range}%
      \else
          \expandafter\putyyassignment\csname$'\number#1\endcsname%$
      \fi
  \fi
}

\def\yx#1[{%
  \expandafter\ifx\csname$[#1]\endcsname\yyval%$
      \putyyvalt
  \else
      \expandafter\ifx\csname$[#1]\endcsname\def%$
          \errmessage{reference to ambiguous symbolic name: #1}%
      \else
          \expandafter\putyytoksx\csname$$[#1]\endcsname
      \fi
  \fi
}

\def\yz#1]{%
  \expandafter\ifx\csname$[#1]\endcsname\yyval%$
      \putyyval
  \else
      \expandafter\ifx\csname$[#1]\endcsname\def%$
          \errmessage{reference to ambiguous symbolic name: #1}%
      \else
          \expandafter\putyyassignment\csname$[#1]\endcsname%$
      \fi
  \fi
}

\def\putyyval\else#1\fi\fi{%
  \fi\yyvalx
}

\def\yyvalx#1{%
  \edef\next{\yyval{#1}}\next
}

\def\putyyvalt\else#1\fi\fi{%
  \fi\yyval
}

\def\putyyassignment#1\fi\fi{%
  \fi\fi\p@tyyassignment#1%
}

\def\putyytoksx#1\fi\fi{%
  \fi\fi#1%
}

\def\p@tyyassignment#1#2{%
  \yystringempty{#2}{#1}{#2\expandafter{#1}}%
}

% natural order stack access macros

\def\p@twwassignment#1#2{%
    \edef\sts{\noexpand\p@@wwassignment{\expandafter\xdecrement\expandafter{\number#1}}}%
    \expandafter\def\expandafter\sts\expandafter{\sts{#2}}% define the stack iterator
    \yyvsa\empty % execute the stack
}

\def\p@@wwassignment#1#2#3{%
  \ifnum#1=\z@ % we have got to the element we need
      \yybreak{\yystringempty{#2}{#3}{#2{#3}}\let\sts\eatone}%
  \else % keep descending into the stack
      \yybreak{\edef\sts{\noexpand\p@@wwassignment{\xdecrement{#1}}}%
               \expandafter\def\expandafter\sts\expandafter{\sts{#2}}}%
  \yycontinue
}

\def\yy#1{%
  \ifx#1[%
      \yybreak{\yz}%
  \else
      \ifx#1]%
          \yybreak@{\yx}%
      \else
          \ifx#1(%
              \yybreak@@{\ym}%
          \else
              \yybreak@@{\yn#1}%
          \fi
      \fi
  \yycontinue
}

% a macro to access the value stack in the direct order, i.e.\ from right to left
% no \yylen is necessary

\def\bb#1#{%
  \ifnum#1&lt;\@ne
      \yybreak{\yyvalx}%
  \else
      \yybreak{\p@twwassignment{#1}}%
  \yycontinue
}

% this macro should only be inserted by the preprocessor, it accesses
% the stack in a `natural' order which is the opposite of how `native'
% bison does it

\def\yg#1#2#3{% #1 is the `native' bison index (e.g. for a: b c d rule,
              % b is $1
              % #2 is the `natural' index (so b would be $3 for the
              % rule above
              % #3 is the implicit `yyilen' (see yyparse.sty for more information)
    \ifnum\yyilen=\z@ % this is probably an inline action, so yyreduce
                      % will only generate the `natural' indexed token
                      % registers
        \yybreak{\csname $$$'#2\endcsname}%
    \else
        \yybreak{\ym#1)}% save one level of expansion ...
    \yycontinue
}

% symbolic name macros that prepare the environment for the use of the stack access macros above

\def\setsymcs#1#2{%
    \toksa{}\numberstochars#1\end
    \toksb\expandafter{\csname$[\the\toksa]\endcsname}% $
    \toksc\expandafter{\csname$'#2\endcsname}% $
    \edef\next{\let\the\toksb\the\toksc}\next
}

\def\setsymtr#1#2{%
    \toksa{}\numberstochars#1\end
    \toksb\expandafter{\csname$$[\the\toksa]\endcsname}%
    \toksc\expandafter{\csname$$'#2\endcsname}%
    \edef\next{\let\the\toksb\the\toksc}\next
}

\def\setlhs#1{%
    \toksa{}\numberstochars#1\end
    \toksb\expandafter{\csname$[\the\toksa]\endcsname}% $
    \edef\next{\let\the\toksb\yyval}\next
}

\def\setsym#1#2{%
    \setsymcs{#1}{#2}%
    \setsymtr{#1}{#2}%
}

% message output

\def\ferrmessage#1{{\newlinechar`\^^J\immediate\write16{\parsernamespace::#1^^J}}}

\newif\ifbootstrapmode
</pre></body></html>