% 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 . % finish parser initialization \let\yylexreturn\yylexreturnregular \genericparser name: main, ptables: cweb/gyytab.tex, ltables: cweb/ltab.tex, tokens: \drvname.tok, asetup: {}, dsetup: \newlexerstateextra, rsetup: \noexpand\savefullstateextra, optimization: \optimizeall;% % prologue parser \genericparser name: prologue, ptables: cweb/dyytab.tex, ltables: cweb/ltab.tex, tokens: \drvname.tok, asetup: {}, dsetup: \newlexerstateextra, rsetup: \noexpand\savefullstateextra, optimization: \optimizeall;% % parser for term names: this is not really a great idea in itself but rather an % illustration of what is possible \genericparser name: small, ptables: cweb/small_tab.tex, ltables: cweb/small_dfa.tex, tokens: {}, asetup: {}, dsetup: {}, rsetup: \noexpand\savefullstateextra, optimization: \optimizeall;% \tomainparser \input yytexlex.sty \let\unparse\yyid \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 } \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 } % stage two macros: parsing \newtoks\symstream \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 \tomainparser \doparse{#1}% \ifyyparsefail \toprologueparser \doparse{#1}% \ifyyparsefail \else \ifsaveparseoutput{\newlinechar=`^^J\immediate\write\exampletable{^^J\harmlesscomment parsed table (prologue): ^^J\the\table}}% \fi \fi \else \ifsaveparseoutput{\newlinechar=`^^J\immediate\write\exampletable{^^J\harmlesscomment parsed table (grammar): ^^J\the\table}}% \fi \fi } % stage three macros: typesetting \def\tlskip{\z@} \def\tfskip{\parindent} \def\typesetalltables{% \begingroup \ifchecktable \ifsaveparseoutput {\newlinechar=`^^J\immediate\write\exampletable{^^J\harmlesscomment stashed stream:^^J\the\yystash}}% \else \errmessage{parsed table: \the\table^^J^^Jstashed stream: \the\yystash}% \fi \fi \symstream\table \table{}% \setprodtable \the\symstream\relax \postoks{}\pushothertables \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 \parindent1em \checkforpropertable\table \tabskip\tfskip \ruletableset \ifchecktable \message{remaining stash: \the\yystash}% \fi \toksa{}\the\yystash \cleanstash\stripstash\checkforccode \ifchecktable \message{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 \endgroup } % 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 \def\ruletableset{% \par \vskip-\baselineskip \ifx\gatoks\relax \else \table\expandafter{\the\table\gatoks}% \fi \setbox0\vbox\expandafter{\expandafter \null\expandafter\prevdepth\the\prevdepth \halign \ifpropertable to \hsize \fi {\hbox to 2em{##\/$\,${\rm:}\hss}\hfil\tabskip\z@&\setallterms{##}&##\hfil\tabskip0pt plus1fil&% \toksa{}##\makestashbox\hfil\tabskip\tlskip\cr \the\table } \expandafter }\expandafter \unvbox\expandafter0\expandafter \prevdepth\the\prevdepth\relax } \def\setallterms#1{\setbox\z@=\hbox{\it#1}\ifsquashterms\hbox to0pt{\unhbox\z@\hss}\else\unhbox\z@\fi\hfil} % 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 % solution below works as well. \def\setglobalalignrules#1{% \def\gatoks{% \omit\hfil&\omit\hfil&\omit\hfil&\omit\hfil\hbox to #1{\hfil}\cr \noalign{\vskip-\baselineskip}% %\noalign{\centerline{$\diamond$}} }% } \setglobalalignrules{3 in}% % to align all the actions across the document, comment out the next line \let\gatoks\relax \def\checkforccode{% \setbox0=\vbox{\setlazyc\the\toksa}% } \def\setlazyc{% \hidecs{\1\4\5\6\8}% } \newif\ifdisplaytokenraw \def\toksdefline#1#2#3#4#5{% #1 is the parsed version of the internal bison name % #2 is the index entry % #3 is the type % #4 is the explicit value % #5 is the parsed version of the string value \ifnum\tempca=\z@ \tokdectoks\expandafter{\the\tokdectoks&{#2}#1\hfil\cr}% \tempca\tempcb \else \ifnum\tempcb=\tempca \tokdectoks\expandafter{\the\tokdectoks{#2}#1\hfil}% \else \tokdectoks\expandafter{\the\tokdectoks&{#2}#1\hfil}% \fi \advance\tempca\m@ne \fi } \def\attachtokentable{% typesetting the token declarations as part of the grammar \tempcb3 \tempca\tempcb \expandafter\tokdectoks\expandafter{\expandafter}\the\tokdectoks \ifnum\tempca=\tempcb \else \bloop \tokdectoks\expandafter{\the\tokdectoks&\omit\hfil}% \ifnum\tempca=\z@ \else \advance\tempca\m@ne \repeat \tokdectoks\expandafter{\the\tokdectoks\cr}% \fi \toksa{\tt\strut##\hfil\tabskip=0pt plus 1fil}% \bloop \toksa\expandafter{\the\toksa&\tt\strut##\hfil}% \ifnum\tempcb=\tw@ \else \advance\tempcb\m@ne \repeat \toksa\expandafter{\the\toksa&\tt\strut##\hfil\tabskip\z@\cr}% \concat\toksa\tokdectoks \tokdectoks\toksa \edef\next{\table{\the\table\noalign{% \tabskip\parindent \nx\displaytokenrawtrue \halign to\hsize{\the\tokdectoks}% }% }}\next \tokdectoks{}% } % typesetting token lists, precedence declaratins, etc % these belong to yyunion.sty but they use `global' settings that are % too specific to put there \def\attachtypestable{% typesetting the type declarations as part of the grammar \toksa{}\the\typestable \edef\next{\table{\the\table\noalign{% {% \the\toksa }% }% }}\next\typestable{}% } \long\def\onetype#1#2{% \toksb{{% \hbadness\@M \rightskip=\z@ \tempda\hsize \advance\tempda-1in \indent{$\langle$\tt union$\rangle.#1$:}\ \hfill\nobreak\hfill\nobreak\null\penalty1\relax\null\nobreak\hfill \hbox to\tempda{$\vtop{\noindent\hsize\tempda\raggedright #2\strut}$}\par }}% \concat\toksa\toksb } \long\def\flexsstatelist#1{% \toksb{{% \hbadness\@M \rightskip=\z@ \tempda\hsize \advance\tempda-1in \indent{$\langle$\tt states-s$\rangle_{\rm f}$:}\ \hfill\nobreak\hfill\nobreak\null\penalty1\relax\null\nobreak\hfill \hbox to\tempda{$\vtop{\noindent\hsize\tempda\raggedright #1\strut}$}\par }}% \concat\toksa\toksb } \long\def\flexxstatelist#1{% \toksb{{% \hbadness\@M \rightskip=\z@ \tempda\hsize \advance\tempda-1in \indent{$\langle$\tt states-x$\rangle_{\rm f}$:}\ \hfill\nobreak\hfill\nobreak\null\penalty1\relax\null\nobreak\hfill \hbox to\tempda{$\vtop{\noindent\hsize\tempda\raggedright #1\strut}$}\par }}% \concat\toksa\toksb } \def\attachprectable{% typesetting the precedence declarations as part of the grammar \toksa{}\the\prectable \edef\next{\table{\the\table\noalign{% {% \the\toksa }% }% }}\next\prectable{}% } \long\def\oneprec#1#2#3{% \toksc{% \hbadness\@M \rightskip=\z@ \tempda\hsize \advance\tempda-1in \indent }% \toksd{% \ \hfill\nobreak\hfill\nobreak\null\penalty1\relax\null\nobreak\hfill \hbox to\tempda{$\vtop{\noindent\hsize\tempda\raggedright #3\strut}$}\par } \def\next{#2}% \ifx\next\empty \toksb{}% \else \toksb{${}:{}$#2}% \fi \edef\next{\toksb{{$\nx\langle$\nx\bf #1\the\toksb$\nx\rangle$}}}\next \appendr\toksa{{\the\toksc\the\toksb\the\toksd}}% } \def\attachoptionstable{% typesetting the options as part of the grammar \edef\next{\table{\the\table\noalign{% \tabskip\parindent \halign{####\nx\hfil\tabskip\z@&\nx\qquad\nx\it####\nx\hfil\cr \the\opttable }% }% }}\next\opttable{}% } \newif\ifpropertable \def\checkforpropertable#1{{% checking if there is any table material % this is a hack to avoid underfull boxes when there is no actual alignment material in % \halign to \hsize \hbadness\@M \let\noalign\trivialnoalign \let\omit\relax \setbox\z@=\vbox{ \halign {\eatone{##}&\eatone{##}.&\eatone{##}&\eatone{##}\cr \the#1% }% }% \ifnum\wd\z@>\z@ \aftergroup\propertabletrue \else \aftergroup\propertablefalse \fi }} \long\def\trivialnoalign#1{} % macros for processing \Cee\ mode material %\long\def\buildstash#1{\toksa\expandafter{\the\toksa#1}} % = stashed \def\cleanstash{% \ifchecktrim\errmessage{collected stash: \the\toksa}\fi \expandafter\cleanst@sh\the\toksa\packagebox} \def\cleanst@sh{\let\6\testsbox\setbox0=\vbox\bgroup} \def\testsbox{% \ifmmode \let\next\relax \else \egroup \ifnum\wd\z@>\z@ \ifnum\ht\z@>\z@ \let\next\scoopupstash \else \let\next\rebuildstash \fi \else \let\next\rebuildstash \fi \fi \next } \long\def\rebuildstash#1\packagebox{\toksa{#1}\cleanstash} \long\def\scoopupstash#1\packagebox{} \def\packagebox{\egroup\ifnum\wd0>\z@\else\toksa{}\fi} \def\stripstash{% \ifchecktrim\errmessage{before trimming: \the\toksa}\fi \def\6{}\expandafter\stripst@sh\expandafter\ignorespaces\the\toksa\6\str@pst@sh} \def\stripst@sh{\toksa{}\stripst@shi} \long\def\stripst@shi#1\6{% \toksb{#1}\futurelet\next\str@pst@sh } \def\str@pst@sh{% \ifx\next\str@pst@sh \iftrailingreturn \striptrim \fi \concat\toksa\toksb \iftrailingreturn % not done yet \let\next\stripagain \else \let\next\eatone \fi \trailingreturnfalse \else \edef\next{\toksa{\the\toksa\the\toksb\noexpand\6}}\next \def\next{\stripst@shi\relax\ignorespaces}% \trailingreturntrue \fi \next } \def\stripagain#1{\stripstash} \newif\iftrailingreturn \def\striptrim{% \ifchecktable\errmessage{trimming: \the\toksb}\fi \edef\next{\the\toksb}% \expandafter\striptr@m\the\toksb\relax\end } \def\striptr@m #1% \relax (from last \stripst@shi) #2% \ignorespaces (from last \stripst@shi) % intervening spaces #3% \relax #4% ? \end{% % \def\next{#4}% % \ifx\next\empty % \toksc{#3#4}\showthe\toksc \setbox\z@\vbox{#3#4}% \ifnum\wd\z@=\z@ \expandafter\trimreturn\the\toksa\end \toksb{}% \else \ifnum\ht\z@=\z@ \expandafter\trimreturn\the\toksa\end \toksb{}% \else \trailingreturnfalse \fi \fi } \def\trimreturn#1\6\end{% \toksa{#1}% } \def\boxstash{% \ifchecktrim\errmessage{stash contents: \the\toksa}\fi $\vtop{\activateinlinec\tabskip\z@\halign{\strut\ignorespaces##\hfil\cr\the\toksa\crcr}}$} \def\makestashbox{\cleanstash\stripstash\boxstash} \newbox\indentbox \def\activateinlinec{% \setbox\indentbox=\hbox{}% \def\1{\setbox\indentbox\hbox{\box\indentbox\hbox to 3em{\hfil}}}% \def\2{\setbox\indentbox\hbox{\box\indentbox\hbox to -3em{}}}% \def\4{\hbox to -3em{}}% \def\5{}% % \let\6\cr \def\6{% \edef\setindentbox{% \setbox\indentbox\hbox to\the\wd\indentbox{\noexpand\hfil}% \copy\indentbox\ignorespaces }% \expandafter\crcontainer\setindentbox }% \def\7{% \edef\setindentbox{% \setbox\indentbox\hbox to\the\wd\indentbox{\noexpand\hfil}% \copy\indentbox\ignorespaces }% \expandafter\crcontainerspread\setindentbox }% \def\8{\hskip-1em}% \let\$\prodterm } \def\crcontainer{\cr} \def\crcontainerspread{\cr\noalign{\yskip}} % rough version of the term typesetting \def\prodterm{% \futurelet\next\analyzepterm } \def\analyzepterm{% \ifx\next\$% \let\next\pr@dterm \else \ifcat\noexpand\next0% \let\next\pr@dterm \else \let\next\oldmathS \fi \fi \next } \def\pr@dterm#1{% \ifx#1\$% \def\next{\hbox{$\Upsilon$}}% \else \if\noexpand#1[% \let\next\seeksym \else \ifnum`#1<"3A\relax \ifnum`#1>`0\relax \def\next{\seekno#1}% \else \def\next{\hbox{$\Upsilon$}#1}% \fi \else \def\next{\hbox{$\Upsilon$}#1}% \fi \fi \fi \next }% \let\oldmathS\$ \let\$\prodterm \def\seekno{\afterassignment\printterm\tempca}% \def\seeksym#1]{% \hbox{$\Upsilon\kern-1pt{}_{\rm#1}$}} \def\printterm{\hbox{$\Upsilon\kern-1pt{}_{\number\tempca}$}}% \long\def\setproduction#1{% \def\termidxrank{5}% \def\headeridxrank{4}% \def\defidxrank{3}% \def\texcsidxrank{5}% \ninepoint \let\returnexplicitspace\splitexplicitspace \let\acharswitch\texcharadjust \let\onecharswitch\texcsadjust \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 } \def\splitexplicitspace{% \yyinput\{\}% } \def\texcharadjust{ ` {% \yybyte{|}% \expandafter\yycp@\expandafter`\the\yybyte\relax \mkpurebyte \yyreturn } _ {% \yybyte{\_}% \expandafter\yycp@\expandafter`\the\yybyte\relax \mkpurebyte \yyreturn } } \def\texcsadjust{ \n {% \yycp@=\n \mkpurebyte \yyreturn } \^^M {% \yyinput\{\}% } \' {% \expandafter\yyinput\benignescape'% } \\ {% \expandafter\expandafter\expandafter\yyinput\expandafter\benignescape\benignescape% } }% % production typesetting \def\beginprod{% \par \begingroup \b@ginprod } \long\def\b@ginprod#1\endprod{% \setproduction{#1}% \endgroup \par } \def\beginmprod{% $$ \vbox\bgroup \def\checkforpropertable##1{\propertablefalse} % so that the table is set to its natural width \b@ginmprod } \long\def\b@ginmprod#1\endmprod{% \setproduction{#1}% \egroup $$% } % centering productions: works for rule listing only (no token declarations, etc.) \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 \ifx\gindex\UNDEFINED \else \termindextrue \immediate\openout\gindex=\jobname.gdx \fi % stringing all the manuals together (disabled for now) %\newwrite\lastpageinfo %\newread\testeof %\toksa\expandafter{\fin} %\edef\fin{\the\toksa\noexpand\savelastpagenumber} %\def\savelastpagenumber{% % \openout\lastpageinfo=\jobname.lpg% % \write\lastpageinfo{\def\noexpand\contentspagenumber{\number\pageno}\pageno=\noexpand\contentspagenumber \advance\pageno by 1}% % \write\lastpageinfo{\def\noexpand\secno{\number\secno}}% % \closeout\lastpageinfo %}