% Copyright 2012-2020, 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/>.

% extra types for the bison scanner

\def\lexspecialchar#1#2#3{\immediate\write16{encountered: \noexpand#1 fmark: #2, smark: #3}}

\def\newlexerstateextra{%
  \setnulstack{obstackforstring}% 
  \setnulstack{obstackforstringraw}% 
}

% lexer environment

\def\yycomplain#1{\ferrmessage{flex: #1}} % lexer errors
\def\yypdeprecated#1{\yywarn{option: #1 is ignored}} % outdated options

\def\STRINGGROW{%
    \concat\currentlaststring\yytextpure
    \concat\currentlaststringraw\yytext}

\def\STRINGFINISH{%
    \laststring\currentlaststring
    \laststringraw\currentlaststringraw
    \yypushr\currentlaststring\on\obstackforstring
    \yypushr\currentlaststringraw\on\obstackforstringraw
    \currentlaststring{}%
    \currentlaststringraw{}%
}
\def\STRINGFREE{%
    \yypopstack\obstackforstring\by\@ne
    \currentlaststring{}%
    \yypopstack\obstackforstringraw\by\@ne
    \currentlaststringraw{}%
}

\def\bracketedidstr{}

\newcount\contextstate % keeping track of the previous lexer state
\newcount\bracketedidcontextstate % similar but in the context of bracketed identifiers
\newcount\lonesting % nesting level for tags
\newcount\percentpercentcount

\newtoks\laststring
\newtoks\laststringraw
\newtoks\currentlaststring
\newtoks\currentlaststringraw

% common \bison parser initialization; the first macro initializes the lexer structures only
% while the second one deals exclusively with the data produced by the parser; logically, in a `real'
% \bison\ parser, the second set of initializations is applied to the |..._extra| local
% data for the parser (for a reentrant yyparse()); we put it here for convenience.

\def\bisonparserinit{%
    \yyinitstack\obstackforstring
    \yyinitstack\obstackforstringraw
    \percentpercentcount=\z@
    \lonesting=\z@
    \laststring{}\laststringraw{}%
    \currentlaststring{}\currentlaststringraw{}%
}

\def\bisonparserdatainit{%
    \table{}\typestable{}\prectable{}\opttable{}%
}

% macros for \flex\ lexer

\newif\iffldidadef
\newif\ifflindented@code
\newif\iffloption@sense
\newif\iffllex@compat
\newif\ifflposix@compat
\newif\ifflin@rule
\newif\iffldoing@rule@action
\newif\ifflcontinued@action
\newif\ifflend@is@ws
\newif\ifflsf@skip@ws
\newif\ifflsf@case@ins
\newif\ifflsf@dot@all

\newcount\fllinenum
\def\flinc@linenum{\advance\fllinenum\@ne}
\def\flinc#1{%
    \expandafter\fl@nc\expandafter{\number#1}{#1}%
}
\def\fl@nc#1#2{%
    \edef#2{\xincrement{#1}}%
}

\def\fldec#1{%
    \expandafter\fld@c\expandafter{\number#1}{#1}%
}
\def\fld@c#1#2{%
    \edef#2{\xdecrement{#1}}%
}

\def\yylessafter#1{}% put back the string starting at (after) #1
\def\flsf@push{}% push the next parenthesis level
\def\flsf@pop{}% pop the nesting level

\def\RETURNNAME{\yylexreturnsym{NAME}}
\def\RETURNCHAR{\yylexreturnsym{CHAR}}
\def\yyflexoptreturn#1{%
    \edef\next{\yylval{{\iffloption@sense\else no\fi}{\the\yytextpure}{\the\yyfmark}{\the\yysmark}}}\next
    \yylexreturnregular{#1}%
}

% macros to process special character classes

\def\makecclpair#1#2{%
    \expandafter\def\csname xccl@#1\endcsname{\langle#2\rangle}%
    \mak@cclpair#1.{#2}%
}

\def\mak@cclpair CCE_#1.#2{%
    \expandafter\def\csname xccl@CCE_NEG_#1\endcsname{\langle^\neg#2\rangle}%
}

\makecclpair{CCE_ALPHA}{\alpha\beta}
\makecclpair{CCE_ALNUM}{\alpha n}
\makecclpair{CCE_BLANK}{\hbox{ }}
\makecclpair{CCE_GRAPH}{\hbox{\dingssmall\leaf}}
\makecclpair{CCE_DIGIT}{\hbox{\.{0..9}}}
\makecclpair{CCE_XDIGIT}{\hbox{\.{0..Z}}}
\makecclpair{CCE_SPACE}{\hbox{\.{\ }}}
\makecclpair{CCE_LOWER}{\hbox{\.{a..z}}}
\makecclpair{CCE_UPPER}{\hbox{\.{A..Z}}}
\makecclpair{CCE_PRINT}{\hbox{\dingssmall\pen}}
\makecclpair{CCE_PUNCT}{\hbox{\.{.}}}
\makecclpair{CCE_CNTRL}{\mapsto}

\def\xcclreturn#1{%
    \yyBEGIN{CCL}%
    \yytextpure{#1}% substitute the token name for the actual text
    % this is slightly dangerous, because of the `_' in the name
    % for this to work, ftokenset.sty must be used
    \yylexreturnsym{#1}%
}

\chardef\flquotechar`\"

\def\fllexsetup{%
    \def\flbrace@depth{0}%
    \def\flsectnum{0}%
    \def\flnmstr{{}{}}% recorded name
    \def\flnmdef{{}{}}% recorded definition
}
