summaryrefslogtreecommitdiff
path: root/support/splint/examples/xxpression/xymmap.sty
diff options
context:
space:
mode:
Diffstat (limited to 'support/splint/examples/xxpression/xymmap.sty')
-rw-r--r--support/splint/examples/xxpression/xymmap.sty155
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
+