% Copyright 2012-2022, 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 . % assigning symbolic names to production terms (this is only a demonstration) % no attempt is made to make this code modular or namespace safe; % the approach is not very elegant and can stand a lot of improvement; % it was decided against such optimization to present a more explicit demonstration % of the procedures \def\makesymbols{% \ifsymdemo \restorecslist{symbols}\yyunion \toksa{}\toksb{}\toksc{}\toksd{}% %\showthe\newsymswitch \the\table \global\newsymswitch\newsymswitch \else \newsymswitch{}% otherwise \yysymswitch is trying to expand the wrong names (\namepair is not present to do \csname ... ) \fi } % symbolic reference name parser \newtoks\newsymswitch \newread\symnames \newwrite\symbolicswitch \newif\ifsymdemo \symdemotrue \ifbootstrapmode \symdemofalse \fi \ifsymdemo \def\inamespace{[intermediate]}% \let\parsernamespace\inamespace \let\hostparsernamespace\mainnamespace % purely for testing reasons \pinittoks{}% \input cweb/gyytab.tex % this should be the parser that will be used later % in this case it is just an example \edef\tointermediateparser{% \let\noexpand\parsernamespace\noexpand\inamespace % switch to the new namespace \the\pinittoks % restore all the tables, tokens and constants, and stacks \let\noexpand\getcurrentparser\noexpand\tointermediateparser }% \settokens % this simply assigns values to tokens where the name of each token is taken out of yytname ... \input bo.tok % this will set up token equivalences in the namespace above ... % those are the values gleaned during the bootstrapping stage. % in the general case, one needs to run a bootsrapping (or similar) % parser to extract the token information. \optimizeall % this is necessary for correct rule listing in the output stage: % otherwise \fgetelemof will use the current value of the \yy... token registers which % will hold the values of the full parser that is loaded next \newsymswitch{}% \listrules % ... to be used while listing the rules % note that we do not bother to set up a lexer for this parser (even though we already have one and the % \optimizeall macro above will create a set of associative tables for it---this is merely an unwanted % sideffect); after the rules have been listed, the intemediate parser is no longer needed. %\showthe\newsymswitch \def\fullnamespace{[full]}% this is the parser that parses the bison grammar from a raw % bison file; it can play a role of the bootstrap parser for % the grammar above, as well, since its input is a complete % bison file; note that it cannot be a bootstrap parser for itself % because it will reject any input that does not form a complete % bison file; this is why a special grammar was created that includes % only a small subset of the full set of productions (%token rules only) to % serve as a bootstrap grammar. %\tomainparser % this will set the value of \setflexstates, so that, if the lexer initialization % below is omitted, the \setflexstates macro can still be used to correctly set the % lexer states \let\parsernamespace\fullnamespace \pinittoks{}% %% \input cweb/fyytab.tex \input cweb/ltab.tex % we reinitialize the lexer out of necessity: % \collecttokennames needs to know how to switch % between two lexer/parser environments so both states % have to be preserved; if one is sure that % grammar_declarations will not used in the productions % part of the file, this can simply be disabled \settokens \setflexstates % the main lexer can be reused in this case; the states still need to be set up \input bo.tok % set up the tokens for the bison grammar parser \newparserstate \newlexerstate \newlexerstateextra % \setnulstack{yyirulestack}% % \edef\tofullparser{% \let\noexpand\parsernamespace\noexpand\fullnamespace % switch to the new namespace \the\pinittoks % restore all the tables, tokens and constants, and stacks \let\noexpand\getcurrentparser\noexpand\tofullparser }% \optimizeall \toksa{\input bg.y}% start building the parsing command % this has to be done carefully, since all the characters input % from the parser file have to be `harmless', so their categories % have to be reset; in order for the parser to be able to stop, % appropriate command sequences would have to be inserted at the end \toksb{\yyeof\yyeof\endparseinput\endparse \let\yyinput\yyinputold \undoascii \ifyyparsefail \errmessage{could not process symbols}% \else \tointermediateparser % the parsing is finished, so we have two very long strings: % o the rules of the hosted parser ([intermediate]) % o the rules of the same parser just parsed % these two strings are used to associate the symbolic names % (which only exist in the second list) to the rule numbers and % the relevant terms; % switching the parse namespace above is done so that the term % indices are looked up in the appropriate table %\showthe\table \makesymbols % list all the rules deriving explicit non-terminals %\showthe\newsymswitch \setexplicitinlinerules\newsymswitch % process implicit non-terminals resulting from inline actions %\showthe\newsymswitch \makesymrefs\newsymswitch % create the switch to be used by the parser (\yyparse) \fi }% % build the command to create the symbolic name switch \toksc{\tofullparser\basicparserinit\bisonparserinit\bisonparserdatainit \let\yyinputold\yyinput \let\yyinput\yyinputtrivial % a demo of a stripped down, slightly faster input routine \doascii{11}\expandafter\yyparse}% \edef\next{\the\toksc\the\toksa\relax\the\toksb}\next % \relax is to stop \TeX\ from trying to expand the file name further % it is not flagged as a bad character because it is part of the epilogue \immediate\openout\symbolicswitch=\jobname.sns % \edef\next{\setsncommands{\def\noexpand\symswitch\hashletter1{\harmlesscomment^^J\noexpand\ifcase\hashletter1\relax \harmlesscomment^^J\the\setsncommands \noexpand\else\harmlesscomment^^J% \noexpand\fi\harmlesscomment^^J% }\harmlesscomment^^J^^J}}\next \edef\next{\unsetsncommands{\def\noexpand\symswitchoff\hashletter1{\harmlesscomment^^J\noexpand\ifcase\hashletter1\relax \harmlesscomment^^J\the\unsetsncommands \noexpand\else\harmlesscomment^^J% \noexpand\fi\harmlesscomment^^J% }\harmlesscomment^^J^^J}}\next {\newlinechar=`\^^J \immediate\write\symbolicswitch{\the\setsncommands\the\unsetsncommands}}% \immediate\closeout\symbolicswitch \tomainparser % go back to the main parser % % \flex\ parser test % {% \toflexreparser \basicparserinit \flexreparserinit \flexreparserdatainit \yyBEGIN{SECT2}% \flin@ruletrue % special status of `\yl' in \CWEB\ makes the following workaround necessary % if the code is unsed inside a \CWEB\ file %|@t}\expandafter\yyparse\space [a-b]*(c|d|e)?\yyeof\yyeof\endparseinput\endparse{@>| \expandafter\yyparse\space [a-b]*(c|d|e)?\yyeof\yyeof\endparseinput\endparse \ifyyparsefail\else \ferrmessage{done processing flex}% \fi }% % {% \def\flnamespace{[flex]} \let\parsernamespace\flnamespace \toflexparser \basicparserinit %\flexparserinit \flexparserdatainit \yylessusedtrue % TODO: put it in the \genericparser command \let\f@nishparse\finishparse \def\finishparse{\endinput\message{end of input}\relax\let\cleanupcs\f@nishparse}% \def\next{% \catcode`\\=12 \catcode`\^^J=12 \catcode`\%=12 \catcode`\^^M=12 \catcode`\{=12 \catcode`\}=12 \catcode`\#=12 \catcode`\_=12 %\yydebugmost \expandafter\yyparse\input cweb/lo.l \cleanupcs\yyeof\yyeof\endparseinput\endparse % note that the space after the file name is necessary \ifyyparsefail \errmessage{stopped}% \fi \yydebugnone \basicparserinit \expandafter\yyparse\input cweb/fil.l \cleanupcs\yyeof\yyeof\endparseinput\endparse % note that the space after the file name is necessary }\expandafter\next % to lock the \catcode of the brace }% \fi