% Copyright 2012-2014, 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 . \newtoks\tayybyte % throwaway token register \newcount\tayymarker % throwaway count register \chardef\EOL=`\^^J% \def\yylex{% \ifnum\yyg@yyinit=\z@ % if ( !yyg->yy_init ) { \yyg@yyinit=\@ne % yyg->yy_init = 1; \ifnum\yyg@yystart=\z@ % if ( ! yyg->yy_start ) { \yyg@yystart=\@ne % yyg->yy_start = 1; \fi % } \fi % } \yylwhile } \def\yylwhile{% % yy_cp = yyg->yy_c_buf_p; % *yy_cp = yyg->yy_hold_char; % yy_bp = yy_cp; % \yycurrentstate=\yyg@yystart % yy_current_state = yyg->yy_start; \advance\yycurrentstate\YYATBOL % yy_current_state += YY_AT_BOL(); \yymatch } \newif\ifyytextbackup \newif\iftraceflexbuffers \def\yymatch{% \ifyytextbackup \xskiptofi\yyreinput \else \xskiptofi\yyinput \fi } \def\yyreinput{\expandafter\yyresetstreams\expandafter\yyinput\the\yytextseen} \def\yyresetstreams{% \iftraceflexbuffers\ferrmessage{will rescan: \the\yytextseen}\fi \yytextseen{}% \yytextseenpure\yytextseen \yyformatseen\yytextseen \yystashseen\yytextseen \yytextbackupfalse } \def\yym@tch{% do { \yyc=\fgetelemof{yyec}\at\yycp@\relax % yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; \yyact=\fgetelemof{yyaccept}\at\yycurrentstate\relax % ... ... reuse \yyact ( yy_act = yy_accept[yy_current_state] ) \ifnum\yyact=\z@ % if ( yy_accept[yy_current_state] ) { \else % \yyg@yylastacceptingstate=\yycurrentstate % yyg->yy_last_accepting_state = yy_current_state; \concat\yytext\yytextseen % yyg->yy_last_accepting_cpos = yy_cp; \concat\yytextpure\yytextseenpure % ... ... \concat\yyformat\yyformatseen % ... ... \concat\yystash\yystashseen % ... ... \yytextlastchar=\yytextseenlastchar % \yyfmark=\yyfmarklast % ... ... \yysmark=\yysmarklast % ... ... \yytextseen={}% \yytextseenpure\yytextseen \yyformatseen\yytextseen \yystashseen\yytextseen \fi % } \yyllwhile } \def\yyllwhile{% ... yyllwhile: \yyact=\fgetelemof{yybase}\at\yycurrentstate\relax % ... ... reusing \yyact ( yy_act = yy_base[yy_current_state] ) \advance\yyact\yyc % ... ... ( yy_act = yy_act + yy_c ) \yyact=\fgetelemof{yychk}\at\yyact\relax % ... ... ( yy_act = yy_chk[yy_act] ( == yy_chk[yy_base[yy_current_state] + yy_c] ) ) \ifnum\yyact=\yycurrentstate % while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { \yybreak\yymatchtail % ... if ( yy_chk[yy_base[yy_current_state] + yy_c] == yy_current_state ) \else % ... goto yy_match_tail; % ... else \yycurrentstate=\fgetelemof{yydef}\at\yycurrentstate\relax % yy_current_state = (int) yy_def[yy_current_state]; \ifnum\yycurrentstate>\YYMAXREALCHAR\relax % if ( yy_current_state >= sizeof( yy_accept ) ) { \yyc=\fgetelemof{yymeta}\at\yyc\relax % yy_c = yy_meta[(unsigned int) yy_c]; \fi % } \yybreak\yyllwhile % ... goto yyllwhile; \yycontinue % } } \def\yymatchtail{% \yycurrentstate=\fgetelemof{yybase}\at\yycurrentstate\relax \advance\yycurrentstate\yyc % \yycurrentstate=\fgetelemof{yynxt}\at\yycurrentstate\relax % yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; \concat\yytextseen\yybyte % ++yy_cp; \concat\yytextseenpure\yybytepure % ... \concat\yyformatseen\yyfbyte\yyfbyte{}% % ... \concat\yystashseen\yysbyte\yysbyte{}% % ... \yytextseenlastchar=\yycp@ % \yyfmarklast=\formatmarker % ... \yysmarklast=\stashmarker % ... \yyact=\fgetelemof{yybase}\at\yycurrentstate\relax % ... reusing \yyact ( yy_act = yy_base[yy_current_state] ) \ifnum\yyact=\YYBASEMAXENTRY\relax % } while ( yy_base[yy_current_state] != max( yy_base ) ); \xskiptofi\yyfindaction % ... if ( yy_base[yy_current_state] == max( yy_base ) ) goto yy_find_action; \else % ... else goto yy_match; \xskiptofi\yymatch \fi } \newif\ifyyflexdebug \newif\iftracebadchars \def\yyfindaction{% \yyact=\fgetelemof{yyaccept}\at\yycurrentstate\relax % yy_act = yy_accept[yy_current_state]; \ifnum\yyact=\z@ % if ( yy_act == 0 ) { \yytextbackuptrue % yy_cp = yyg->yy_last_accepting_cpos; \yycurrentstate=\yyg@yylastacceptingstate % yy_current_state = yyg->yy_last_accepting_state; \yyact=\fgetelemof{yyaccept}\at\yycurrentstate\relax% yy_act = yy_accept[yy_current_state]; \ifyyflexdebug\ferrmessage{backup: \the\yytext:\the\yytextseen}\fi \else % \concat\yytext\yytextseen \concat\yytextpure\yytextseenpure \concat\yyformat\yyformatseen \concat\yystash\yystashseen \yytextlastchar=\yytextseenlastchar \yyfmark=\yyfmarklast \yysmark=\yysmarklast \yytextseen{}% \yytextseenpure{}% \yyformatseen{}% \yystashseen{}% % \fi % } % \YYDOBEFOREACTION % YY_DO_BEFORE_ACTION; \ifyyflexdebug \ferrmessage{action: \the\yyact, state: \the\yycurrentstate\space(\the\yytext)}% \fi \doaction } \def\YYRULESETUP{% %#define YY_RULE_SETUP \ \yytoksempty{\yytext}{}{% % if ( yyleng > 0 ) \ \ifnum\EOL=\yytextlastchar % YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (yytext[yyleng - 1] == '\n'); \ \YYATBOL=\@ne % YY_USER_ACTION \else %#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) \YYATBOL=\z@ \fi }% } %#define BEGIN yyg->yy_start = 1 + 2 * % should be: %#define BEGIN(state) yyg->yy_start = 1 + 2 * ( state ) \newif\iftracestates \def\yylexstate#1{\csname flexstate\parsernamespace #1\endcsname} \def\yyBEGIN#1{% \yyg@yystart \expandafter\ifx\csname flexstate\parsernamespace #1\endcsname\relax #1 \iftracestates\ferrmessage{now in state: #1}\fi \else \csname flexstate\parsernamespace #1\endcsname\relax \iftracestates\ferrmessage{now in state: #1 (\number\csname flexstate\parsernamespace #1\endcsname)}\fi \fi \multiply\yyg@yystart\tw@ \advance\yyg@yystart\@ne } \def\yyBEGINr#1{% \yyg@yystart#1% \iftracestates\ferrmessage{new state: \the\yyg@yystart}\fi \multiply\yyg@yystart\tw@ \advance\yyg@yystart\@ne } %#define YY_START ((yyg->yy_start - 1) / 2) \def\YYSTART{% \expandafter\xdivbytwo\expandafter{\number \expandafter\xdecrement\expandafter{\number\yyg@yystart}} } \def\yypushstate#1{% \expandafter\yypush\expandafter{\number\YYSTART}\on\yystatestack \yyBEGIN{#1}% } \def\yypopstate{% \yypop\yystatestack\into{\expandafter\yyBEGIN\romannumeral0}% \iftracestates\message{new state (* 2 + 1 scrambled): \the\yyg@yystart}\fi } \def\yytopstate#1{% \yyreadstack\yystatestack\at\z@\to#1% } \let\yylexcontinue\yylwhile % complete the while loop (requires \yylexnext) \def\yylexcontinue{\yytext{}\yytextpure\yytext\yylwhile} % complete the while loop % \yylextail is the return point from the lexer \let\yyreturn\yym@tch % the return point from the low-level input \def\yylexreturnbootstrap#1{% \yytext{}\yytextpure\yytext \expandafter\ifx\csname token\parsernamespace #1\endcsname\relax % this token value is undefined \let\yylextail\yylex % so lex the next token \else \yychar\csname token\parsernamespace #1\endcsname\relax \let\yylextail\yyparsetail \fi } \def\yylexreturnregular#1{\yychar\csname token\parsernamespace #1\endcsname\relax\yytext{}\yytextpure{}\let\yylextail\yyparsetail} \def\yylexreturnval#1{% return value (yytext) only \yychar\csname token\parsernamespace #1\endcsname\relax \yylval\expandafter{\expandafter{\the\yytext}}% \yylval\expandafter\expandafter\expandafter{\expandafter\the\expandafter\yylval\expandafter{\the\yytextpure}}% % the above is an equivalent of % \edef\next{\yylval{{\the\yytext}{\the\yytextpure}}}\next % but does not `pollute' the definition of \next \yytext{}\yytextpure\yytext\let\yylextail\yyparsetail } \def\yylexreturnptr#1{% return stream pointers only \yylval\expandafter{\expandafter{\the\yyfmark}}% \yylval\expandafter\expandafter\expandafter{\expandafter\the\expandafter\yylval\expandafter{\the\yysmark}}% % the above is an equivalent of % \edef\next{\yylval{{\the\yyfmark}{\the\yysmark}}}\next % but does not `pollute' the definition of \next \yylexreturn{#1}% } \def\yylexreturntext{\yylexreturnptr{\the\yytextpure}} \def\yylexreturnraw#1{% return the character value \yychar`#1\relax \yytext{}\yytextpure{}\let\yylextail\yyparsetail } \def\yylexreturnchar{% \expandafter\yylexreturnraw\the\yytextpure } \def\yylexnext{\yytext{}\yytextpure{}} % use this with a trivial \yylexcontinue \let\yylexnext\empty \def\yyterminate{\yychar\YYEOF\yylval{}\yytext{}\yytextpure{}\let\yylextail\yyparsetail} \def\yyerrterminate{\yylexreturn{$undefined}} %$ \def\ferrmessage#1{\immediate\write16{#1}} % \yyless is slow and the macros below have not been tested in their current % form: avoid them \def\yyless#1{% \ifnum#1=\z@ \ROLLBACKCURRENTTOKEN \else \let\oldyyreturn\yyreturn \edef\yyreturn{\noexpand\yyskipnchars{\number#1}}% \expandafter\yyinput\the\yytext\yyeof \fi } \def\yyskipnchars#1{% \ifnum\yycp@=\YYENDOFBUFFERCHAR % read \yyeof \yycomplain{yyless buffer overflow: #1 characters too many}% \else \ifnum#1=\@ne % skipped the required number of tokens \yybreak@\yyl@ss \else \edef\yyreturn{\noexpand\yyskipnchars{\xdecrement{#1}}}% \yybreak@\yyinput \fi \yycontinue } \def\yyl@ss#1\yyeof{% \yytext{#1}% \concatl\yytext\yytextseen \yytext{}\yytextpure{}% \yytextbackuptrue \let\yyreturn\oldyyreturn } %#define ROLLBACK_CURRENT_TOKEN \ % do { \ % scanner_cursor.column -= mbsnwidth (yytext, yyleng, 0); \ % yyless (0); \ % } while (0) \def\ROLLBACKCURRENTTOKEN{% \concatl\yytext\yytextseen \yytext{}\yytextpure{}% \yytextbackuptrue } % \yytext---current yytext % \yytextseen---last accepted yytext % |--\yytext--|--\yytextseen--|--remaining buffer--| % after accepting state: % [---------\yytext-----------] % after backing up: % |--\yytext--|--\yytextseen-----remaining buffer--| % \yytextseen={} %#define YY_DO_BEFORE_ACTION \ % yyg->yytext_ptr = yy_bp; \ % yyleng = (size_t) (yy_cp - yy_bp); \ % yyg->yy_hold_char = *yy_cp; \ % *yy_cp = '\0'; \ % yyg->yy_c_buf_p = yy_cp; \def\doaction{% \yydoactionswitch\yyact } %#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) % as the macros above and below make a lot of assignments, % expandability was not a % priority, however, keeping the macro namespace clean was; % expandability is, of course a guaranteed way to do so, grouping is % another; \def\yylexeofaction{% \yygetnextbuffer \ifYYEOBLASTMATCH \yygetpreviousstate \ifyyflexdebug\ferrmessage{found previous state: \the\yycurrentstatelocal\space matched text: \the\yytext>>\the\yytextseen(\the\yybyte))}\fi \yycurrentstate\yycurrentstatelocal \let\yylextail\yyfind@ction \YYEOBLASTMATCHfalse \else \yyact\YYENDOFBUFFER\relax \advance\yyact\YYSTART \advance\yyact\@ne % yy_act = YY_STATE_EOF(YY_START); \let\yylextail\doaction % goto do_action; \appendl\yytextseen{\the\yytext}\yytextbackuptrue % in case the scanner gets called again \ifyyflexdebug \yytoksempty{\yytext}% {\errmessage{internal error: matched nothing in eob state}}% {\yyisthiscsr\yytext\yyeof{}{\errmessage{internal error: matched more that a single eob}}}% \ferrmessage{eob in user state: \the\yyact\space matched text: \the\yytext(\the\yytextpure)\space to read: \the\yytextseen}% \fi \yytext{}% \fi } \def\yygetnextbuffer{% \yytoksempty{\yytext}{\errmessage{internal error: empty matched text in eob state}}% {% \expandafter\expandafter\expandafter \yystringempty % we have matched exactly one token \expandafter\expandafter\expandafter{\expandafter\eatone\the\yytext}% {\YYEOBLASTMATCHfalse}{\YYEOBLASTMATCHtrue}% }% } \def\yyeofcontainer{\yyeof} \newif\ifYYEOBLASTMATCH \def\yygetpreviousstate{% \yycurrentstatelocal=\yyg@yystart \advance\yycurrentstatelocal\YYATBOL % \yytoksempty{\yytext}{\errmessage{internal error: empty matched text in eob state}}{}% \expandafter\yysplitoff\expandafter.\the\yytext\yyeof\end \appendl\yytextseen{\noexpand\yyeof}\yytextbackuptrue \ifyyflexdebug\ferrmessage{searching for last match in text: \the\yytext}\fi % TODO: delete \yytoksempty{\yytext}{}{% yyg->yytext_ptr >= yyg->yy_c_buf_p /* do not enter the for loop */ \yytextpure{}% \yyfutureyytext\yytextseen % to be reinserted in yyfind@action \yytextseen{}\yytextseenpure{}% \expandafter\yytext\expandafter {\expandafter}\expandafter \yygetpreviousstatefor\the\yytext\splitoffend % at least one iteration of the for loop }% } \def\yysplitoff#1\yyeof#2\end{% \yystringempty{#2}{% \errmessage{internal error: something other than \noexpand\yyeof\space triggered eob action}% }{% \yytext\expandafter{\eatone#1}% to remove the `.' at the beginning }% } \def\yygetpreviousstatefor{% % save all the lexer variables affected by \yyinput % to be restored on exit from the `for' loop % i.e.~when the \splitoff token is read \let\currentyyreturn\yyreturn % \let\currentyyfbyte\yyfbyte \let\currentyysbyte\yysbyte \let\currentstashmarker\stashmarker \let\currentformatmarker\formatmarker % \let\yyfbyte\tayybyte \let\yysbyte\tayybyte \let\stashmarker\tayymarker \let\formatmarker\tayymarker % \let\yyreturn\yygetpreviousstatef@r \yyinput } \def\yygetpreviousstatef@r{% \let\default\yygetpreviousstatedefault \ifyyflexdebug\ferrmessage{just read: \the\yybyte}\fi % TODO: delete \switchon{\expandafter\getfirsttoken\expandafter{\the\yybyte}}\in\yygetpreviousstateswitch } \def\yygetpreviousstateswitch{% \yyeof {% scanned a NUL \yyclocal\YYECMAGIC\relax % the constant extracted from yy_get_next_state \yygetpreviousstat@f@r } \splitoffend {% yyg->yytext_ptr >= yyg->yy_c_buf_p /* exit the for loop */ % this is not an actual character but a marker for the end of the `for' loop \let\yyfbyte\currentyyfbyte \let\yysbyte\currentyysbyte \let\stashmarker\currentstashmarker \let\formatmarker\currentformatmarker \yycp@=\YYENDOFBUFFERCHAR\relax % this is not necessary \yybyte{}\yybytepure{}% % \let\yyreturn\currentyyreturn } \endparse \endparseinput {% \errmessage{internal error.: reading past the end of the input buffer}% } } \def\yygetpreviousstatedefault{% \yyclocal=\fgetelemof{yyec}\at\yycp@\relax % yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; \yytextseenlastchar=\yycp@ \yygetpreviousstat@f@r } \def\yygetpreviousstat@f@r{% \ifnum\fgetelemof{yyaccept}\at\yycurrentstatelocal=\z@ % if ( yy_accept[yy_current_state] ) { \concat\yytextseen\yybyte \concat\yytextseenpure\yybytepure \yybyte{}\yybytepure\yybyte \else % \ifyyflexdebug\ferrmessage{possible accepting state: \the\yycurrentstatelocal:% \fgetelemof{yyaccept}\at\yycurrentstatelocal}\fi % TODO: delete \yyg@yylastacceptingstate=\yycurrentstatelocal % yyg->yy_last_accepting_state = yy_current_state; \concat\yytext\yytextseen % yyg->yy_last_accepting_cpos = yy_cp; TODO:????????? \concat\yytextpure\yytextseenpure % ... ... \yytextseen=\yybyte \yytextseenpure=\yybytepure \yytextbackuptrue \yybyte{}\yybytepure\yybyte \yytextlastchar=\yytextseenlastchar % \fi \yygpswhile } \def\yygpswhile{% ... yyllwhile: \yyact=\fgetelemof{yybase}\at\yycurrentstatelocal\relax% ... ... reusing \yyact ( yy_act = yy_base[yy_current_state] ) \advance\yyact\yyclocal % ... ... ( yy_act = yy_act + yy_c ) \ifnum\fgetelemof{yychk}\at\yyact=\yycurrentstatelocal % while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { \yybreak\yygpsfornext % ... if ( yy_chk[yy_base[yy_current_state] + yy_c] == yy_current_state ) % ... ... exit the while loop \else % ... return yy_current_state; % ... else \yycurrentstatelocal=\fgetelemof{yydef}\at\yycurrentstatelocal\relax % yy_current_state = (int) yy_def[yy_current_state]; \ifnum\yycurrentstatelocal>\YYMAXREALCHAR\relax % if ( yy_current_state >= sizeof( yy_accept ) ) { \yyclocal=\fgetelemof{yymeta}\at\yyclocal\relax% yy_c = yy_meta[(unsigned int) yy_c]; \fi % } \yybreak\yygpswhile % ... goto yyllwhile; \yycontinue % } } \def\yygpsfornext{% \yycurrentstatelocal=\fgetelemof{yybase}\at\yycurrentstatelocal\relax \advance\yycurrentstatelocal\yyclocal \yycurrentstatelocal=\fgetelemof{yynxt}\at\yycurrentstatelocal\relax \ifyyflexdebug\ferrmessage{switching to state: \the\yycurrentstatelocal}\fi % TODO: delete \yyinput } \def\yyfind@ction{% we have to use this macro instead of the % regular \yyfindaction because we use a stop token (\splitoffend) to terminate % the `for' loop and are thus `one token behind' by the time this action is taken % therefore we have to forego the `yy_cp actions' in the original \yyfindaction \yyact=\fgetelemof{yyaccept}\at\yycurrentstate\relax % yy_act = yy_accept[yy_current_state]; \ifnum\yyact=\z@ % if ( yy_act == 0 ) { % yy_cp = yyg->yy_last_accepting_cpos; \yycurrentstate=\yyg@yylastacceptingstate % yy_current_state = yyg->yy_last_accepting_state; \yyact=\fgetelemof{yyaccept}\at\yycurrentstate\relax% yy_act = yy_accept[yy_current_state]; \ifyyflexdebug\ferrmessage{backup.: \the\yytext:\the\yytextseen}\fi \else % \concat\yytext\yytextseen \concat\yytext\yybyte \yybyte{}% \yytextseen{}% \concat\yytextpure\yytextseenpure \concat\yyformat\yyformatseen \concat\yystash\yystashseen \yytextlastchar=\yytextseenlastchar \yyfmark=\yyfmarklast \yysmark=\yysmarklast \yyformatseen{}% \yystashseen{}% % \fi % } \concat\yytextseen\yyfutureyytext % ... reinsert the tokens seen by the lexer before % ... \yygetpreviousaction got rolling \yyfutureyytext{}% \yytextbackuptrue % \YYDOBEFOREACTION % YY_DO_BEFORE_ACTION; \ifyyflexdebug \ferrmessage{action.: \the\yyact, state: \the\yycurrentstate\space(\the\yytext) \parsernamespace}% \fi \doaction }