diff options
Diffstat (limited to 'support/splint/examples/xxpression/xymmap.sty')
-rw-r--r-- | support/splint/examples/xxpression/xymmap.sty | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/support/splint/examples/xxpression/xymmap.sty b/support/splint/examples/xxpression/xymmap.sty new file mode 100644 index 0000000000..3d36bae920 --- /dev/null +++ b/support/splint/examples/xxpression/xymmap.sty @@ -0,0 +1,155 @@ +% Copyright 2012-2015, Alexander Shibakov +% This file is part of SPLinT +% +% SPLinT is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% SPLinT is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with SPLinT. If not, see <http://www.gnu.org/licenses/>. + +% assigning symbolic names to production terms (this is only a demonstration) + +\def\makesymbols{% + \restorecslist{symbols}\yyunion + \toksa{}\toksb{}\toksc{}\toksd{}% + \the\symstream + \global\newsymswitch\newsymswitch +} + +% symbolic reference name parser + +\newtoks\newsymswitch +\newread\symnames + +\newwrite\symbolicswitch + +\def\inamespace{[intermediate]}% +\let\parsernamespace\inamespace +\let\hostparsernamespace\mainnamespace % purely for testing reasons +\pinittoks{}% +\input ptab.tex % this is the enhanced expression parser +\edef\tointermediateparser{% + \noexpand\savefullstate % unnecessary + \noexpand\savefullstateextra % unnecessary + \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 xxpression.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. + % this is only needed if the bison file contains a definition that + % lists both the idenitifier and a string as names for a token but the grammar + % uses the identifier version at least once: + % (say, %token IDENTIFIER "identifier"; is used as well as + % ... + % token: + % IDENTIFIER { ... } + % ... + % see the included xxpression.w) +\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 in 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 \drvname.tok % set up the tokens for the bison grammar parser +\newparserstate +\newlexerstate +\newlexerstateextra +% +\setnulstack{yyirulestack}% +% +\edef\tofullparser{% + \noexpand\savefullstate + \noexpand\savefullstateextra + \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 xxpp.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 + \symstream\table + \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\parserinit + \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 + |