summaryrefslogtreecommitdiff
path: root/support/splint/tex/yymisc.sty
diff options
context:
space:
mode:
Diffstat (limited to 'support/splint/tex/yymisc.sty')
-rw-r--r--support/splint/tex/yymisc.sty355
1 files changed, 261 insertions, 94 deletions
diff --git a/support/splint/tex/yymisc.sty b/support/splint/tex/yymisc.sty
index fcc38da96d..b961135b02 100644
--- a/support/splint/tex/yymisc.sty
+++ b/support/splint/tex/yymisc.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
@@ -14,7 +14,7 @@
% You should have received a copy of the GNU General Public License
% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
-% `data structure access' macros': picking the n-th undelimited parameter
+% `data structure access' macros: picking the n-th undelimited parameter
% in a parameter list inside a token register
% it is assumed that none of the arguments is \end, and that there are enough
% parameters to pick the desired one
@@ -88,6 +88,28 @@
\def\g@ttenth#1#2#3#4#5#6#7#8#9\end{\g@tsecond#9\end}
+% removing the first element of a token register if it has more than one;
+
+\def\sansfirst#1{%
+ \expandafter\s@nsfirst\expandafter{\the#1}{#1}%
+}
+
+\def\s@nsfirst#1#2{%
+ \expandafter\s@nsf@rst\expandafter{\eatone#1}{#2}%
+}
+
+\def\s@nsf@rst#1#2{%
+ \yystringempty{#1}{}{%
+ #2{#1}%
+ }%
+}
+
+% a version of the macro above that expands to the original argument with the first element removed
+
+\def\sansfirstx#1{%
+ \expandafter\yystringempty\expandafter{\eatone#1}{#1}{\eatone#1}%
+}
+
% string replacement: all arguments are registers, nothing is expanded, no \next is defined
% note that this is not a greedy replacement: this could be arranged with a more sophisticated macro
% also note that the string being replaced cannot have any braces in it
@@ -270,6 +292,18 @@
% in the interest of efficiency; the old version (that used a control sequence
% as a `stop marker') was more prone to this bug.
+% the next sequence is not merely a convenient abbreviation; it is useful if one
+% wants to look at an `alternative' value stored for the sequence without restoring
+% it to the curent namespace; it also sets up the naming convention for namespaces
+
+\def\restorecsname#1#2{% get the name of the sequence in storage
+ % note that #2 can be a string beginning with an arbitrary
+ % character as a placeholder for the escape character
+ '#1'[\expandafter\eatone\string#2]%
+}
+
+% save macros listed in #2 in namespace #1
+
\def\savecs#1#2{\s@vecs{#1}#2.}
\def\s@vecs#1#2{%
@@ -277,12 +311,22 @@
\yybreak{}%
\else
\yybreak{%
- \expandafter\let\csname '#1'[\expandafter\eatone\string#2]\endcsname#2%
+ \expandafter\let\csname\restorecsname{#1}{#2}\endcsname#2%
\s@vecs{#1}%
}%
\yycontinue
}
+% similar to the macro above but the list is a control sequence
+
+\def\savecslist#1#2{%
+ \expandafter\s@vecslist\expandafter{#2}{#1}%
+}
+
+\def\s@vecslist#1#2{%
+ \savecs{#2}{#1}%
+}
+
\def\restorecs#1#2{\r@storecs{#1}#2.}
\def\r@storecs#1#2{%
@@ -290,12 +334,20 @@
\yybreak{}%
\else
\yybreak{%
- \expandafter\let\expandafter#2\csname '#1'[\expandafter\eatone\string#2]\endcsname
+ \expandafter\let\expandafter#2\csname\restorecsname{#1}{#2}\endcsname
\r@storecs{#1}%
}%
\yycontinue
}
+\def\restorecslist#1#2{%
+ \expandafter\r@storecslist\expandafter{#2}{#1}%
+}
+
+\def\r@storecslist#1#2{%
+ \restorecs{#2}{#1}%
+}
+
\def\hidecs#1{\h@decs#1.}
\def\h@decs#1{%
@@ -309,51 +361,53 @@
\yycontinue
}
-\def\savehcs#1#2{\savecs{#1}{#2}\hidecs{#2}}
-
-\def\savecslist#1#2{%
- \expandafter\s@vecslist\expandafter{#2}{#1}%
-}
+\def\hidecslist#1{\expandafter\hidecs\expandafter{#1}}
-\def\s@vecslist#1#2{%
- \savecs{#2}{#1}%
-}
+\def\savehcs#1#2{\savecs{#1}{#2}\hidecs{#2}}
-\def\restorecslist#1#2{%
- \expandafter\r@storecslist\expandafter{#2}{#1}%
+\def\savehcslist#1#2{%
+ \expandafter\s@vehcslist\expandafter{#2}{#1}%
}
-\def\r@storecslist#1#2{%
- \restorecs{#2}{#1}%
+\def\s@vehcslist#1#2{%
+ \savehcs{#2}{#1}%
}
% a twist on the macros above: save control sequences with a postfix
-\def\savecsx#1#2{\s@vecsx{#1}#2.}
+\def\savecsx#1#2{\s@vecsx{#1}#2.} % there is no \savecsxlist macro
-\def\s@vecsx#1#2{%
+\def\s@vecsx#1#2{% #1 is the namespace, #2 is a control sequence without the postfix or prefix
\ifx#2.%
\yybreak{}%
\else
\yybreak{%
- \expandafter\s@vecsxlet\expandafter#2\csname\expandafter\defprefix\expandafter\eatone\string#2\defpostfix\endcsname{#1}%
+ \expandafter\s@vecsxlet\csname\expandafter\defprefix\expandafter\eatone\string#2\defpostfix\endcsname#2{#1}%
\s@vecsx{#1}%
}%
\yycontinue
}
-\def\s@vecsxlet#1#2{%
- \expandafter\let\csname '#2'[\expandafter\defprefix\expandafter\eatone\string#1\defpostfix]\endcsname
+\def\s@vecsxlet#1#2#3{% #1 is the control sequence augmented by prefix and postfix,
+ % #2 is the control sequence without prefix or postfix
+ % #3 is the namespace
+ \expandafter\let\expandafter#1\csname\restorecsxname{#3}{#2}\endcsname
}
\def\restorecsx#1#2{\r@storecsx{#1}#2.}
+% see remarks about \restorecsname above
+
+\def\restorecsxname#1#2{%
+ '#1'[\expandafter\defprefix\expandafter\eatone\string#2\defpostfix]%
+}
+
\def\r@storecsx#1#2{%
\ifx#2.%
\yybreak{}%
\else
\yybreak{%
- \expandafter\r@storecsxlet\expandafter#2\csname '#1'[\expandafter\defprefix\expandafter\eatone\string#2\defpostfix]\endcsname
+ \expandafter\r@storecsxlet\expandafter#2\csname\restorecsxname{#1}{#2}\endcsname
\r@storecsx{#1}%
}%
\yycontinue
@@ -401,7 +455,7 @@
% in the appropriate namespace, this macro adds a
% preamble, a postamble and a `this' type macro; this
% will mostly be used with indexing \TeX\ control sequences
- \tokse{\def\thisname{#1}\edef\thisnamex{\expandafter\eatone\string#1}}%
+ \toksf{\def\thisname{#1}\edef\thisnamex{\expandafter\eatone\string#1}}%
\toksa\expandafter{%
\csname\expandafter\defprefix\expandafter\eatone\string#1\defpostfix\endcsname}%
\toksc\expandafter{\expandafter\def\the\toksa#2}%
@@ -410,11 +464,11 @@
}
\def\d@f@{%
- \appendl\toksd{\the\tokse}%
- \tokse\expandafter{\defypreamble}%
- \appendl\toksd{\the\tokse}%
- \tokse\expandafter{\defypostamble}%
- \appendr\toksd{\the\tokse}
+ \tokse{\defypreamble}%
+ \concatl\tokse\toksd
+ \concatl\toksf\toksd
+ \tokse{\defypostamble}%
+ \concat\toksd\tokse
\toksd\expandafter{\expandafter{\the\toksd}}%
\concat\toksc\toksd
\afterassignment\d@fy
@@ -429,12 +483,14 @@
\def\defp#1#2#{% flexible dynamic type checking
\toksa\expandafter\expandafter\expandafter{\yyuniontag#1}%
- \expandafter\edef\yyuniontag{\the\toksa}%
+ \expandafter\edef\yyuniontag{\the\toksa}% add the sequence to the current union
\def#1#2{\errmessage{unexpected type: \string#1 in namespace <\currentyyunionnamespace>}}%
\savecs\parserstrictnamespace#1%
\toksa{#2}%
- \edef#1{\the\toksa}%
+ \edef#1{\the\toksa}% save the prototype
\savecs\parserprototypesnamespace#1%
+ \let#1\relax
+ \savecs\parserdebugnamespace#1% save the debug sequence for outputting the AST
\def#1#2%
}
@@ -478,6 +534,17 @@
{\catcode`\^^M=12 \aftergroup\def\aftergroup\eolletter\aftergroup{\aftergroup^^M\aftergroup}}% end of line, ... not really
{\catcode`\|=0\catcode`\\=12 |aftergroup|def|aftergroup|benignescape|aftergroup{|aftergroup\|aftergroup}}% not an escape
{\catcode`\#=12 \aftergroup\def\aftergroup\hashletter\aftergroup{\aftergroup#\aftergroup}}% not a parameter token
+{\catcode`\~=12 \aftergroup\def\aftergroup\safetilde\aftergroup{\aftergroup~\aftergroup}}% inactive tie
+{\catcode`\$=12 \aftergroup\def\aftergroup\safemath\aftergroup{\aftergroup$\aftergroup}}% not really a start math character
+
+\let\uscore\_ % the canonical underscore for the fonts that do not have the character
+
+% remove the brackets from the namespace string;
+% the parameter is the control sequence that expands to the namespace string
+
+\def\stripbrackets#1{\expandafter\stripbr@ckets#1[]\end}
+
+\def\stripbr@ckets#1[#2]#3\end{\yystringempty{#3}{#1}{#1#2}}
% token name input
@@ -631,10 +698,11 @@
% tables
\def\newtable@full#1{%
- \toksa{\csname newtoks\endcsname}%
- \expandafter\the\expandafter\toksa\csname #1\parsernamespace\endcsname
- \edef\next{\let\csname #1\endcsname\csname #1\parsernamespace\endcsname}\next
- \toksa\expandafter{\next}\concat\pinittoks\toksa
+ \expandafter\expandafter\csname newtoks\endcsname\csname #1\parsernamespace\endcsname
+ \expandafter\expandafter\expandafter\let\expandafter
+ \expandafter\csname #1\endcsname\csname #1\parsernamespace\endcsname
+ \appendr\pinittoks{\let\expandafter\noexpand\csname #1\endcsname
+ \expandafter\noexpand\csname #1\parsernamespace\endcsname}%
\csname #1\parsernamespace\endcsname=%
}
@@ -645,72 +713,61 @@
\def\constset#1#2{%
% a \mathchardef would be nicer but it cannot handle negative numbers
\expandafter\def\csname #1\parsernamespace\endcsname{#2}%
- \toksa\expandafter{\csname #1\endcsname}%
- \toksb\expandafter{\csname #1\parsernamespace\endcsname}%
- \edef\next{\let\the\toksa\the\toksb}\next
- \toksa\expandafter{\next}\concat\pinittoks\toksa
+ \expandafter\expandafter\expandafter\let\expandafter
+ \expandafter\csname #1\endcsname\csname #1\parsernamespace\endcsname
+ \appendr\pinittoks{\let\expandafter\noexpand\csname #1\endcsname
+ \expandafter\noexpand\csname #1\parsernamespace\endcsname}%
}
\def\uconstset#1#2{%
% a \mathchardef for positive constants
\expandafter\mathchardef\csname #1\parsernamespace\endcsname=#2 %
- \toksa\expandafter{\csname #1\endcsname}%
- \toksb\expandafter{\csname #1\parsernamespace\endcsname}%
- \edef\next{\let\the\toksa\the\toksb}\next
- \toksa\expandafter{\next}\concat\pinittoks\toksa
+ \expandafter\expandafter\expandafter\let\expandafter
+ \expandafter\csname #1\endcsname\csname #1\parsernamespace\endcsname
+ \appendr\pinittoks{\let\expandafter\noexpand\csname #1\endcsname
+ \expandafter\noexpand\csname #1\parsernamespace\endcsname}%
}
\def\charset#1#2{%
\expandafter\chardef\csname #1\parsernamespace\endcsname=#2\relax%
- \toksa\expandafter{\csname #1\endcsname}%
- \toksb\expandafter{\csname #1\parsernamespace\endcsname}%
- \edef\next{\let\the\toksa\the\toksb}\next
- \toksa\expandafter{\next}\concat\pinittoks\toksa
-}
-
-% switch macro
-
-\def\stashswitch#1{%
- \toksa\expandafter{\csname #1\endcsname}%
- \toksb\expandafter{\csname #1\parsernamespace\endcsname}%
- \edef\next{\let\the\toksb\the\toksa}\next
- \edef\next{\let\the\toksa\the\toksb}%
- \toksa\expandafter{\next}\concat\pinittoks\toksa
+ \expandafter\expandafter\expandafter\let\expandafter
+ \expandafter\csname #1\endcsname\csname #1\parsernamespace\endcsname
+ \appendr\pinittoks{\let\expandafter\noexpand\csname #1\endcsname
+ \expandafter\noexpand\csname #1\parsernamespace\endcsname}%
}
% parser and lexer state control
-\def\settokreg#1{%
- \toksa{\csname newtoks\endcsname}%
- \expandafter\the\expandafter\toksa\csname #1\parsernamespace\endcsname
- \edef\next{\let\csname #1\endcsname\csname #1\parsernamespace\endcsname}\next
- \toksa\expandafter{\next}\concat\pinittoks\toksa
+\def\settokreg#1{% do not create individual token registers for each parser namespace
+ \expandafter\ifx\csname #1\endcsname\relax
+ \expandafter\expandafter\csname newtoks\endcsname\csname #1\endcsname
+ \fi
}
-\def\setcntreg#1{%
- \toksa{\csname newcount\endcsname}%
- \expandafter\the\expandafter\toksa\csname #1\parsernamespace\endcsname
- \edef\next{\let\csname #1\endcsname\csname #1\parsernamespace\endcsname}\next
- \toksa\expandafter{\next}\concat\pinittoks\toksa
+\def\setcntreg#1{% do not create individual count registers for each parser namespace
+ \expandafter\ifx\csname #1\endcsname\relax
+ \expandafter\expandafter\csname newcount\endcsname\csname #1\endcsname
+ \fi
}
\def\setnulstack#1{%
- \toksa\expandafter{\csname #1\endcsname}%
- \toksb\expandafter{\csname #1\parsernamespace\endcsname}%
- \edef\next{\let\the\toksb\noexpand\empty}\next
- \edef\next{\let\the\toksa\the\toksb}\next
- \toksa\expandafter{\next}\concat\pinittoks\toksa
- \setcntreg{#1<count>}% this is only needed for the accelerated stack
+ \expandafter\let\csname #1\parsernamespace\endcsname\empty % for the unoptimized stack
+ \appendr\pinittoks{\let\expandafter\noexpand\csname #1\endcsname
+ \expandafter\noexpand\csname #1\parsernamespace\endcsname}%
+ \setcntreg{#1<count>}% this is only (as well as the only action that is) needed for the accelerated stack
}
\def\setcurrentcs#1{%
- \toksa\expandafter{\csname #1\endcsname}%
- \toksb\expandafter{\csname #1\parsernamespace\endcsname}%
- \edef\next{\let\the\toksb\the\toksa}\next
- \edef\next{\toksa{\let\the\toksa\the\toksb}}\next
- \concat\pinittoks\toksa
+ \expandafter\expandafter\expandafter\let\expandafter
+ \expandafter\csname #1\parsernamespace\endcsname\csname #1\endcsname
+ \appendr\pinittoks{\let\expandafter\noexpand\csname #1\endcsname
+ \expandafter\noexpand\csname #1\parsernamespace\endcsname}%
}
+% switch macro
+
+\let\stashswitch\setcurrentcs
+
\def\newparserstate{%
\setcntreg{yytoken}%
\setcntreg{yystate}%
@@ -721,14 +778,18 @@
% \yyval and \yylval will be token registers
\settokreg{yyval}%
\settokreg{yylval}%
+ \setnulstack{astarray}% an array of AST nodes
\setnulstack{yyssa}%
\setnulstack{yyvsa}%
}
\def\newlexerstate{%
+ \settokreg{yytext@}% `dirty' buffer (contains stash and formatting)
+ \settokreg{yytext@seen}% read `dirty' buffer
\settokreg{yytext}%
\settokreg{yytextseen}%
\settokreg{yybyte}%
+ \settokreg{yysubtext}% stash between characters
\settokreg{yyfutureyytext}% token register used to save read text in eob macros
%
\settokreg{yytextpure}% % the registers that serve the same role
@@ -760,32 +821,133 @@
%
\setcntreg{yyfmark}% % the last marker in the current token
\setcntreg{yyfmarklast}%
+ \setcntreg{yyfmark@accept}%
\setcntreg{yysmark}%
\setcntreg{yysmarklast}%
+ \setcntreg{yysmark@accept}%
\setnulstack{yystatestack}%
\setcurrentcs{setflexstates}%
\setcurrentcs{ifyytextbackup}% this is purely to record the recovery command in \pinittoks
}
-\def\savestatelist#1{% this elaborate definition is needed to ensure that `throwaway token registers' like \toksa
- % survive the namespace switch
- \edef\next{\expandafter\expandafter\expandafter
- \let\expandafter\expandafter\expandafter\noexpand\expandafter\expandafter\csname #1\parsernamespace\endcsname
- \expandafter\noexpand\csname #1\endcsname}\next
-}
-
-\def\savefullstate{%
- \savestatelist{yyssa}%
- \savestatelist{yyvsa}%
- \savestatelist{yystatestack}%
- \savestatelist{ifyytextbackup}% buffer
-}
-
% use \pinittoks to compose a `parser restore' macro along with
% \let\yyvsa\yyvsa[parser namespace] and \let\yyssa\yyssa[parser namespace];
% `parser save' macro only has to set up \yy?sa[parser namespace]'s;
-% if a fully reentrant parser is required, use the macros above to save the contents of
-% all the variables by redefining \settokreg and \setcntreg and saving \yy?sa stacks
+%
+% this mechanism creates parsers that (barely) survive namespace switches (such as when a local
+% parser is used to extract information about the tokens) and does not result in a reentrant parser;
+% if a fully reentrant parser is required, either use the macros above to save the contents of
+% all the variables by redefining \settokreg and \setcntreg and saving \yy?sa stacks or, better still,
+% take advantage of the grouping mechanism provided by \TeX; note that the grouping approach seems
+% to be the only viable solution if the stack mechanism is `optimized'
+
+% optimization options
+
+\def\optimizeall{%
+ % lexer
+ \ifnum\optimization>\z@
+ \optimize{yynxt}%
+ \optimize{yyaccept}%
+ \optimize{yydef}%
+ \optimize{yychk}%
+ \optimize{yybase}%
+ \optimize{yyec}%
+ \optimize{yymeta}%
+ \tracingstats=\@ne
+ \fi
+ % parser
+ \ifnum\optimization>\@ne
+ \optimize{yytranslate}%
+ \optimize{yyrone}%
+ \optimize{yyrtwo}%
+ \optimize{yyrthree}%
+ \optimize{yydefact}%
+ \optimize{yydefgoto}%
+ \optimize{yypact}%
+ \optimize{yypgoto}%
+ \optimize{yytable}%
+ \optimize{yycheck}%
+ \optimize{yyprhs}%
+ \optimize{yyrhs}%
+ \optimize{yytoknum}%
+ \optimize{yystos}%
+ \optimizetext{yytname}%
+ \fi
+}
+
+% parser and lexer initialization, token prettyfying
+
+\def\genericparser name: #1, ptables: #2, ltables: #3, tokens: #4, asetup: #5, dsetup: #6, rsetup: #7, optimization: #8;{%
+ % parser initialization
+ %
+ \expandafter\def\csname #1namespace\endcsname{[#1]}%
+ \savecs{local-namespace}\parsernamespace
+ \expandafter\let\expandafter\parsernamespace\csname #1namespace\endcsname
+ \pinittoks{}%
+ \input #2 % load main parser table
+ \settokens % set the values of all tokens
+ \yystringempty{#4}{}{%
+ \input #4 % use token equivalence table to set the values of non-string tokens
+ }%
+ #5% (a)dditional setups
+ %
+ \input #3 % load lexer tables
+ %
+ % at this point the macros inside the table files (\newtable, \constset,
+ % \yybigswitch, \stashswitch, \addname, \yydoactionswitch, \setflexstates,
+ % \stateset, \tokeneq) have set up the corresponding stuctures in
+ % the `parser namespace' (e.g. if the parser namespace is `main',
+ % \newtable{yyaccept} created a token register \yyaccept[main]),
+ % assigned the `generic' names to them (to continue
+ % the example above, \newtable does \let\yyaccept\yyaccept[main]) and
+ % recorded the corresponding commands in \pinittoks for future use.
+ %
+ % lexer state macros are namespace specific (just like token names)
+ % so they have to be set in each namespace.
+ %
+ \setflexstates
+ #8% possible optimization
+ %
+ % finally, we add the definitions for the variables used in running
+ % the lexer and the parser.
+ \newparserstate
+ \newlexerstate
+ #6% additional (d)ata setup (say, \newlexerstateextra)
+ %
+ % we record all the commands necessary to switch to the desired namespace
+ % in a convenient macro
+ {%
+ \toks0{#7}% additional setup before switching namespaces
+ \edef\next{%
+ \the\toks0 % additional namespace setups
+ \let\noexpand\parsernamespace\expandafter\noexpand\csname #1namespace\endcsname
+ \the\pinittoks % restore all the tables, tokens and constants, and stacks
+ \let\noexpand\getcurrentparser\expandafter\noexpand\csname to#1parser\endcsname
+ }%
+ \toks0\expandafter{\next}%
+ \edef\next{\toks0{\def\expandafter\noexpand\csname to#1parser\endcsname{\the\toks0}}}\next
+ \expandafter
+ }\the\toks0
+ \restorecs{local-namespace}\parsernamespace
+}
+
+\def\genericprettytokens namespace: #1, tokens: #2, correction: #3, host: #4;{%
+ \savecs{local-namespace}{\parsernamespace\tokeneq}%
+ \yystringempty{#2}{}{%
+ \expandafter\let\expandafter\parsernamespace\csname #1namespace\endcsname
+ \def\tokeneq##1##2{\prettytoken{##1}}%
+ \let\tokenpp\prettytoken
+ \input #2 % /* re-use token equivalence table to set the typesetting of tokens */
+ }%
+ \yystringempty{#3}{}{%
+ \expandafter\let\expandafter\parsernamespace\csname #1namespace\endcsname
+ \input #3 % input customized typesetting rules for tokens
+ }%
+ \yystringempty{#4}{}{%
+ \expandafter\let\expandafter\hostparsernamespace\csname #4namespace\endcsname
+ }%
+ \restorecs{local-namespace}{\parsernamespace\tokeneq}%
+}
% switch and dfa macros
@@ -1186,7 +1348,7 @@
\def\setuprefs#1#2{%
\expandafter\let\csname$[#1]\endcsname.% $o the \ifx ... \relax test makes sense ...
\appendr\nameflagtoks{\noexpand\unsetsymname{#1}}% clean it up later
- \toksa{}\expandafter\charstonumbers#1\end
+ \toksa{}\expandafter\charstonumbers#1\end
\edef\next{\toksb{\space\space\noexpand\setsym{\the\toksa}{#2}\hc^^J\uu\uu\hc\hc\hc\uu#1 --> #2^^J}}\next
\edef\next{\toksc{\space\space\noexpand\unsetsym{\the\toksa}\hc^^J\uu\uu\hc\hc\hc\uu#1 --> \relax^^J}}\next
\concat\setsncommands\toksb
@@ -1420,3 +1582,8 @@
\setsymcs{#1}{#2}%
\setsymtr{#1}{#2}%
}
+
+% message output
+
+\def\ferrmessage#1{{\newlinechar`\^^J\immediate\write16{\parsernamespace::#1^^J}}}
+