diff options
Diffstat (limited to 'support/splint/tex/yyinit.sty')
-rw-r--r-- | support/splint/tex/yyinit.sty | 614 |
1 files changed, 528 insertions, 86 deletions
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 |