LCOV - code coverage report
Current view: top level - mnt/wasteland/wcohen/systemtap_write/systemtap/re2c-migrate - re2c-emit.cxx (source / functions) Hit Total Coverage
Test: stap.info Lines: 515 1232 41.8 %
Date: 2013-03-08 Functions: 52 91 57.1 %
Branches: 549 3394 16.2 %

           Branch data     Line data    Source code
       1                 :            : // -*- C++ -*-
       2                 :            : // Copyright (C) 2012-2013 Red Hat Inc.
       3                 :            : //
       4                 :            : // This file is part of systemtap, and is free software.  You can
       5                 :            : // redistribute it and/or modify it under the terms of the GNU General
       6                 :            : // Public License (GPL); either version 2, or (at your option) any
       7                 :            : // later version.
       8                 :            : //
       9                 :            : // ---
      10                 :            : //
      11                 :            : // This file incorporates code from the re2c project; please see
      12                 :            : // re2c-migrate/README for details.
      13                 :            : 
      14                 :            : /* Implements additional functions having to do with emitting code. */
      15                 :            : 
      16                 :            : /*
      17                 :            :  Author for null_stream stuff: Marcus Boerger <helly@users.sourceforge.net>
      18                 :            : */
      19                 :            : 
      20                 :            : #include <stdarg.h>
      21                 :            : #include <stdlib.h>
      22                 :            : #include <string.h>
      23                 :            : #include <stdio.h>
      24                 :            : #include <ctype.h>
      25                 :            : #include <iomanip>
      26                 :            : #include <iostream>
      27                 :            : #include <sstream>
      28                 :            : #include <time.h>
      29                 :            : #include <assert.h>
      30                 :            : #include <string>
      31                 :            : #include <map>
      32                 :            : #include "re2c-globals.h"
      33                 :            : #include "re2c-dfa.h"
      34                 :            : #include "re2c-regex.h"
      35                 :            : 
      36                 :            : namespace re2c
      37                 :            : {
      38                 :            : 
      39                 :            : // moved here from code.h
      40                 :            : 
      41                 :            : 
      42                 :            : class BitMap
      43                 :            : {
      44                 :            : public:
      45                 :            :         static BitMap   *first;
      46                 :            : 
      47                 :            :         const Go        *go;
      48                 :            :         const State     *on;
      49                 :            :         const BitMap    *next;
      50                 :            :         unsigned            i;
      51                 :            :         unsigned            m;
      52                 :            : 
      53                 :            : public:
      54                 :            :         static const BitMap *find(const Go*, const State*);
      55                 :            :         static const BitMap *find(const State*);
      56                 :            :         static void gen(std::ostream&, unsigned ind, unsigned, unsigned);
      57                 :            :         static void stats();
      58                 :            :         BitMap(const Go*, const State*);
      59                 :            :         ~BitMap();
      60                 :            : 
      61                 :            : #if PEDANTIC
      62                 :            :         BitMap(const BitMap& oth)
      63                 :            :                 : go(oth.go)
      64                 :            :                 , on(oth.on)
      65                 :            :                 , next(oth.next)
      66                 :            :                 , i(oth.i)
      67                 :            :                 , m(oth.m)
      68                 :            :         {
      69                 :            :         }
      70                 :            :         BitMap& operator = (const BitMap& oth)
      71                 :            :         {
      72                 :            :                 new(this) BitMap(oth);
      73                 :            :                 return *this;
      74                 :            :         }
      75                 :            : #endif
      76                 :            : };
      77                 :            : 
      78                 :            : #ifdef _MSC_VER
      79                 :            : # pragma warning(disable: 4355) /* 'this' : used in base member initializer list */
      80                 :            : #endif
      81                 :            : 
      82                 :            : // -------------------------------------------------------------
      83                 :            : 
      84                 :            : // moved here from code_names.h
      85                 :            : 
      86                 :       4828 : class CodeNames: public std::map<std::string, std::string>
      87                 :            : {
      88                 :            : public:
      89                 :            :         std::string& operator [] (const char * what);
      90                 :            : };
      91                 :            : 
      92                 :       2132 : inline std::string& CodeNames::operator [] (const char * what)
      93                 :            : {
      94 [ +  - ][ +  - ]:       2132 :         CodeNames::iterator it = find(std::string(what));
                 [ +  - ]
      95                 :            :         
      96 [ +  - ][ +  + ]:       2132 :         if (it != end())
      97                 :            :         {
      98         [ +  - ]:       1975 :                 return it->second;
      99                 :            :         }
     100                 :            :         else
     101                 :            :         {
     102 [ +  - ][ +  - ]:       2132 :                 return insert(std::make_pair(std::string(what), std::string(what))).first->second;
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     103                 :            :         }
     104                 :            : }
     105                 :            : 
     106                 :            : // -------------------------------------------------------
     107                 :            : 
     108                 :            : // moved here from globals.cc
     109                 :            : 
     110                 :            : enum BUFFERSIZE { BSIZE = 8192};
     111                 :            : 
     112                 :            : 
     113                 :            : bool bFlag = false;
     114                 :            : bool cFlag = false;
     115                 :            : bool dFlag = false;
     116                 :            : bool fFlag = false;
     117                 :            : bool gFlag = false;
     118                 :            : bool rFlag = false;
     119                 :            : bool sFlag = false;
     120                 :            : 
     121                 :            : bool bNoGenerationDate = false;
     122                 :            : 
     123                 :            : bool bFirstPass  = true;
     124                 :            : bool bLastPass   = false;
     125                 :            : bool bUsedYYBitmap  = false;
     126                 :            : 
     127                 :            : bool bUsedYYAccept  = false;
     128                 :            : bool bUsedYYMaxFill = false;
     129                 :            : bool bUsedYYMarker  = true;
     130                 :            : 
     131                 :            : bool bEmitYYCh       = true;
     132                 :            : bool bUseStartLabel  = false;
     133                 :            : bool bUseStateNext   = false;
     134                 :            : bool bUseYYFill      = true;
     135                 :            : bool bUseYYFillParam = true;
     136                 :            : bool bUseYYFillCheck = true;
     137                 :            : bool bUseYYFillNaked = false;
     138                 :            : bool bUseYYSetConditionParam = true;
     139                 :            : bool bUseYYGetConditionNaked = false;
     140                 :            : bool bUseYYSetStateParam = true;
     141                 :            : bool bUseYYSetStateNaked = false;
     142                 :            : bool bUseYYGetStateNaked = false;
     143                 :            : 
     144                 :       2414 : std::string startLabelName;
     145         [ +  - ]:       2414 : std::string labelPrefix("yy");
     146         [ +  - ]:       2414 : std::string condPrefix("yyc_");
     147         [ +  - ]:       2414 : std::string condEnumPrefix("yyc");
     148         [ +  - ]:       2414 : std::string condDivider("/* *********************************** */");
     149         [ +  - ]:       2414 : std::string condDividerParam("@@");
     150         [ +  - ]:       2414 : std::string condGoto("goto @@;");
     151         [ +  - ]:       2414 : std::string condGotoParam("@@");
     152         [ +  - ]:       2414 : std::string yychConversion("");
     153         [ +  - ]:       2414 : std::string yyFillLength("@@");
     154         [ +  - ]:       2414 : std::string yySetConditionParam("@@");
     155         [ +  - ]:       2414 : std::string yySetStateParam("@@");
     156         [ +  - ]:       2414 : std::string yySetupRule("");
     157                 :            : unsigned maxFill = 1;
     158                 :            : unsigned next_label = 0;
     159                 :            : unsigned cGotoThreshold = 9;
     160                 :            : 
     161                 :            : unsigned topIndent = 0;
     162         [ +  - ]:       2414 : std::string indString("\t");
     163                 :            : bool yybmHexTable = false;
     164                 :            : bool bUseStateAbort = false;
     165                 :            : bool bWroteGetState = false;
     166                 :            : bool bWroteCondCheck = false;
     167                 :            : 
     168                 :            : unsigned next_fill_index = 0;
     169                 :            : unsigned last_fill_index = 0;
     170                 :       2414 : std::set<unsigned> vUsedLabels;
     171                 :       2414 : CodeNames mapCodeName;
     172                 :       2414 : std::string typesInline;
     173                 :            : 
     174                 :            : // --------------------------------------------------------------------
     175                 :            : 
     176                 :            : // there must be at least one span in list;  all spans must cover
     177                 :            : // same range
     178                 :            : 
     179                 :       4161 : static std::string indent(unsigned ind)
     180                 :            : {
     181                 :       4161 :         std::string str;
     182                 :            : 
     183 [ +  - ][ +  + ]:       6822 :         while (!DFlag && ind-- > 0)
                 [ +  + ]
     184                 :            :         {
     185         [ +  - ]:       2661 :                 str += indString;
     186                 :            :         }
     187                 :       4161 :         return str;
     188                 :            : }
     189                 :            : 
     190                 :            : template<typename _Ty>
     191                 :          0 : std::string replaceParam(std::string str, const std::string& param, const _Ty& value)
     192                 :            : {
     193 [ #  # ][ #  # ]:          0 :         std::ostringstream strValue;
     194                 :            : 
     195 [ #  # ][ #  # ]:          0 :         strValue << value;
     196                 :            : 
     197                 :            :         std::string::size_type pos;
     198                 :            : 
     199 [ #  # ][ #  # ]:          0 :         while((pos = str.find(param)) != std::string::npos)
         [ #  # ][ #  # ]
     200                 :            :         {
     201 [ #  # ][ #  # ]:          0 :                 str.replace(pos, param.length(), strValue.str());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     202                 :            :         }
     203                 :            : 
     204 [ #  # ][ #  # ]:          0 :         return str;
         [ #  # ][ #  # ]
     205                 :            : }
     206                 :            : 
     207                 :        254 : static void genYYFill(std::ostream &o, unsigned, unsigned need)
     208                 :            : {
     209         [ +  - ]:        254 :         if (bUseYYFillParam)
     210                 :            :         {
     211                 :        254 :                 o << mapCodeName["YYFILL"];
     212         [ +  - ]:        254 :                 if (!bUseYYFillNaked)
     213                 :            :                 {
     214                 :        254 :                         o << "(" << need << ");";
     215                 :            :                 }
     216                 :        254 :                 o << "\n";
     217                 :            :         }
     218                 :            :         else
     219                 :            :         {
     220 [ #  # ][ #  # ]:          0 :                 o << replaceParam(mapCodeName["YYFILL"], yyFillLength, need);
                 [ #  # ]
     221         [ #  # ]:          0 :                 if (!bUseYYFillNaked)
     222                 :            :                 {
     223                 :          0 :                         o << ";";
     224                 :            :                 }
     225                 :          0 :                 o << "\n";
     226                 :            :         }
     227                 :        254 : }
     228                 :            : 
     229                 :          0 : static std::string genGetState()
     230                 :            : {
     231         [ #  # ]:          0 :         if (bUseYYGetStateNaked)
     232                 :            :         {
     233                 :          0 :                 return mapCodeName["YYGETSTATE"];
     234                 :            :         }
     235                 :            :         else
     236                 :            :         {
     237                 :          0 :                 return mapCodeName["YYGETSTATE"] + "()";
     238                 :            :         }
     239                 :            : }
     240                 :            : 
     241                 :          0 : static std::string genGetCondition()
     242                 :            : {
     243         [ #  # ]:          0 :         if (bUseYYGetConditionNaked)
     244                 :            :         {
     245                 :          0 :                 return mapCodeName["YYGETCONDITION"];
     246                 :            :         }
     247                 :            :         else
     248                 :            :         {
     249                 :          0 :                 return mapCodeName["YYGETCONDITION"] + "()";
     250                 :            :         }
     251                 :            : }
     252                 :            : 
     253                 :          0 : static void genSetCondition(std::ostream& o, unsigned ind, const std::string& newcond)
     254                 :            : {
     255         [ #  # ]:          0 :         if (bUseYYSetConditionParam)
     256                 :            :         {
     257 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << mapCodeName["YYSETCONDITION"] << "(" << condEnumPrefix << newcond << ");\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     258                 :            :         }
     259                 :            :         else
     260                 :            :         {
     261 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << replaceParam(mapCodeName["YYSETCONDITION"], yySetConditionParam, condEnumPrefix + newcond) << "\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     262                 :            :         }
     263                 :          0 : }
     264                 :            : 
     265                 :          0 : static std::string space(unsigned this_label)
     266                 :            : {
     267 [ #  # ][ #  # ]:          0 :         int nl = next_label > 999999 ? 6 : next_label > 99999 ? 5 : next_label > 9999 ? 4 : next_label > 999 ? 3 : next_label > 99 ? 2 : next_label > 9 ? 1 : 0;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     268 [ #  # ][ #  # ]:          0 :         int tl = this_label > 999999 ? 6 : this_label > 99999 ? 5 : this_label > 9999 ? 4 : this_label > 999 ? 3 : this_label > 99 ? 2 : this_label > 9 ? 1 : 0;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     269                 :            : 
     270         [ #  # ]:          0 :         return std::string(std::max(1, nl - tl + 1), ' ');
     271                 :            : }
     272                 :            : 
     273                 :          0 : void Go::compact()
     274                 :            : {
     275                 :            :         // arrange so that adjacent spans have different targets
     276                 :          0 :         unsigned i = 0;
     277                 :            : 
     278         [ #  # ]:          0 :         for (unsigned j = 1; j < nSpans; ++j)
     279                 :            :         {
     280         [ #  # ]:          0 :                 if (span[j].to != span[i].to)
     281                 :            :                 {
     282                 :          0 :                         ++i;
     283                 :          0 :                         span[i].to = span[j].to;
     284                 :            :                 }
     285                 :            : 
     286                 :          0 :                 span[i].ub = span[j].ub;
     287                 :            :         }
     288                 :            : 
     289                 :          0 :         nSpans = i + 1;
     290                 :          0 : }
     291                 :            : 
     292                 :          0 : void Go::unmap(Go *base, const State *x)
     293                 :            : {
     294                 :          0 :         Span *s = span, *b = base->span, *e = &b[base->nSpans];
     295                 :          0 :         unsigned lb = 0;
     296                 :          0 :         s->ub = 0;
     297                 :          0 :         s->to = NULL;
     298                 :            : 
     299         [ #  # ]:          0 :         for (; b != e; ++b)
     300                 :            :         {
     301         [ #  # ]:          0 :                 if (b->to == x)
     302                 :            :                 {
     303         [ #  # ]:          0 :                         if ((s->ub - lb) > 1)
     304                 :            :                         {
     305                 :          0 :                                 s->ub = b->ub;
     306                 :            :                         }
     307                 :            :                 }
     308                 :            :                 else
     309                 :            :                 {
     310         [ #  # ]:          0 :                         if (b->to != s->to)
     311                 :            :                         {
     312         [ #  # ]:          0 :                                 if (s->ub)
     313                 :            :                                 {
     314                 :          0 :                                         lb = s->ub;
     315                 :          0 :                                         ++s;
     316                 :            :                                 }
     317                 :            : 
     318                 :          0 :                                 s->to = b->to;
     319                 :            :                         }
     320                 :            : 
     321                 :          0 :                         s->ub = b->ub;
     322                 :            :                 }
     323                 :            :         }
     324                 :            : 
     325                 :          0 :         s->ub = e[ -1].ub;
     326                 :          0 :         ++s;
     327                 :          0 :         nSpans = s - span;
     328                 :          0 : }
     329                 :            : 
     330                 :          0 : static void doGen(const Go *g, const State *s, unsigned *bm, unsigned f, unsigned m)
     331                 :            : {
     332                 :          0 :         Span *b = g->span, *e = &b[g->nSpans];
     333                 :          0 :         unsigned lb = 0;
     334                 :            : 
     335         [ #  # ]:          0 :         for (; b < e; ++b)
     336                 :            :         {
     337         [ #  # ]:          0 :                 if (b->to == s)
     338                 :            :                 {
     339 [ #  # ][ #  # ]:          0 :                         for (; lb < b->ub && lb < 256; ++lb)
                 [ #  # ]
     340                 :            :                         {
     341                 :          0 :                                 bm[lb-f] |= m;
     342                 :            :                         }
     343                 :            :                 }
     344                 :            : 
     345                 :          0 :                 lb = b->ub;
     346                 :            :         }
     347                 :          0 : }
     348                 :            : 
     349                 :          0 : static void prt(std::ostream& o, const Go *g, const State *s)
     350                 :            : {
     351                 :          0 :         Span *b = g->span, *e = &b[g->nSpans];
     352                 :          0 :         unsigned lb = 0;
     353                 :            : 
     354         [ #  # ]:          0 :         for (; b < e; ++b)
     355                 :            :         {
     356         [ #  # ]:          0 :                 if (b->to == s)
     357                 :            :                 {
     358                 :          0 :                         printSpan(o, lb, b->ub);
     359                 :            :                 }
     360                 :            : 
     361                 :          0 :                 lb = b->ub;
     362                 :            :         }
     363                 :          0 : }
     364                 :            : 
     365                 :          0 : static bool matches(const Go *g1, const State *s1, const Go *g2, const State *s2)
     366                 :            : {
     367                 :          0 :         Span *b1 = g1->span, *e1 = &b1[g1->nSpans];
     368                 :          0 :         unsigned lb1 = 0;
     369                 :          0 :         Span *b2 = g2->span, *e2 = &b2[g2->nSpans];
     370                 :          0 :         unsigned lb2 = 0;
     371                 :            : 
     372                 :          0 :         for (;;)
     373                 :            :         {
     374 [ #  # ][ #  # ]:          0 :                 for (; b1 < e1 && b1->to != s1; ++b1)
                 [ #  # ]
     375                 :            :                 {
     376                 :          0 :                         lb1 = b1->ub;
     377                 :            :                 }
     378                 :            : 
     379 [ #  # ][ #  # ]:          0 :                 for (; b2 < e2 && b2->to != s2; ++b2)
                 [ #  # ]
     380                 :            :                 {
     381                 :          0 :                         lb2 = b2->ub;
     382                 :            :                 }
     383                 :            : 
     384         [ #  # ]:          0 :                 if (b1 == e1)
     385                 :            :                 {
     386                 :          0 :                         return b2 == e2;
     387                 :            :                 }
     388                 :            : 
     389         [ #  # ]:          0 :                 if (b2 == e2)
     390                 :            :                 {
     391                 :          0 :                         return false;
     392                 :            :                 }
     393                 :            : 
     394 [ #  # ][ #  # ]:          0 :                 if (lb1 != lb2 || b1->ub != b2->ub)
     395                 :            :                 {
     396                 :          0 :                         return false;
     397                 :            :                 }
     398                 :            : 
     399                 :          0 :                 ++b1;
     400                 :          0 :                 ++b2;
     401                 :            :         }
     402                 :            : }
     403                 :            : 
     404                 :            : BitMap *BitMap::first = NULL;
     405                 :            : 
     406                 :          0 : BitMap::BitMap(const Go *g, const State *x)
     407                 :            :         : go(g)
     408                 :            :         , on(x)
     409                 :            :         , next(first)
     410                 :            :         , i(0)
     411                 :          0 :         , m(0)
     412                 :            : {
     413                 :          0 :         first = this;
     414                 :          0 : }
     415                 :            : 
     416                 :          0 : BitMap::~BitMap()
     417                 :            : {
     418         [ #  # ]:          0 :         delete next;
     419                 :          0 : }
     420                 :            : 
     421                 :          0 : const BitMap *BitMap::find(const Go *g, const State *x)
     422                 :            : {
     423         [ #  # ]:          0 :         for (const BitMap *b = first; b; b = b->next)
     424                 :            :         {
     425         [ #  # ]:          0 :                 if (matches(b->go, b->on, g, x))
     426                 :            :                 {
     427                 :          0 :                         return b;
     428                 :            :                 }
     429                 :            :         }
     430                 :            : 
     431                 :          0 :         return new BitMap(g, x);
     432                 :            : }
     433                 :            : 
     434                 :          0 : const BitMap *BitMap::find(const State *x)
     435                 :            : {
     436         [ #  # ]:          0 :         for (const BitMap *b = first; b; b = b->next)
     437                 :            :         {
     438         [ #  # ]:          0 :                 if (b->on == x)
     439                 :            :                 {
     440                 :          0 :                         return b;
     441                 :            :                 }
     442                 :            :         }
     443                 :            : 
     444                 :          0 :         return NULL;
     445                 :            : }
     446                 :            : 
     447                 :          0 : void BitMap::gen(std::ostream &o, unsigned ind, unsigned lb, unsigned ub)
     448                 :            : {
     449 [ #  # ][ #  # ]:          0 :         if (first && bLastPass && bUsedYYBitmap)
                 [ #  # ]
     450                 :            :         {
     451 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << "static const unsigned char " << mapCodeName["yybm"] << "[] = {";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     452                 :            : 
     453                 :          0 :                 unsigned c = 1, n = ub - lb;
     454                 :          0 :                 const BitMap *cb = first;
     455                 :            : 
     456         [ #  # ]:          0 :                 while((cb = cb->next) != NULL) {
     457                 :          0 :                         ++c;
     458                 :            :                 }
     459                 :          0 :                 BitMap *b = first;
     460                 :            : 
     461 [ #  # ][ #  # ]:          0 :                 unsigned *bm = new unsigned[n];
     462                 :            :                 
     463         [ #  # ]:          0 :                 for (unsigned i = 0, t = 1; b; i += n, t += 8)
     464                 :            :                 {
     465                 :          0 :                         memset(bm, 0, n * sizeof(unsigned));
     466                 :            : 
     467 [ #  # ][ #  # ]:          0 :                         for (unsigned m = 0x80; b && m; m >>= 1)
                 [ #  # ]
     468                 :            :                         {
     469                 :          0 :                                 b->i = i;
     470                 :          0 :                                 b->m = m;
     471                 :          0 :                                 doGen(b->go, b->on, bm, lb, m);
     472                 :          0 :                                 b = const_cast<BitMap*>(b->next);
     473                 :            :                         }
     474                 :            : 
     475         [ #  # ]:          0 :                         if (c > 8)
     476                 :            :                         {
     477 [ #  # ][ #  # ]:          0 :                                 o << "\n" << indent(ind+1) << "/* table " << t << " .. " << std::min(c, t+7) << ": " << i << " */";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     478                 :            :                         }
     479                 :            : 
     480         [ #  # ]:          0 :                         for (unsigned j = 0; j < n; ++j)
     481                 :            :                         {
     482         [ #  # ]:          0 :                                 if (j % 8 == 0)
     483                 :            :                                 {
     484 [ #  # ][ #  # ]:          0 :                                         o << "\n" << indent(ind+1);
         [ #  # ][ #  # ]
     485                 :            :                                 }
     486                 :            : 
     487         [ #  # ]:          0 :                                 if (yybmHexTable)
     488                 :            :                                 {
     489         [ #  # ]:          0 :                                         prtHex(o, bm[j]);
     490                 :            :                                 }
     491                 :            :                                 else
     492                 :            :                                 {
     493 [ #  # ][ #  # ]:          0 :                                         o << std::setw(3) << (unsigned)bm[j];
     494                 :            :                                 }
     495         [ #  # ]:          0 :                                 o  << ", ";
     496                 :            :                         }
     497                 :            :                 }
     498                 :            : 
     499 [ #  # ][ #  # ]:          0 :                 o << "\n" << indent(ind) << "};\n";
         [ #  # ][ #  # ]
                 [ #  # ]
     500                 :            :                 /* stats(); */
     501                 :            :                 
     502         [ #  # ]:          0 :                 delete[] bm;
     503                 :            :         }
     504                 :          0 : }
     505                 :            : 
     506                 :          0 : void BitMap::stats()
     507                 :            : {
     508                 :          0 :         unsigned n = 0;
     509                 :            : 
     510         [ #  # ]:          0 :         for (const BitMap *b = first; b; b = b->next)
     511                 :            :         {
     512                 :          0 :                 prt(std::cerr, b->go, b->on);
     513                 :          0 :                 std::cerr << std::endl;
     514                 :          0 :                 ++n;
     515                 :            :         }
     516                 :            : 
     517                 :          0 :         std::cerr << n << " bitmaps\n";
     518                 :          0 :         first = NULL;
     519                 :          0 : }
     520                 :            : 
     521                 :       1118 : static void genGoTo(std::ostream &o, unsigned ind, const State *from, const State *to, bool & readCh)
     522                 :            : {
     523         [ -  + ]:       1118 :         if (DFlag)
     524                 :            :         {
     525                 :          0 :                 o << from->label << " -> " << to->label << "\n";
     526                 :       1118 :                 return;
     527                 :            :         }
     528                 :            : 
     529 [ +  + ][ +  - ]:       1118 :         if (readCh && from->label + 1 != to->label)
     530                 :            :         {
     531 [ +  - ][ +  - ]:          4 :                 o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     532                 :          4 :                 readCh = false;
     533                 :            :         }
     534                 :            : 
     535 [ +  - ][ +  - ]:       1118 :         o << indent(ind) << "goto " << labelPrefix << to->label << ";\n";
         [ +  - ][ +  - ]
                 [ +  - ]
     536                 :       1118 :         vUsedLabels.insert(to->label);
     537                 :            : }
     538                 :            : 
     539                 :         12 : static void genIf(std::ostream &o, unsigned ind, const char *cmp, unsigned v, bool &readCh)
     540                 :            : {
     541 [ +  - ][ +  - ]:         12 :         o << indent(ind) << "if (";
     542         [ -  + ]:         12 :         if (readCh)
     543                 :            :         {
     544                 :          0 :                 o << "(" << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ")";
     545                 :          0 :                 readCh = false;
     546                 :            :         }
     547                 :            :         else
     548                 :            :         {
     549                 :         12 :                 o << mapCodeName["yych"];
     550                 :            :         }
     551                 :            : 
     552                 :         12 :         o << " " << cmp << " ";
     553                 :         12 :         prtChOrHex(o, v);
     554                 :         12 :         o << ") ";
     555                 :         12 : }
     556                 :            : 
     557                 :        254 : static void need(std::ostream &o, unsigned ind, unsigned n, bool & readCh, bool bSetMarker)
     558                 :            : {
     559         [ +  - ]:        254 :         if (DFlag)
     560                 :            :         {
     561                 :        254 :                 return;
     562                 :            :         }
     563                 :            : 
     564                 :        254 :         unsigned fillIndex = next_fill_index;
     565                 :            : 
     566         [ -  + ]:        254 :         if (fFlag)
     567                 :            :         {
     568                 :          0 :                 next_fill_index++;
     569         [ #  # ]:          0 :                 if (bUseYYSetStateParam)
     570                 :            :                 {
     571 [ #  # ][ #  # ]:          0 :                         o << indent(ind) << mapCodeName["YYSETSTATE"] << "(" << fillIndex << ");\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     572                 :            :                 }
     573                 :            :                 else
     574                 :            :                 {
     575 [ #  # ][ #  # ]:          0 :                         o << indent(ind) << replaceParam(mapCodeName["YYSETSTATE"], yySetStateParam, fillIndex) << "\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     576                 :            :                 }
     577                 :            :         }
     578                 :            : 
     579 [ +  - ][ +  - ]:        254 :         if (bUseYYFill && n > 0)
     580                 :            :         {
     581 [ +  - ][ +  - ]:        254 :                 o << indent(ind);
                 [ +  - ]
     582         [ +  + ]:        254 :                 if (n == 1)
     583                 :            :                 {
     584         [ +  - ]:        250 :                         if (bUseYYFillCheck)
     585                 :            :                         {
     586 [ +  - ][ +  - ]:        250 :                                 o << "if (" << mapCodeName["YYLIMIT"] << " <= " << mapCodeName["YYCURSOR"] << ") ";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     587                 :            :                         }
     588         [ +  - ]:        250 :                         genYYFill(o, ind, n);
     589                 :            :                 }
     590                 :            :                 else
     591                 :            :                 {
     592         [ +  - ]:          4 :                         if (bUseYYFillCheck)
     593                 :            :                         {
     594 [ +  - ][ +  - ]:          4 :                                 o << "if ((" << mapCodeName["YYLIMIT"] << " - " << mapCodeName["YYCURSOR"] << ") < " << n << ") ";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     595                 :            :                         }
     596         [ +  - ]:          4 :                         genYYFill(o, ind, n);
     597                 :            :                 }
     598                 :            :         }
     599                 :            : 
     600         [ -  + ]:        254 :         if (fFlag)
     601                 :            :         {
     602 [ #  # ][ #  # ]:          0 :                 o << mapCodeName["yyFillLabel"] << fillIndex << ":\n";
         [ #  # ][ #  # ]
     603                 :            :         }
     604                 :            : 
     605         [ +  - ]:        254 :         if (n > 0)
     606                 :            :         {
     607         [ +  + ]:        254 :                 if (bSetMarker)
     608                 :            :                 {
     609 [ +  - ][ +  - ]:         44 :                         o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*(" << mapCodeName["YYMARKER"] << " = " << mapCodeName["YYCURSOR"] << ");\n";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     610                 :            :                 }
     611                 :            :                 else
     612                 :            :                 {
     613 [ +  - ][ +  - ]:        210 :                         o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     614                 :            :                 }
     615                 :        254 :                 readCh = false;
     616                 :            :         }
     617                 :            : }
     618                 :            : 
     619                 :        178 : void Match::emit(std::ostream &o, unsigned ind, bool &readCh, const std::string&) const
     620                 :            : {
     621         [ -  + ]:        178 :         if (DFlag)
     622                 :            :         {
     623                 :        178 :                 return;
     624                 :            :         }
     625                 :            : 
     626         [ +  + ]:        178 :         if (state->link)
     627                 :            :         {
     628 [ +  - ][ +  - ]:        158 :                 o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n";
         [ +  - ][ +  - ]
                 [ +  - ]
     629                 :            :         }
     630         [ +  + ]:         20 :         else if (!readAhead())
     631                 :            :         {
     632                 :            :                 /* do not read next char if match */
     633 [ +  - ][ +  - ]:          8 :                 o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n";
         [ +  - ][ +  - ]
                 [ +  - ]
     634                 :          8 :                 readCh = true;
     635                 :            :         }
     636                 :            :         else
     637                 :            :         {
     638 [ +  - ][ +  - ]:         12 :                 o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     639                 :         12 :                 readCh = false;
     640                 :            :         }
     641                 :            : 
     642         [ +  + ]:        178 :         if (state->link)
     643                 :            :         {
     644                 :        158 :                 need(o, ind, state->depth, readCh, false);
     645                 :            :         }
     646                 :            : }
     647                 :            : 
     648                 :          0 : void Enter::emit(std::ostream &o, unsigned ind, bool &readCh, const std::string&) const
     649                 :            : {
     650         [ #  # ]:          0 :         if (state->link)
     651                 :            :         {
     652 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n";
         [ #  # ][ #  # ]
                 [ #  # ]
     653         [ #  # ]:          0 :                 if (vUsedLabels.count(label))
     654                 :            :                 {
     655                 :          0 :                         o << labelPrefix << label << ":\n";
     656                 :            :                 }
     657                 :          0 :                 need(o, ind, state->depth, readCh, false);
     658                 :            :         }
     659                 :            :         else
     660                 :            :         {
     661                 :            :                 /* we shouldn't need 'rule-following' protection here */
     662 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     663         [ #  # ]:          0 :                 if (vUsedLabels.count(label))
     664                 :            :                 {
     665                 :          0 :                         o << labelPrefix << label << ":\n";
     666                 :            :                 }
     667                 :          0 :                 readCh = false;
     668                 :            :         }
     669                 :          0 : }
     670                 :            : 
     671                 :         46 : void Initial::emit(std::ostream &o, unsigned ind, bool &readCh, const std::string&) const
     672                 :            : {
     673 [ +  - ][ -  + ]:         46 :         if (!cFlag && !startLabelName.empty())
                 [ -  + ]
     674                 :            :         {
     675                 :          0 :                 o << startLabelName << ":\n";
     676                 :            :         }
     677                 :            : 
     678 [ +  - ][ -  + ]:         46 :         if (vUsedLabels.count(label+1))
     679                 :            :         {
     680         [ #  # ]:          0 :                 if (state->link)
     681                 :            :                 {
     682 [ #  # ][ #  # ]:          0 :                         o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n";
         [ #  # ][ #  # ]
                 [ #  # ]
     683                 :            :                 }
     684                 :            :                 else
     685                 :            :                 {
     686 [ #  # ][ #  # ]:          0 :                         o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     687                 :            :                 }
     688                 :            :         }
     689                 :            : 
     690         [ -  + ]:         46 :         if (vUsedLabels.count(label))
     691                 :            :         {
     692                 :          0 :                 o << labelPrefix << label << ":\n";
     693                 :            :         }
     694         [ +  - ]:         46 :         else if (!label)
     695                 :            :         {
     696                 :         46 :                 o << "\n";
     697                 :            :         }
     698                 :            : 
     699         [ -  + ]:         46 :         if (dFlag)
     700                 :            :         {
     701 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << mapCodeName["YYDEBUG"] << "(" << label << ", *" << mapCodeName["YYCURSOR"] << ");\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     702                 :            :         }
     703                 :            : 
     704         [ +  - ]:         46 :         if (state->link)
     705                 :            :         {
     706 [ +  + ][ +  - ]:         46 :                 need(o, ind, state->depth, readCh, setMarker && bUsedYYMarker);
     707                 :            :         }
     708                 :            :         else
     709                 :            :         {
     710 [ #  # ][ #  # ]:          0 :                 if (setMarker && bUsedYYMarker)
     711                 :            :                 {
     712 [ #  # ][ #  # ]:          0 :                         o << indent(ind) << mapCodeName["YYMARKER"] << " = " << mapCodeName["YYCURSOR"] << ";\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     713                 :            :                 }
     714                 :          0 :                 readCh = false;
     715                 :            :         }
     716                 :         46 : }
     717                 :            : 
     718                 :         52 : void Save::emit(std::ostream &o, unsigned ind, bool &readCh, const std::string&) const
     719                 :            : {
     720         [ -  + ]:         52 :         if (DFlag)
     721                 :            :         {
     722                 :         52 :                 return;
     723                 :            :         }
     724                 :            : 
     725         [ +  - ]:         52 :         if (bUsedYYAccept)
     726                 :            :         {
     727 [ +  - ][ +  - ]:         52 :                 o << indent(ind) << mapCodeName["yyaccept"] << " = " << selector << ";\n";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     728                 :            :         }
     729                 :            : 
     730         [ +  + ]:         52 :         if (state->link)
     731                 :            :         {
     732         [ +  - ]:         50 :                 if (bUsedYYMarker)
     733                 :            :                 {
     734 [ +  - ][ +  - ]:         50 :                         o << indent(ind) << mapCodeName["YYMARKER"] << " = ++" << mapCodeName["YYCURSOR"] << ";\n";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     735                 :            :                 }
     736                 :         50 :                 need(o, ind, state->depth, readCh, false);
     737                 :            :         }
     738                 :            :         else
     739                 :            :         {
     740         [ +  - ]:          2 :                 if (bUsedYYMarker)
     741                 :            :                 {
     742 [ +  - ][ +  - ]:          2 :                         o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*(" << mapCodeName["YYMARKER"] << " = ++" << mapCodeName["YYCURSOR"] << ");\n";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     743                 :            :                 }
     744                 :            :                 else
     745                 :            :                 {
     746 [ #  # ][ #  # ]:          0 :                         o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     747                 :            :                 }
     748                 :          2 :                 readCh = false;
     749                 :            :         }
     750                 :            : }
     751                 :            : 
     752                 :         54 : Move::Move(State *s) : Action(s)
     753                 :            : {
     754                 :            :         ;
     755                 :         54 : }
     756                 :            : 
     757                 :        104 : void Move::emit(std::ostream &, unsigned, bool &, const std::string&) const
     758                 :            : {
     759                 :            :         ;
     760                 :        104 : }
     761                 :            : 
     762                 :         23 : Accept::Accept(State *x, unsigned n, unsigned *s, State **r)
     763         [ +  - ]:         23 :                 : Action(x), nRules(n), saves(s), rules(r)
     764                 :            : {
     765                 :            :         ;
     766                 :         23 : }
     767                 :            : 
     768                 :         23 : void Accept::genRuleMap()
     769                 :            : {
     770         [ +  + ]:         69 :         for (unsigned i = 0; i < nRules; ++i)
     771                 :            :         {
     772         [ +  + ]:         46 :                 if (saves[i] != ~0u)
     773                 :            :                 {
     774                 :         43 :                         mapRules[saves[i]] = rules[i];
     775                 :            :                 }
     776                 :            :         }
     777                 :         23 : }
     778                 :            : 
     779                 :        120 : void Accept::emitBinary(std::ostream &o, unsigned ind, unsigned l, unsigned r, bool &readCh) const
     780                 :            : {
     781         [ +  + ]:        120 :         if (l < r)
     782                 :            :         {
     783                 :         40 :                 unsigned m = (l + r) >> 1;
     784                 :            : 
     785         [ -  + ]:         40 :                 assert(bUsedYYAccept);
     786 [ +  - ][ +  - ]:         40 :                 o << indent(ind) << "if (" << mapCodeName["yyaccept"] << (r == l+1 ? " == " : " <= ") << m << ") {\n";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     787                 :         40 :                 emitBinary(o, ++ind, l, m, readCh);
     788 [ +  - ][ +  - ]:         40 :                 o << indent(--ind) << "} else {\n";
     789                 :         40 :                 emitBinary(o, ++ind, m + 1, r, readCh);
     790 [ +  - ][ +  - ]:         40 :                 o << indent(--ind) << "}\n";
     791                 :            :         }
     792                 :            :         else
     793                 :            :         {
     794 [ +  - ][ +  - ]:         80 :                 genGoTo(o, ind, state, mapRules.find(l)->second, readCh);
     795                 :            :         }
     796                 :        120 : }
     797                 :            : 
     798                 :         44 : void Accept::emit(std::ostream &o, unsigned ind, bool &readCh, const std::string&) const
     799                 :            : {
     800         [ +  - ]:         44 :         if (mapRules.size() > 0)
     801                 :            :         {
     802                 :         44 :                 bUsedYYMarker = true;
     803         [ +  - ]:         44 :                 if (!DFlag)
     804                 :            :                 {
     805 [ +  - ][ +  - ]:         44 :                         o << indent(ind) << mapCodeName["YYCURSOR"] << " = " << mapCodeName["YYMARKER"] << ";\n";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     806                 :            :                 }
     807                 :            : 
     808         [ -  + ]:         44 :                 if (readCh) // shouldn't be necessary, but might become at some point
     809                 :            :                 {
     810 [ #  # ][ #  # ]:          0 :                         o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     811                 :          0 :                         readCh = false;
     812                 :            :                 }
     813                 :            : 
     814         [ +  + ]:         44 :                 if (mapRules.size() > 1)
     815                 :            :                 {
     816                 :         40 :                         bUsedYYAccept = true;
     817                 :            : 
     818 [ -  + ][ #  # ]:         40 :                         if (gFlag && mapRules.size() >= cGotoThreshold)
                 [ -  + ]
     819                 :            :                         {
     820 [ #  # ][ #  # ]:          0 :                                 o << indent(ind++) << "{\n";
     821 [ #  # ][ #  # ]:          0 :                                 o << indent(ind++) << "static void *" << mapCodeName["yytarget"] << "[" << mapRules.size() << "] = {\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     822 [ #  # ][ #  # ]:          0 :                                 for (RuleMap::const_iterator it = mapRules.begin(); it != mapRules.end(); ++it)
                 [ #  # ]
     823                 :            :                                 {
     824 [ #  # ][ #  # ]:          0 :                                         o << indent(ind) << "&&" << labelPrefix << it->second->label << ",\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     825 [ #  # ][ #  # ]:          0 :                                         vUsedLabels.insert(it->second->label);
     826                 :            :                                 }
     827 [ #  # ][ #  # ]:          0 :                                 o << indent(--ind) << "};\n";
     828 [ #  # ][ #  # ]:          0 :                                 o << indent(ind) << "goto *" << mapCodeName["yytarget"] << "[" << mapCodeName["yyaccept"] << "];\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     829 [ #  # ][ #  # ]:          0 :                                 o << indent(--ind) << "}\n";
     830                 :            :                         }
     831 [ +  - ][ +  - ]:         40 :                         else if (sFlag || (mapRules.size() == 2 && !DFlag))
         [ +  - ][ +  - ]
     832                 :            :                         {
     833                 :         40 :                                 emitBinary(o, ind, 0, mapRules.size() - 1, readCh);
     834                 :            :                         }
     835         [ #  # ]:          0 :                         else if (DFlag)
     836                 :            :                         {
     837 [ #  # ][ #  # ]:          0 :                                 for (RuleMap::const_iterator it = mapRules.begin(); it != mapRules.end(); ++it)
                 [ #  # ]
     838                 :            :                                 {
     839 [ #  # ][ #  # ]:          0 :                                         o << state->label << " -> " << it->second->label;
         [ #  # ][ #  # ]
     840 [ #  # ][ #  # ]:          0 :                                         o << " [label=\"yyaccept=" << it->first << "\"]\n";
         [ #  # ][ #  # ]
     841                 :            :                                 }
     842                 :            :                         }
     843                 :            :                         else
     844                 :            :                         {
     845 [ #  # ][ #  # ]:          0 :                                 o << indent(ind) << "switch (" << mapCodeName["yyaccept"] << ") {\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     846                 :            : 
     847 [ #  # ][ #  # ]:          0 :                                 RuleMap::const_iterator it = mapRules.begin(), end = mapRules.end();
     848                 :            :                 
     849         [ #  # ]:          0 :                                 while (it != end)
     850                 :            :                                 {
     851                 :          0 :                                         RuleMap::const_iterator tmp = it;
     852                 :            : 
     853         [ #  # ]:          0 :                                         if (++it == end)
     854                 :            :                                         {
     855 [ #  # ][ #  # ]:          0 :                                                 o << indent(ind) << "default:\t";
         [ #  # ][ #  # ]
     856                 :            :                                         }
     857                 :            :                                         else
     858                 :            :                                         {
     859 [ #  # ][ #  # ]:          0 :                                                 o << indent(ind) << "case " << tmp->first << ": \t";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     860                 :            :                                         }
     861                 :            : 
     862 [ #  # ][ #  # ]:          0 :                                         genGoTo(o, 0, state, tmp->second, readCh);
     863                 :            :                                 }
     864                 :            :                         
     865 [ #  # ][ #  # ]:          0 :                                 o << indent(ind) << "}\n";
         [ #  # ][ #  # ]
     866                 :            :                         }
     867                 :            :                 }
     868                 :            :                 else
     869                 :            :                 {
     870                 :            :                         // no need to write if statement here since there is only case 0.
     871 [ +  - ][ +  - ]:          4 :                         genGoTo(o, ind, state, mapRules.find(0)->second, readCh);
                 [ +  - ]
     872                 :            :                 }
     873                 :            :         }
     874                 :         44 : }
     875                 :            : 
     876                 :         47 : Rule::Rule(State *s, RuleOp *r) : Action(s), rule(r)
     877                 :            : {
     878                 :            :         ;
     879                 :         47 : }
     880                 :            : 
     881                 :         90 : void Rule::emit(std::ostream &o, unsigned ind, bool &, const std::string& condName) const
     882                 :            : {
     883         [ -  + ]:         90 :         if (DFlag)
     884                 :            :         {
     885                 :          0 :                 o << state->label << " [label=\"" << rule->code->line << "\"]\n";
     886                 :         90 :                 return;
     887                 :            :         }
     888                 :            : 
     889                 :         90 :         unsigned back = rule->ctx->fixedLength();
     890                 :            : 
     891         [ -  + ]:         90 :         if (back != 0u)
     892                 :            :         {
     893 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << mapCodeName["YYCURSOR"] << " = " << mapCodeName["YYCTXMARKER"] << ";\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     894                 :            :         }
     895                 :            : 
     896 [ -  + ][ #  # ]:         90 :         if (rule->code->newcond.length() && condName != rule->code->newcond)
                 [ -  + ]
     897                 :            :         {
     898                 :          0 :                 genSetCondition(o, ind, rule->code->newcond);
     899                 :            :         }
     900                 :            : 
     901 [ -  + ][ #  # ]:         90 :         if (!yySetupRule.empty() && !rule->code->autogen)
                 [ -  + ]
     902                 :            :         {
     903 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << yySetupRule << "\n";
                 [ #  # ]
     904                 :            :         }
     905                 :            : 
     906         [ +  - ]:         90 :         o << indent(ind);
     907         [ -  + ]:         90 :         if (rule->code->autogen)
     908                 :            :         {
     909 [ #  # ][ #  # ]:          0 :                 o << replaceParam(condGoto, condGotoParam, condPrefix + rule->code->newcond);
         [ #  # ][ #  # ]
                 [ #  # ]
     910                 :            :         }
     911                 :            :         else
     912                 :            :         {
     913                 :         90 :                 o << rule->code->text;
     914                 :            :         }
     915                 :         90 :         o << "\n";
     916                 :            : }
     917                 :            : 
     918                 :        126 : static void doLinear(std::ostream &o, unsigned ind, Span *s, unsigned n, const State *from, const State *next, bool &readCh, unsigned mask)
     919                 :            : {
     920                 :        126 :         for (;;)
     921                 :            :         {
     922                 :        126 :                 State *bg = s[0].to;
     923                 :            : 
     924 [ -  + ][ #  # ]:        126 :                 while (n >= 3 && s[2].to == bg && (s[1].ub - s[0].ub) == 1)
         [ #  # ][ -  + ]
     925                 :            :                 {
     926 [ #  # ][ #  # ]:          0 :                         if (s[1].to == next && n == 3)
     927                 :            :                         {
     928 [ #  # ][ #  # ]:          0 :                                 if (!mask || (s[0].ub > 0x00FF))
     929                 :            :                                 {
     930                 :          0 :                                         genIf(o, ind, "!=", s[0].ub, readCh);
     931                 :          0 :                                         genGoTo(o, 0, from, bg, readCh);
     932                 :            :                                 }
     933 [ #  # ][ #  # ]:          0 :                                 if (next->label != from->label + 1 || DFlag)
     934                 :            :                                 {
     935                 :          0 :                                         genGoTo(o, ind, from, next, readCh);
     936                 :            :                                 }
     937                 :          0 :                                 return ;
     938                 :            :                         }
     939                 :            :                         else
     940                 :            :                         {
     941 [ #  # ][ #  # ]:          0 :                                 if (!mask || (s[0].ub > 0x00FF))
     942                 :            :                                 {
     943                 :          0 :                                         genIf(o, ind, "==", s[0].ub, readCh);
     944                 :          0 :                                         genGoTo(o, 0, from, s[1].to, readCh);
     945                 :            :                                 }
     946                 :            :                         }
     947                 :            : 
     948                 :          0 :                         n -= 2;
     949                 :          0 :                         s += 2;
     950                 :            :                 }
     951                 :            : 
     952         [ +  + ]:        126 :                 if (n == 1)
     953                 :            :                 {
     954                 :            :                         //              if(bg != next){
     955 [ +  + ][ -  + ]:        114 :                         if (s[0].to->label != from->label + 1 || DFlag)
     956                 :            :                         {
     957                 :          6 :                                 genGoTo(o, ind, from, s[0].to, readCh);
     958                 :            :                         }
     959                 :            :                         //              }
     960                 :        114 :                         return ;
     961                 :            :                 }
     962 [ +  - ][ +  + ]:         12 :                 else if (n == 2 && bg == next)
     963                 :            :                 {
     964 [ -  + ][ #  # ]:         10 :                         if (!mask || (s[0].ub > 0x00FF))
     965                 :            :                         {
     966                 :         10 :                                 genIf(o, ind, ">=", s[0].ub, readCh);
     967                 :         10 :                                 genGoTo(o, 0, from, s[1].to, readCh);
     968                 :            :                         }
     969 [ +  - ][ -  + ]:         10 :                         if (next->label != from->label + 1 || DFlag)
     970                 :            :                         {
     971                 :          0 :                                 genGoTo(o, ind, from, next, readCh);
     972                 :            :                         }
     973                 :         10 :                         return ;
     974                 :            :                 }
     975                 :            :                 else
     976                 :            :                 {
     977 [ -  + ][ #  # ]:          2 :                         if (!mask || ((s[0].ub - 1) > 0x00FF))
     978                 :            :                         {
     979                 :          2 :                                 genIf(o, ind, "<=", s[0].ub - 1, readCh);
     980                 :          2 :                                 genGoTo(o, 0, from, bg, readCh);
     981                 :            :                         }
     982                 :          2 :                         n -= 1;
     983                 :          2 :                         s += 1;
     984                 :            :                 }
     985                 :            :         }
     986                 :            : 
     987                 :            :         if (next->label != from->label + 1 || DFlag)
     988                 :            :         {
     989                 :            :                 genGoTo(o, ind, from, next, readCh);
     990                 :            :         }
     991                 :            : }
     992                 :            : 
     993                 :        124 : void Go::genLinear(std::ostream &o, unsigned ind, const State *from, const State *next, bool &readCh, unsigned mask) const
     994                 :            : {
     995                 :        124 :         doLinear(o, ind, span, nSpans, from, next, readCh, mask);
     996                 :        124 : }
     997                 :            : 
     998                 :          0 : static void printDotCharInterval(std::ostream &o, unsigned lastPrintableChar, unsigned chr, const State *from, const State *to, bool multipleIntervals)
     999                 :            : {
    1000                 :          0 :         o << from->label << " -> " << to->label;
    1001                 :          0 :         o << " [label=";
    1002                 :            : 
    1003         [ #  # ]:          0 :         if (lastPrintableChar != 0)
    1004                 :            :         {
    1005                 :          0 :                 --chr; // we are already one char past the end
    1006                 :            : 
    1007                 :            :                 // make an interval (e.g. [A-Z])
    1008         [ #  # ]:          0 :                 if (lastPrintableChar != chr)
    1009                 :            :                 {
    1010                 :          0 :                         o << "\"[" << (char)lastPrintableChar << "-" << (char)chr << "]\"";
    1011                 :            : 
    1012         [ #  # ]:          0 :                         if (multipleIntervals)
    1013                 :            :                         {
    1014                 :          0 :                                 o << "]\n";
    1015                 :          0 :                                 o << from->label << " -> " << to->label;
    1016                 :          0 :                                 o << " [label=";
    1017                 :          0 :                                 prtChOrHex(o, ++chr);
    1018                 :            :                         }
    1019                 :            :                 }
    1020                 :            :                 else
    1021                 :            :                 {
    1022                 :          0 :                         prtChOrHex(o, chr);
    1023                 :            :                 }
    1024                 :            :         }
    1025                 :            :         else
    1026                 :            :         {
    1027                 :          0 :                 prtChOrHex(o, chr);
    1028                 :            :         }
    1029                 :            : 
    1030                 :          0 :         o << "]";
    1031                 :          0 : }
    1032                 :            : 
    1033                 :        778 : static bool genCases(std::ostream &o, unsigned ind, unsigned lb, Span *s, bool &newLine, unsigned mask, const State *from, const State *to)
    1034                 :            : {
    1035                 :        778 :         bool used = false;
    1036                 :        778 :         unsigned lastPrintableChar = 0;
    1037                 :            : 
    1038         [ +  + ]:        778 :         if (!newLine)
    1039                 :            :         {
    1040                 :         18 :                 o << "\n";
    1041                 :            :         }
    1042                 :        778 :         newLine = true;
    1043         [ +  - ]:        778 :         if (lb < s->ub)
    1044                 :            :         {
    1045                 :       1126 :                 for (;;)
    1046                 :            :                 {
    1047 [ -  + ][ #  # ]:       1126 :                         if (!mask || lb > 0x00FF)
    1048                 :            :                         {
    1049         [ -  + ]:       1126 :                                 if (DFlag)
    1050                 :            :                                 {
    1051 [ #  # ][ #  # ]:          0 :                                         if ((lb >= 'A' && lb <= 'Z') || (lb >= 'a' && lb <= 'z') || (lb >= '0' && lb <= '9'))
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1052                 :            :                                         {
    1053         [ #  # ]:          0 :                                                 if (lastPrintableChar == 0)
    1054                 :            :                                                 {
    1055                 :          0 :                                                         lastPrintableChar = lb;
    1056                 :            :                                                 }
    1057                 :            : 
    1058         [ #  # ]:          0 :                                                 if (++lb == s->ub)
    1059                 :            :                                                 {
    1060                 :          0 :                                                         break;
    1061                 :            :                                                 }
    1062                 :          0 :                                                 continue;
    1063                 :            :                                         }
    1064                 :            : 
    1065                 :          0 :                                         printDotCharInterval(o, lastPrintableChar, lb, from, to, true);
    1066                 :          0 :                                         lastPrintableChar = 0;
    1067                 :            :                                 }
    1068                 :            :                                 else
    1069                 :            :                                 {
    1070 [ +  - ][ +  - ]:       1126 :                                         o << indent(ind) << "case ";
    1071                 :       1126 :                                         prtChOrHex(o, lb);
    1072                 :       1126 :                                         o << ":";
    1073 [ -  + ][ #  # ]:       1126 :                                         if (dFlag && eFlag && lb < 256u && isprint(talx[lb]))
         [ #  # ][ #  # ]
    1074                 :            :                                         {
    1075 [ #  # ][ #  # ]:          0 :                                                 o << " /* " << std::string(1, talx[lb]) << " */";
         [ #  # ][ #  # ]
    1076                 :            :                                         }
    1077                 :            :                                 }
    1078                 :       1126 :                                 newLine = false;
    1079                 :       1126 :                                 used = true;
    1080                 :            :                         }
    1081                 :            : 
    1082         [ +  + ]:       1126 :                         if (++lb == s->ub)
    1083                 :            :                         {
    1084                 :        778 :                                 break;
    1085                 :            :                         }
    1086                 :            : 
    1087                 :        348 :                         o << "\n";
    1088                 :        348 :                         newLine = true;
    1089                 :            :                 }
    1090                 :            :         }
    1091                 :            : 
    1092         [ -  + ]:        778 :         if (lastPrintableChar != 0)
    1093                 :            :         {
    1094                 :          0 :                 printDotCharInterval(o, lastPrintableChar, lb, from, to, false);
    1095                 :            : 
    1096                 :          0 :                 o << "\n";
    1097                 :          0 :                 newLine = true;
    1098                 :            :         }
    1099                 :            : 
    1100                 :        778 :         return used;
    1101                 :            : }
    1102                 :            : 
    1103                 :        380 : void Go::genSwitch(std::ostream &o, unsigned ind, const State *from, const State *next, bool &readCh, unsigned mask) const
    1104                 :            : {
    1105                 :        380 :         bool newLine = true;
    1106                 :            : 
    1107 [ -  + ][ +  + ]:        380 :         if ((mask ? wSpans : nSpans) <= 2)
    1108                 :            :         {
    1109         [ +  - ]:        124 :                 genLinear(o, ind, from, next, readCh, mask);
    1110                 :            :         }
    1111                 :            :         else
    1112                 :            :         {
    1113                 :        256 :                 State *def = span[nSpans - 1].to;
    1114 [ +  - ][ +  - ]:        256 :                 Span **sP = new Span * [nSpans - 1], **r, **s, **t;
    1115                 :            : 
    1116                 :        256 :                 t = &sP[0];
    1117                 :            : 
    1118         [ +  + ]:       1756 :                 for (unsigned i = 0; i < nSpans; ++i)
    1119                 :            :                 {
    1120         [ +  + ]:       1500 :                         if (span[i].to != def)
    1121                 :            :                         {
    1122                 :        778 :                                 *(t++) = &span[i];
    1123                 :            :                         }
    1124                 :            :                 }
    1125                 :            : 
    1126         [ +  - ]:        256 :                 if (!DFlag)
    1127                 :            :                 {
    1128         [ -  + ]:        256 :                         if (dFlag)
    1129                 :            :                         {
    1130 [ #  # ][ #  # ]:          0 :                                 o << indent(ind) << mapCodeName["YYDEBUG"] << "(-1, " << mapCodeName["yych"] << ");\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1131                 :            :                         }
    1132                 :            : 
    1133         [ -  + ]:        256 :                         if (readCh)
    1134                 :            :                         {
    1135 [ #  # ][ #  # ]:          0 :                                 o << indent(ind) << "switch ((" << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ")) {\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1136                 :          0 :                                 readCh = false;
    1137                 :            :                         }
    1138                 :            :                         else
    1139                 :            :                         {
    1140 [ +  - ][ +  - ]:        256 :                                 o << indent(ind) << "switch (" << mapCodeName["yych"] << ") {\n";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
    1141                 :            :                         }
    1142                 :            :                 }
    1143                 :            : 
    1144         [ +  + ]:       1016 :                 while (t != &sP[0])
    1145                 :            :                 {
    1146                 :        760 :                         bool used = false;
    1147                 :            : 
    1148                 :        760 :                         r = s = &sP[0];
    1149                 :            : 
    1150                 :        760 :                         const State *to = (*s)->to;
    1151                 :            : 
    1152         [ +  + ]:        760 :                         if (*s == &span[0])
    1153                 :            :                         {
    1154         [ +  - ]:        246 :                                 used |= genCases(o, ind, 0, *s, newLine, mask, from, to);
    1155                 :            :                         }
    1156                 :            :                         else
    1157                 :            :                         {
    1158         [ +  - ]:        514 :                                 used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask, from, to);
    1159                 :            :                         }
    1160                 :            : 
    1161         [ +  + ]:       1730 :                         while (++s < t)
    1162                 :            :                         {
    1163         [ +  + ]:        970 :                                 if ((*s)->to == to)
    1164                 :            :                                 {
    1165         [ +  - ]:         18 :                                         used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask, from, to);
    1166                 :            :                                 }
    1167                 :            :                                 else
    1168                 :            :                                 {
    1169                 :        952 :                                         *(r++) = *s;
    1170                 :            :                                 }
    1171                 :            :                         }
    1172                 :            : 
    1173 [ +  - ][ +  - ]:        760 :                         if (used && !DFlag)
    1174                 :            :                         {
    1175 [ -  + ][ +  - ]:        760 :                                 genGoTo(o, newLine ? ind+1 : 1, from, to, readCh);
    1176                 :        760 :                                 newLine = true;
    1177                 :            :                         }
    1178                 :        760 :                         t = r;
    1179                 :            :                 }
    1180                 :            : 
    1181         [ -  + ]:        256 :                 if (DFlag)
    1182                 :            :                 {
    1183         [ #  # ]:          0 :                         if (!newLine)
    1184                 :            :                         {
    1185         [ #  # ]:          0 :                                 o << "\n";
    1186                 :          0 :                                 newLine = true;
    1187                 :            :                         }
    1188                 :            : 
    1189 [ #  # ][ #  # ]:          0 :                         o << from->label << " -> " << def->label;
                 [ #  # ]
    1190         [ #  # ]:          0 :                         o << " [label=default]\n" ;
    1191                 :            :                 }
    1192                 :            :                 else
    1193                 :            :                 {
    1194 [ +  - ][ +  - ]:        256 :                         o << indent(ind) << "default:";
         [ +  - ][ +  - ]
    1195         [ +  - ]:        256 :                         genGoTo(o, 1, from, def, readCh);
    1196 [ +  - ][ +  - ]:        256 :                         o << indent(ind) << "}\n";
         [ +  - ][ +  - ]
    1197                 :            :                 }
    1198                 :            : 
    1199         [ +  - ]:        256 :                 delete [] sP;
    1200                 :            :         }
    1201                 :        380 : }
    1202                 :            : 
    1203                 :          0 : static void doBinary(std::ostream &o, unsigned ind, Span *s, unsigned n, const State *from, const State *next, bool &readCh, unsigned mask)
    1204                 :            : {
    1205         [ #  # ]:          0 :         if (n <= 4)
    1206                 :            :         {
    1207                 :          0 :                 doLinear(o, ind, s, n, from, next, readCh, mask);
    1208                 :            :         }
    1209                 :            :         else
    1210                 :            :         {
    1211                 :          0 :                 unsigned h = n / 2;
    1212                 :            : 
    1213                 :          0 :                 genIf(o, ind, "<=", s[h - 1].ub - 1, readCh);
    1214                 :          0 :                 o << "{\n";
    1215                 :          0 :                 doBinary(o, ind+1, &s[0], h, from, next, readCh, mask);
    1216 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << "} else {\n";
    1217                 :          0 :                 doBinary(o, ind+1, &s[h], n - h, from, next, readCh, mask);
    1218 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << "}\n";
    1219                 :            :         }
    1220                 :          0 : }
    1221                 :            : 
    1222                 :          0 : void Go::genBinary(std::ostream &o, unsigned ind, const State *from, const State *next, bool &readCh, unsigned mask) const
    1223                 :            : {
    1224         [ #  # ]:          0 :         if (mask)
    1225                 :            :         {
    1226         [ #  # ]:          0 :                 Span * sc = new Span[wSpans];
    1227                 :            :                 
    1228         [ #  # ]:          0 :                 for (unsigned i = 0, j = 0; i < nSpans; i++)
    1229                 :            :                 {
    1230         [ #  # ]:          0 :                         if (span[i].ub > 0xFF)
    1231                 :            :                         {
    1232                 :          0 :                                 sc[j++] = span[i];
    1233                 :            :                         }
    1234                 :            :                 }
    1235                 :            : 
    1236                 :          0 :                 doBinary(o, ind, sc, wSpans, from, next, readCh, mask);
    1237                 :            : 
    1238         [ #  # ]:          0 :                 delete[] sc;
    1239                 :            :         }
    1240                 :            :         else
    1241                 :            :         {
    1242                 :          0 :                 doBinary(o, ind, span, nSpans, from, next, readCh, mask);
    1243                 :            :         }
    1244                 :          0 : }
    1245                 :            : 
    1246                 :        514 : void Go::genBase(std::ostream &o, unsigned ind, const State *from, const State *next, bool &readCh, unsigned mask) const
    1247                 :            : {
    1248 [ -  + ][ +  + ]:        514 :         if ((mask ? wSpans : nSpans) == 0)
    1249                 :            :         {
    1250                 :        134 :                 return ;
    1251                 :            :         }
    1252                 :            : 
    1253         [ +  - ]:        380 :         if (!sFlag)
    1254                 :            :         {
    1255                 :        380 :                 genSwitch(o, ind, from, next, readCh, mask);
    1256                 :        380 :                 return ;
    1257                 :            :         }
    1258                 :            : 
    1259 [ #  # ][ #  # ]:          0 :         if ((mask ? wSpans : nSpans) > 8)
    1260                 :            :         {
    1261                 :          0 :                 Span *bot = &span[0], *top = &span[nSpans - 1];
    1262                 :            :                 unsigned util;
    1263                 :            : 
    1264         [ #  # ]:          0 :                 if (bot[0].to == top[0].to)
    1265                 :            :                 {
    1266                 :          0 :                         util = (top[ -1].ub - bot[0].ub) / (nSpans - 2);
    1267                 :            :                 }
    1268                 :            :                 else
    1269                 :            :                 {
    1270         [ #  # ]:          0 :                         if (bot[0].ub > (top[0].ub - top[ -1].ub))
    1271                 :            :                         {
    1272                 :          0 :                                 util = (top[0].ub - bot[0].ub) / (nSpans - 1);
    1273                 :            :                         }
    1274                 :            :                         else
    1275                 :            :                         {
    1276                 :          0 :                                 util = top[ -1].ub / (nSpans - 1);
    1277                 :            :                         }
    1278                 :            :                 }
    1279                 :            : 
    1280         [ #  # ]:          0 :                 if (util <= 2)
    1281                 :            :                 {
    1282                 :          0 :                         genSwitch(o, ind, from, next, readCh, mask);
    1283                 :          0 :                         return ;
    1284                 :            :                 }
    1285                 :            :         }
    1286                 :            : 
    1287 [ #  # ][ #  # ]:          0 :         if ((mask ? wSpans : nSpans) > 5)
    1288                 :            :         {
    1289                 :          0 :                 genBinary(o, ind, from, next, readCh, mask);
    1290                 :            :         }
    1291                 :            :         else
    1292                 :            :         {
    1293                 :        514 :                 genLinear(o, ind, from, next, readCh, mask);
    1294                 :            :         }
    1295                 :            : }
    1296                 :            : 
    1297                 :          0 : void Go::genCpGoto(std::ostream &o, unsigned ind, const State *from, const State *next, bool &readCh) const
    1298                 :            : {
    1299         [ #  # ]:          0 :         std::string sYych;
    1300                 :            :         
    1301         [ #  # ]:          0 :         if (readCh)
    1302                 :            :         {
    1303 [ #  # ][ #  # ]:          0 :                 sYych = "(" + mapCodeName["yych"] + " = " + yychConversion + "*" + mapCodeName["YYCURSOR"] + ")";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1304                 :            :         }
    1305                 :            :         else
    1306                 :            :         {
    1307 [ #  # ][ #  # ]:          0 :                 sYych = mapCodeName["yych"];
    1308                 :            :         }
    1309                 :            : 
    1310                 :          0 :         readCh = false;
    1311         [ #  # ]:          0 :         if (wFlag)
    1312                 :            :         {
    1313 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << "if (" << sYych <<" & ~0xFF) {\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1314         [ #  # ]:          0 :                 genBase(o, ind+1, from, next, readCh, 1);
    1315 [ #  # ][ #  # ]:          0 :                 o << indent(ind++) << "} else {\n";
         [ #  # ][ #  # ]
    1316 [ #  # ][ #  # ]:          0 :                 sYych = mapCodeName["yych"];
    1317                 :            :         }
    1318                 :            :         else
    1319                 :            :         {
    1320 [ #  # ][ #  # ]:          0 :                 o << indent(ind++) << "{\n";
         [ #  # ][ #  # ]
    1321                 :            :         }
    1322 [ #  # ][ #  # ]:          0 :         o << indent(ind++) << "static void *" << mapCodeName["yytarget"] << "[256] = {\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1323 [ #  # ][ #  # ]:          0 :         o << indent(ind);
                 [ #  # ]
    1324                 :            : 
    1325                 :          0 :         unsigned ch = 0;
    1326         [ #  # ]:          0 :         for (unsigned i = 0; i < lSpans; ++i)
    1327                 :            :         {
    1328         [ #  # ]:          0 :                 vUsedLabels.insert(span[i].to->label);
    1329         [ #  # ]:          0 :                 for(; ch < span[i].ub; ++ch)
    1330                 :            :                 {
    1331 [ #  # ][ #  # ]:          0 :                         o << "&&" << labelPrefix << span[i].to->label;
                 [ #  # ]
    1332         [ #  # ]:          0 :                         if (ch == 255)
    1333                 :            :                         {
    1334         [ #  # ]:          0 :                                 o << "\n";
    1335                 :          0 :                                 i = lSpans;
    1336                 :          0 :                                 break;
    1337                 :            :                         }
    1338         [ #  # ]:          0 :                         else if (ch % 8 == 7)
    1339                 :            :                         {
    1340 [ #  # ][ #  # ]:          0 :                                 o << ",\n" << indent(ind);
         [ #  # ][ #  # ]
    1341                 :            :                         }
    1342                 :            :                         else
    1343                 :            :                         {
    1344 [ #  # ][ #  # ]:          0 :                                 o << "," << space(span[i].to->label);
         [ #  # ][ #  # ]
    1345                 :            :                         }
    1346                 :            :                 }
    1347                 :            :         }
    1348 [ #  # ][ #  # ]:          0 :         o << indent(--ind) << "};\n";
         [ #  # ][ #  # ]
    1349 [ #  # ][ #  # ]:          0 :         o << indent(ind) << "goto *" << mapCodeName["yytarget"] << "[" << sYych << "];\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1350 [ #  # ][ #  # ]:          0 :         o << indent(--ind) << "}\n";
         [ #  # ][ #  # ]
                 [ #  # ]
    1351                 :          0 : }
    1352                 :            : 
    1353                 :        514 : void Go::genGoto(std::ostream &o, unsigned ind, const State *from, const State *next, bool &readCh)
    1354                 :            : {
    1355 [ +  - ][ -  + ]:        514 :         if ((gFlag || wFlag) && wSpans == ~0u)
                 [ #  # ]
    1356                 :            :         {
    1357                 :          0 :                 unsigned nBitmaps = 0;
    1358         [ #  # ]:          0 :                 std::set<unsigned> vTargets;
    1359                 :          0 :                 wSpans = 0;
    1360                 :          0 :                 lSpans = 1;
    1361                 :          0 :                 dSpans = 0;
    1362         [ #  # ]:          0 :                 for (unsigned i = 0; i < nSpans; ++i)
    1363                 :            :                 {
    1364         [ #  # ]:          0 :                         if (span[i].ub > 0xFF)
    1365                 :            :                         {
    1366                 :          0 :                                 wSpans++;
    1367                 :            :                         }
    1368 [ #  # ][ #  # ]:          0 :                         if (span[i].ub < 0x100 || !wFlag)
    1369                 :            :                         {
    1370                 :          0 :                                 lSpans++;
    1371                 :            : 
    1372                 :          0 :                                 State *to = span[i].to;
    1373                 :            :         
    1374 [ #  # ][ #  # ]:          0 :                                 if (to && to->isBase)
    1375                 :            :                                 {
    1376                 :          0 :                                         const BitMap *b = BitMap::find(to);
    1377                 :            :         
    1378 [ #  # ][ #  # ]:          0 :                                         if (b && matches(b->go, b->on, this, to))
                 [ #  # ]
    1379                 :            :                                         {
    1380                 :          0 :                                                 nBitmaps++;
    1381                 :            :                                         }
    1382                 :            :                                         else
    1383                 :            :                                         {
    1384                 :          0 :                                                 dSpans++;
    1385         [ #  # ]:          0 :                                                 vTargets.insert(to->label);
    1386                 :          0 :                                         }
    1387                 :            :                                 }
    1388                 :            :                                 else
    1389                 :            :                                 {
    1390                 :          0 :                                         dSpans++;
    1391         [ #  # ]:          0 :                                         vTargets.insert(to->label);
    1392                 :            :                                 }
    1393                 :            :                         }
    1394                 :            :                 }
    1395 [ #  # ][ #  # ]:          0 :                 lTargets = vTargets.size() >> nBitmaps;
    1396                 :            :         }
    1397                 :            : 
    1398 [ -  + ][ #  # ]:        514 :         if (gFlag && (lTargets >= cGotoThreshold || dSpans >= cGotoThreshold))
                 [ #  # ]
    1399                 :            :         {
    1400                 :          0 :                 genCpGoto(o, ind, from, next, readCh);
    1401                 :          0 :                 return;
    1402                 :            :         }
    1403         [ -  + ]:        514 :         else if (bFlag)
    1404                 :            :         {
    1405         [ #  # ]:          0 :                 for (unsigned i = 0; i < nSpans; ++i)
    1406                 :            :                 {
    1407                 :          0 :                         State *to = span[i].to;
    1408                 :            : 
    1409 [ #  # ][ #  # ]:          0 :                         if (to && to->isBase)
    1410                 :            :                         {
    1411                 :          0 :                                 const BitMap *b = BitMap::find(to);
    1412         [ #  # ]:          0 :                                 std::string sYych;
    1413                 :            : 
    1414 [ #  # ][ #  # ]:          0 :                                 if (b && matches(b->go, b->on, this, to))
                 [ #  # ]
    1415                 :            :                                 {
    1416                 :          0 :                                         Go go;
    1417 [ #  # ][ #  # ]:          0 :                                         go.span = new Span[nSpans];
    1418                 :          0 :                                         go.unmap(this, to);
    1419         [ #  # ]:          0 :                                         if (readCh)
    1420                 :            :                                         {
    1421 [ #  # ][ #  # ]:          0 :                                                 sYych = "(" + mapCodeName["yych"] + " = " + yychConversion + "*" + mapCodeName["YYCURSOR"] + ")";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1422                 :            :                                         }
    1423                 :            :                                         else
    1424                 :            :                                         {
    1425 [ #  # ][ #  # ]:          0 :                                                 sYych = mapCodeName["yych"];
    1426                 :            :                                         }
    1427                 :          0 :                                         readCh = false;
    1428         [ #  # ]:          0 :                                         if (wFlag)
    1429                 :            :                                         {
    1430 [ #  # ][ #  # ]:          0 :                                                 o << indent(ind) << "if (" << sYych << " & ~0xFF) {\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1431 [ #  # ][ #  # ]:          0 :                                                 sYych = mapCodeName["yych"];
    1432         [ #  # ]:          0 :                                                 genBase(o, ind+1, from, next, readCh, 1);
    1433 [ #  # ][ #  # ]:          0 :                                                 o << indent(ind) << "} else ";
         [ #  # ][ #  # ]
    1434                 :            :                                         }
    1435                 :            :                                         else
    1436                 :            :                                         {
    1437 [ #  # ][ #  # ]:          0 :                                                 o << indent(ind);
                 [ #  # ]
    1438                 :            :                                         }
    1439                 :          0 :                                         bUsedYYBitmap = true;
    1440 [ #  # ][ #  # ]:          0 :                                         o << "if (" << mapCodeName["yybm"] << "[" << b->i << "+" << sYych << "] & ";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1441         [ #  # ]:          0 :                                         if (yybmHexTable)
    1442                 :            :                                         {
    1443         [ #  # ]:          0 :                                                 prtHex(o, b->m);
    1444                 :            :                                         }
    1445                 :            :                                         else
    1446                 :            :                                         {
    1447         [ #  # ]:          0 :                                                 o << (unsigned) b->m;
    1448                 :            :                                         }
    1449         [ #  # ]:          0 :                                         o << ") {\n";
    1450         [ #  # ]:          0 :                                         genGoTo(o, ind+1, from, to, readCh);
    1451 [ #  # ][ #  # ]:          0 :                                         o << indent(ind) << "}\n";
         [ #  # ][ #  # ]
    1452         [ #  # ]:          0 :                                         go.genBase(o, ind, from, next, readCh, 0);
    1453         [ #  # ]:          0 :                                         delete [] go.span;
    1454                 :            :                                         return ;
    1455 [ #  # ][ #  # ]:          0 :                                 }
    1456                 :            :                         }
    1457                 :            :                 }
    1458                 :            :         }
    1459                 :            : 
    1460                 :        514 :         genBase(o, ind, from, next, readCh, 0);
    1461                 :            : }
    1462                 :            : 
    1463                 :        514 : void State::emit(std::ostream &o, unsigned ind, bool &readCh, const std::string& condName) const
    1464                 :            : {
    1465         [ +  + ]:        514 :         if (vUsedLabels.count(label))
    1466                 :            :         {
    1467                 :        355 :                 o << labelPrefix << label << ":\n";
    1468                 :            :         }
    1469 [ -  + ][ #  # ]:        514 :         if (dFlag && !action->isInitial())
                 [ -  + ]
    1470                 :            :         {
    1471 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << mapCodeName["YYDEBUG"] << "(" << label << ", *" << mapCodeName["YYCURSOR"] << ");\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1472                 :            :         }
    1473         [ -  + ]:        514 :         if (isPreCtxt)
    1474                 :            :         {
    1475 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << mapCodeName["YYCTXMARKER"] << " = " << mapCodeName["YYCURSOR"] << " + 1;\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1476                 :            :         }
    1477                 :        514 :         action->emit(o, ind, readCh, condName);
    1478                 :        514 : }
    1479                 :            : 
    1480                 :          7 : static unsigned merge(Span *x0, State *fg, State *bg)
    1481                 :            : {
    1482                 :          7 :         Span *x = x0, *f = fg->go.span, *b = bg->go.span;
    1483                 :          7 :         unsigned nf = fg->go.nSpans, nb = bg->go.nSpans;
    1484                 :          7 :         State *prev = NULL, *to;
    1485                 :            :         // NB: we assume both spans are for same range
    1486                 :            : 
    1487                 :          7 :         for (;;)
    1488                 :            :         {
    1489         [ +  - ]:         14 :                 if (f->ub == b->ub)
    1490                 :            :                 {
    1491         [ +  + ]:         14 :                         to = f->to == b->to ? bg : f->to;
    1492                 :            : 
    1493         [ -  + ]:         14 :                         if (to == prev)
    1494                 :            :                         {
    1495                 :          0 :                                 --x;
    1496                 :            :                         }
    1497                 :            :                         else
    1498                 :            :                         {
    1499                 :         14 :                                 x->to = prev = to;
    1500                 :            :                         }
    1501                 :            : 
    1502                 :         14 :                         x->ub = f->ub;
    1503                 :         14 :                         ++x;
    1504                 :         14 :                         ++f;
    1505                 :         14 :                         --nf;
    1506                 :         14 :                         ++b;
    1507                 :         14 :                         --nb;
    1508                 :            : 
    1509 [ +  + ][ +  - ]:         14 :                         if (nf == 0 && nb == 0)
    1510                 :            :                         {
    1511                 :          7 :                                 return x - x0;
    1512                 :            :                         }
    1513                 :            :                 }
    1514                 :            : 
    1515         [ +  + ]:         17 :                 while (f->ub < b->ub)
    1516                 :            :                 {
    1517         [ +  + ]:         10 :                         to = f->to == b->to ? bg : f->to;
    1518                 :            : 
    1519         [ +  + ]:         10 :                         if (to == prev)
    1520                 :            :                         {
    1521                 :          5 :                                 --x;
    1522                 :            :                         }
    1523                 :            :                         else
    1524                 :            :                         {
    1525                 :          5 :                                 x->to = prev = to;
    1526                 :            :                         }
    1527                 :            : 
    1528                 :         10 :                         x->ub = f->ub;
    1529                 :         10 :                         ++x;
    1530                 :         10 :                         ++f;
    1531                 :         10 :                         --nf;
    1532                 :            :                 }
    1533                 :            : 
    1534         [ -  + ]:          7 :                 while (b->ub < f->ub)
    1535                 :            :                 {
    1536         [ #  # ]:          0 :                         to = b->to == f->to ? bg : f->to;
    1537                 :            : 
    1538         [ #  # ]:          0 :                         if (to == prev)
    1539                 :            :                         {
    1540                 :          0 :                                 --x;
    1541                 :            :                         }
    1542                 :            :                         else
    1543                 :            :                         {
    1544                 :          0 :                                 x->to = prev = to;
    1545                 :            :                         }
    1546                 :            : 
    1547                 :          0 :                         x->ub = b->ub;
    1548                 :          0 :                         ++x;
    1549                 :          0 :                         ++b;
    1550                 :          0 :                         --nb;
    1551                 :            :                 }
    1552                 :            :         }
    1553                 :            : }
    1554                 :            : 
    1555                 :            : static const unsigned cInfinity = ~0u;
    1556                 :            : 
    1557                 :            : class SCC
    1558                 :            : {
    1559                 :            : 
    1560                 :            : public:
    1561                 :            :         State   **top, **stk;
    1562                 :            : 
    1563                 :            : public:
    1564                 :            :         SCC(unsigned);
    1565                 :            :         ~SCC();
    1566                 :            :         void traverse(State*);
    1567                 :            : 
    1568                 :            : #ifdef PEDANTIC
    1569                 :            : private:
    1570                 :            :         SCC(const SCC& oth)
    1571                 :            :                 : top(oth.top)
    1572                 :            :                 , stk(oth.stk)
    1573                 :            :         {
    1574                 :            :         }
    1575                 :            :         SCC& operator = (const SCC& oth)
    1576                 :            :         {
    1577                 :            :                 new(this) SCC(oth);
    1578                 :            :                 return *this;
    1579                 :            :         }
    1580                 :            : #endif
    1581                 :            : };
    1582                 :            : 
    1583                 :         24 : SCC::SCC(unsigned size)
    1584         [ +  - ]:         24 :         : top(new State * [size])
    1585                 :         24 :         , stk(top)
    1586                 :            : {
    1587                 :         24 : }
    1588                 :            : 
    1589                 :         24 : SCC::~SCC()
    1590                 :            : {
    1591         [ +  - ]:         24 :         delete [] stk;
    1592                 :         24 : }
    1593                 :            : 
    1594                 :        155 : void SCC::traverse(State *x)
    1595                 :            : {
    1596                 :        155 :         *top = x;
    1597                 :        155 :         unsigned k = ++top - stk;
    1598                 :        155 :         x->depth = k;
    1599                 :            : 
    1600         [ +  + ]:       1028 :         for (unsigned i = 0; i < x->go.nSpans; ++i)
    1601                 :            :         {
    1602                 :        873 :                 State *y = x->go.span[i].to;
    1603                 :            : 
    1604         [ +  + ]:        873 :                 if (y)
    1605                 :            :                 {
    1606         [ +  + ]:        723 :                         if (y->depth == 0)
    1607                 :            :                         {
    1608                 :        131 :                                 traverse(y);
    1609                 :            :                         }
    1610                 :            : 
    1611         [ +  + ]:        723 :                         if (y->depth < x->depth)
    1612                 :            :                         {
    1613                 :         94 :                                 x->depth = y->depth;
    1614                 :            :                         }
    1615                 :            :                 }
    1616                 :            :         }
    1617                 :            : 
    1618         [ +  + ]:        155 :         if (x->depth == k)
    1619                 :            :         {
    1620         [ +  + ]:        155 :                 do
    1621                 :            :                 {
    1622                 :        155 :                         (*--top)->depth = cInfinity;
    1623                 :        155 :                         (*top)->link = x;
    1624                 :            :                 }
    1625                 :            :                 while (*top != x);
    1626                 :            :         }
    1627                 :        155 : }
    1628                 :            : 
    1629                 :        131 : static bool state_is_in_non_trivial_SCC(const State* s)
    1630                 :            : {
    1631                 :            :         
    1632                 :            :         // does not link to self
    1633         [ +  + ]:        131 :         if (s->link != s)
    1634                 :            :         {
    1635                 :         94 :                 return true;
    1636                 :            :         }
    1637                 :            :         
    1638                 :            :         // or exists i: (s->go.spans[i].to->link == s)
    1639                 :            :         //
    1640                 :            :         // Note: (s->go.spans[i].to == s) is allowed, corresponds to s
    1641                 :            :         // looping back to itself.
    1642                 :            :         //
    1643         [ +  + ]:         91 :         for (unsigned i = 0; i < s->go.nSpans; ++i)
    1644                 :            :         {
    1645                 :         79 :                 const State* t = s->go.span[i].to;
    1646                 :            :         
    1647 [ +  + ][ +  + ]:         79 :                 if (t && t->link == s)
    1648                 :            :                 {
    1649                 :         25 :                         return true;
    1650                 :            :                 }
    1651                 :            :         }
    1652                 :            :         // otherwise no
    1653                 :        131 :         return false;
    1654                 :            : }
    1655                 :            : 
    1656                 :        322 : static unsigned maxDist(State *s)
    1657                 :            : {
    1658         [ +  + ]:        322 :         if (s->depth != cInfinity)
    1659                 :            :         {
    1660                 :            :                 // Already calculated, just return result.
    1661                 :        167 :         return s->depth;
    1662                 :            :         }
    1663                 :        155 :         unsigned mm = 0;
    1664                 :            : 
    1665         [ +  + ]:       1028 :         for (unsigned i = 0; i < s->go.nSpans; ++i)
    1666                 :            :         {
    1667                 :        873 :                 State *t = s->go.span[i].to;
    1668                 :            : 
    1669         [ +  + ]:        873 :                 if (t)
    1670                 :            :                 {
    1671                 :        723 :                         unsigned m = 1;
    1672                 :            : 
    1673         [ +  + ]:        723 :                         if (!t->link) // marked as non-key state
    1674                 :            :                         {
    1675         [ +  + ]:         13 :                                 if (t->depth == cInfinity)
    1676                 :            :                                 {
    1677                 :         12 :                                         t->depth = maxDist(t);
    1678                 :            :                                 }
    1679                 :         13 :                                 m += t->depth;
    1680                 :            :                         }
    1681                 :            : 
    1682         [ +  + ]:        723 :                         if (m > mm)
    1683                 :            :                         {
    1684                 :        157 :                                 mm = m;
    1685                 :            :                         }
    1686                 :            :                 }
    1687                 :            :         }
    1688                 :            : 
    1689                 :        155 :         s->depth = mm;
    1690                 :        322 :         return mm;
    1691                 :            : }
    1692                 :            : 
    1693                 :         24 : static void calcDepth(State *head)
    1694                 :            : {
    1695                 :            :         State* s;
    1696                 :            : 
    1697                 :            :         // mark non-key states by s->link = NULL ;
    1698         [ +  + ]:        179 :         for (s = head; s; s = s->next)
    1699                 :            :         {
    1700 [ +  + ][ +  + ]:        155 :                 if (s != head && !state_is_in_non_trivial_SCC(s))
                 [ +  + ]
    1701                 :            :                 {
    1702                 :         12 :                         s->link = NULL;
    1703                 :            :                 }
    1704                 :            :                 //else: key state, leave alone
    1705                 :            :         }
    1706                 :            :         
    1707         [ +  + ]:        179 :         for (s = head; s; s = s->next)
    1708                 :            :         {
    1709                 :        155 :                 s->depth = cInfinity;
    1710                 :            :         }
    1711                 :            : 
    1712                 :            :         // calculate max number of transitions before guarantied to reach
    1713                 :            :         // a key state.
    1714         [ +  + ]:        179 :         for (s = head; s; s = s->next)
    1715                 :            :         {
    1716                 :        155 :                 maxDist(s);
    1717                 :            :         }
    1718                 :         24 : }
    1719                 :            : 
    1720                 :         24 : void DFA::findSCCs()
    1721                 :            : {
    1722         [ +  - ]:         24 :         SCC scc(nStates);
    1723                 :            :         State *s;
    1724                 :            : 
    1725         [ +  + ]:        179 :         for (s = head; s; s = s->next)
    1726                 :            :         {
    1727                 :        155 :                 s->depth = 0;
    1728                 :        155 :                 s->link = NULL;
    1729                 :            :         }
    1730                 :            : 
    1731         [ +  + ]:        179 :         for (s = head; s; s = s->next)
    1732                 :            :         {
    1733         [ +  + ]:        155 :                 if (!s->depth)
    1734                 :            :                 {
    1735         [ +  - ]:         24 :                         scc.traverse(s);
    1736                 :            :                 }
    1737                 :            :         }
    1738                 :            : 
    1739         [ +  - ]:         24 :         calcDepth(head);
    1740                 :         24 : }
    1741                 :            : 
    1742                 :         54 : void DFA::split(State *s)
    1743                 :            : {
    1744         [ +  - ]:         54 :         State *move = new State;
    1745         [ +  - ]:         54 :         (void) new Move(move);
    1746                 :         54 :         addState(&s->next, move);
    1747                 :         54 :         move->link = s->link;
    1748                 :         54 :         move->rule = s->rule;
    1749                 :         54 :         move->go = s->go;
    1750                 :         54 :         s->rule = NULL;
    1751                 :         54 :         s->go.nSpans = 1;
    1752                 :         54 :         s->go.span = new Span[1];
    1753                 :         54 :         s->go.span[0].ub = ubChar;
    1754                 :         54 :         s->go.span[0].to = move;
    1755                 :         54 : }
    1756                 :            : 
    1757                 :         24 : void DFA::findBaseState()
    1758                 :            : {
    1759         [ +  - ]:         24 :         Span *span = new Span[ubChar - lbChar];
    1760                 :            : 
    1761         [ +  + ]:        303 :         for (State *s = head; s; s = s->next)
    1762                 :            :         {
    1763         [ +  + ]:        279 :                 if (!s->link)
    1764                 :            :                 {
    1765         [ +  + ]:        101 :                         for (unsigned i = 0; i < s->go.nSpans; ++i)
    1766                 :            :                         {
    1767                 :         19 :                                 State *to = s->go.span[i].to;
    1768                 :            : 
    1769 [ +  - ][ +  + ]:         19 :                                 if (to && to->isBase)
    1770                 :            :                                 {
    1771                 :          7 :                                         to = to->go.span[0].to;
    1772                 :          7 :                                         unsigned nSpans = merge(span, s, to);
    1773                 :            : 
    1774         [ +  + ]:          7 :                                         if (nSpans < s->go.nSpans)
    1775                 :            :                                         {
    1776         [ +  - ]:          5 :                                                 delete [] s->go.span;
    1777                 :          5 :                                                 s->go.nSpans = nSpans;
    1778         [ +  - ]:          5 :                                                 s->go.span = new Span[nSpans];
    1779                 :          5 :                                                 memcpy(s->go.span, span, nSpans*sizeof(Span));
    1780                 :            :                                         }
    1781                 :            : 
    1782                 :          7 :                                         break;
    1783                 :            :                                 }
    1784                 :            :                         }
    1785                 :            :                 }
    1786                 :            :         }
    1787                 :            : 
    1788         [ +  - ]:         24 :         delete [] span;
    1789                 :         24 : }
    1790                 :            : 
    1791                 :         24 : void DFA::prepare()
    1792                 :            : {
    1793                 :            :         State *s;
    1794                 :            :         unsigned i;
    1795                 :            : 
    1796                 :         24 :         bUsedYYBitmap = false;
    1797                 :            : 
    1798                 :         24 :         findSCCs();
    1799                 :         24 :         head->link = head;
    1800                 :            : 
    1801                 :         24 :         unsigned nRules = 0;
    1802                 :            : 
    1803         [ +  + ]:        179 :         for (s = head; s; s = s->next)
    1804                 :            :         {
    1805                 :        155 :                 s->depth = maxDist(s);
    1806         [ +  + ]:        155 :                 if (maxFill < s->depth)
    1807                 :            :                 {
    1808                 :          2 :                         maxFill = s->depth;
    1809                 :            :                 }
    1810 [ +  + ][ +  + ]:        155 :                 if (s->rule && s->rule->accept >= nRules)
    1811                 :            :                 {
    1812                 :         24 :                         nRules = s->rule->accept + 1;
    1813                 :            :                 }
    1814                 :            :         }
    1815                 :            : 
    1816                 :         24 :         unsigned nSaves = 0;
    1817         [ +  - ]:         24 :         saves = new unsigned[nRules];
    1818                 :         24 :         memset(saves, ~0, (nRules)*sizeof(*saves));
    1819                 :            : 
    1820                 :            :         // mark backtracking points
    1821                 :         24 :         bSaveOnHead = false;
    1822                 :            : 
    1823         [ +  + ]:        179 :         for (s = head; s; s = s->next)
    1824                 :            :         {
    1825         [ +  + ]:        155 :                 if (s->rule)
    1826                 :            :                 {
    1827         [ +  + ]:        321 :                         for (i = 0; i < s->go.nSpans; ++i)
    1828                 :            :                         {
    1829 [ +  + ][ +  + ]:        265 :                                 if (s->go.span[i].to && !s->go.span[i].to->rule)
    1830                 :            :                                 {
    1831         [ +  - ]:        187 :                                         delete s->action;
    1832                 :        187 :                                         s->action = NULL;
    1833                 :            : 
    1834         [ +  + ]:        187 :                                         if (saves[s->rule->accept] == ~0u)
    1835                 :            :                                         {
    1836                 :         43 :                                                 saves[s->rule->accept] = nSaves++;
    1837                 :            :                                         }
    1838                 :            : 
    1839                 :        187 :                                         bSaveOnHead |= s == head;
    1840         [ +  - ]:        187 :                                         (void) new Save(s, saves[s->rule->accept]); // sets s->action
    1841                 :            :                                 }
    1842                 :            :                         }
    1843                 :            :                 }
    1844                 :            :         }
    1845                 :            : 
    1846                 :            :         // insert actions
    1847         [ +  - ]:         24 :         rules = new State * [nRules];
    1848                 :            : 
    1849                 :         24 :         memset(rules, 0, (nRules)*sizeof(*rules));
    1850                 :            : 
    1851                 :         24 :         State *accept = NULL;
    1852                 :         24 :         Accept *accfixup = NULL;
    1853                 :            : 
    1854         [ +  + ]:        249 :         for (s = head; s; s = s->next)
    1855                 :            :         {
    1856                 :            :                 State * ow;
    1857                 :            : 
    1858         [ +  + ]:        225 :                 if (!s->rule)
    1859                 :            :                 {
    1860                 :        169 :                         ow = accept;
    1861                 :            :                 }
    1862                 :            :                 else
    1863                 :            :                 {
    1864         [ +  + ]:         56 :                         if (!rules[s->rule->accept])
    1865                 :            :                         {
    1866         [ +  - ]:         47 :                                 State *n = new State;
    1867         [ +  - ]:         47 :                                 (void) new Rule(n, s->rule);
    1868                 :         47 :                                 rules[s->rule->accept] = n;
    1869                 :         47 :                                 addState(&s->next, n);
    1870                 :            :                         }
    1871                 :            : 
    1872                 :         56 :                         ow = rules[s->rule->accept];
    1873                 :            :                 }
    1874                 :            : 
    1875         [ +  + ]:       1098 :                 for (i = 0; i < s->go.nSpans; ++i)
    1876                 :            :                 {
    1877         [ +  + ]:        873 :                         if (!s->go.span[i].to)
    1878                 :            :                         {
    1879         [ +  + ]:        150 :                                 if (!ow)
    1880                 :            :                                 {
    1881         [ +  - ]:         23 :                                         ow = accept = new State;
    1882         [ +  - ]:         23 :                                         accfixup = new Accept(accept, nRules, saves, rules);
    1883                 :         23 :                                         addState(&s->next, accept);
    1884                 :            :                                 }
    1885                 :            : 
    1886                 :        150 :                                 s->go.span[i].to = ow;
    1887                 :            :                         }
    1888                 :            :                 }
    1889                 :            :         }
    1890                 :            :         
    1891         [ +  + ]:         24 :         if (accfixup)
    1892                 :            :         {
    1893                 :         23 :                 accfixup->genRuleMap();
    1894                 :            :         }
    1895                 :            : 
    1896                 :            :         // split ``base'' states into two parts
    1897         [ +  + ]:        249 :         for (s = head; s; s = s->next)
    1898                 :            :         {
    1899                 :        225 :                 s->isBase = false;
    1900                 :            : 
    1901         [ +  + ]:        225 :                 if (s->link)
    1902                 :            :                 {
    1903         [ +  + ]:        842 :                         for (i = 0; i < s->go.nSpans; ++i)
    1904                 :            :                         {
    1905         [ +  + ]:        699 :                                 if (s->go.span[i].to == s)
    1906                 :            :                                 {
    1907                 :         54 :                                         s->isBase = true;
    1908                 :         54 :                                         split(s);
    1909                 :            : 
    1910         [ -  + ]:         54 :                                         if (bFlag)
    1911                 :            :                                         {
    1912                 :          0 :                                                 BitMap::find(&s->next->go, s);
    1913                 :            :                                         }
    1914                 :            : 
    1915                 :         54 :                                         s = s->next;
    1916                 :         54 :                                         break;
    1917                 :            :                                 }
    1918                 :            :                         }
    1919                 :            :                 }
    1920                 :            :         }
    1921                 :            : 
    1922                 :            :         // find ``base'' state, if possible
    1923                 :         24 :         findBaseState();
    1924                 :            : 
    1925         [ +  - ]:         24 :         delete head->action;
    1926                 :         24 :         head->action = NULL;
    1927                 :         24 : }
    1928                 :            : 
    1929                 :            : /* TODOXXX: this stuff is needed for DFA::emit */
    1930                 :            : 
    1931                 :            : template<class _E, class _Tr = std::char_traits<_E> >
    1932         [ -  + ]:         46 : class basic_null_streambuf
    1933                 :            :         : public std::basic_streambuf<_E, _Tr>
    1934                 :            : {
    1935                 :            : public:
    1936                 :         23 :         basic_null_streambuf()
    1937                 :         23 :                 : std::basic_streambuf<_E, _Tr>()
    1938                 :            :         {
    1939                 :            :         }       
    1940                 :            : };
    1941                 :            : 
    1942                 :            : typedef basic_null_streambuf<char> null_streambuf;
    1943                 :            : 
    1944                 :            : template<class _E, class _Tr = std::char_traits<_E> >
    1945                 :            : class basic_null_stream
    1946                 :            :         : public std::basic_ostream<_E, _Tr>
    1947                 :            : {
    1948                 :            : public:
    1949                 :         23 :         basic_null_stream()
    1950 [ +  - ][ +  - ]:         23 :                 : std::basic_ostream<_E, _Tr>(null_buf = new basic_null_streambuf<_E, _Tr>())
                 [ +  - ]
    1951                 :            :         {
    1952                 :            :         }
    1953                 :            :         
    1954                 :         23 :         virtual ~basic_null_stream()
    1955                 :            :         {
    1956 [ +  - ][ +  - ]:         23 :                 delete null_buf;
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
    1957                 :          0 :         }
    1958                 :            : 
    1959                 :            :         basic_null_stream& put(_E)
    1960                 :            :         {
    1961                 :            :                 // nothing to do
    1962                 :            :                 return *this;
    1963                 :            :         }
    1964                 :            :         
    1965                 :            :         basic_null_stream& write(const _E *, std::streamsize)
    1966                 :            :         {
    1967                 :            :                 // nothing to do
    1968                 :            :                 return *this;
    1969                 :            :         }
    1970                 :            : 
    1971                 :            : protected:
    1972                 :            :         basic_null_streambuf<_E, _Tr> * null_buf;
    1973                 :            : };
    1974                 :            : 
    1975                 :            : typedef basic_null_stream<char> null_stream;
    1976                 :            : 
    1977                 :            : 
    1978                 :         23 : void DFA::emit(std::ostream &o, unsigned& ind, const RegExpMap* specMap, const std::string& condName, bool isLastCond, bool& bPrologBrace)
    1979                 :            : {
    1980 [ -  + ][ #  # ]:         23 :         bool bProlog = (!cFlag || !bWroteCondCheck);
    1981                 :            : 
    1982         [ +  - ]:         23 :         if (!cFlag)
    1983                 :            :         {
    1984                 :         23 :                 bUsedYYAccept = false;
    1985                 :            :         }
    1986                 :            :         
    1987                 :            :         // In -c mode, the prolog needs its own label separate from start_label.
    1988                 :            :         // prolog_label is before the condition branch (GenCondGoto). It is
    1989                 :            :         // equivalent to startLabelName.
    1990                 :            :         // start_label corresponds to current condition.
    1991                 :            :         // NOTE: prolog_label must be yy0 because of the !getstate:re2c handling
    1992                 :            :         // in scanner.re
    1993                 :         23 :         unsigned prolog_label = next_label;
    1994 [ +  - ][ -  + ]:         23 :         if (bProlog && cFlag)
    1995                 :            :         {
    1996                 :          0 :                 next_label++;
    1997                 :            :         }
    1998                 :            : 
    1999                 :         23 :         unsigned start_label = next_label;
    2000                 :            : 
    2001 [ +  - ][ +  - ]:         23 :         (void) new Initial(head, next_label++, bSaveOnHead);
    2002                 :            : 
    2003         [ -  + ]:         23 :         if (bUseStartLabel)
    2004                 :            :         {
    2005 [ #  # ][ #  # ]:          0 :                 if (startLabelName.empty())
    2006                 :            :                 {
    2007         [ #  # ]:          0 :                         vUsedLabels.insert(prolog_label);
    2008                 :            :                 }
    2009                 :            :         }
    2010                 :            : 
    2011                 :            :         State *s;
    2012                 :            : 
    2013         [ +  + ]:        280 :         for (s = head; s; s = s->next)
    2014                 :            :         {
    2015                 :        257 :                 s->label = next_label++;
    2016                 :            :         }
    2017                 :            : 
    2018                 :            :         // Save 'next_fill_index' and compute information about code generation
    2019                 :            :         // while writing to null device.
    2020                 :         23 :         unsigned save_fill_index = next_fill_index;
    2021         [ +  - ]:         23 :         null_stream  null_dev;
    2022                 :            : 
    2023         [ +  + ]:        280 :         for (s = head; s; s = s->next)
    2024                 :            :         {
    2025                 :        257 :                 bool readCh = false;
    2026         [ +  - ]:        257 :                 s->emit(null_dev, ind, readCh, condName);
    2027         [ +  - ]:        257 :                 s->go.genGoto(null_dev, ind, s, s->next, readCh);
    2028                 :            :         }
    2029         [ -  + ]:         23 :         if (last_fill_index < next_fill_index)
    2030                 :            :         {
    2031                 :          0 :                 last_fill_index = next_fill_index;
    2032                 :            :         }
    2033                 :         23 :         next_fill_index = save_fill_index;
    2034                 :            : 
    2035                 :            :         // Generate prolog
    2036         [ +  - ]:         23 :         if (bProlog)
    2037                 :            :         {
    2038                 :            : 
    2039         [ -  + ]:         23 :                 if (DFlag)
    2040                 :            :                 {
    2041                 :          0 :                         bPrologBrace = true;
    2042         [ #  # ]:          0 :                         o << "digraph re2c {\n";
    2043                 :            :                 }
    2044 [ +  - ][ +  + ]:         23 :                 else if ((!fFlag && bUsedYYAccept)
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ +  - ]
    2045                 :          3 :                 ||  (!fFlag && bEmitYYCh)
    2046                 :          0 :                 ||  (bFlag && !cFlag && BitMap::first)
    2047         [ #  # ]:          0 :                 ||  (cFlag && !bWroteCondCheck && gFlag && !specMap->empty())
    2048                 :          0 :                 ||  (fFlag && !bWroteGetState && gFlag)
    2049                 :            :                 )
    2050                 :            :                 {
    2051                 :         23 :                         bPrologBrace = true;
    2052 [ +  - ][ +  - ]:         23 :                         o << indent(ind++) << "{\n";
         [ +  - ][ +  - ]
    2053                 :            :                 }
    2054         [ #  # ]:          0 :                 else if (ind == 0)
    2055                 :            :                 {
    2056                 :          0 :                         ind = 1;
    2057                 :            :                 }
    2058                 :            : 
    2059 [ +  - ][ +  - ]:         23 :                 if (!fFlag && !DFlag)
    2060                 :            :                 {
    2061         [ +  - ]:         23 :                         if (bEmitYYCh)
    2062                 :            :                         {
    2063 [ +  - ][ +  - ]:         23 :                                 o << indent(ind) << mapCodeName["YYCTYPE"] << " " << mapCodeName["yych"] << ";\n";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
    2064                 :            :                         }
    2065         [ +  + ]:         43 :                         if (bUsedYYAccept)
    2066                 :            :                         {
    2067 [ +  - ][ +  - ]:         20 :                                 o << indent(ind) << "unsigned int " << mapCodeName["yyaccept"] << " = 0;\n";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
    2068                 :            :                         }
    2069                 :            :                 }
    2070                 :            :                 else
    2071                 :            :                 {
    2072         [ #  # ]:         23 :                         o << "\n";
    2073                 :            :                 }
    2074                 :            :         }
    2075 [ -  + ][ #  # ]:         23 :         if (bFlag && !cFlag && BitMap::first)
                 [ #  # ]
    2076                 :            :         {
    2077         [ #  # ]:          0 :                 BitMap::gen(o, ind, lbChar, ubChar <= 256 ? ubChar : 256);
    2078                 :            :         }
    2079         [ +  - ]:         23 :         if (bProlog)
    2080                 :            :         {
    2081         [ +  - ]:         23 :                 genCondTable(o, ind, *specMap);
    2082         [ +  - ]:         23 :                 genGetStateGoto(o, ind, prolog_label);
    2083 [ -  + ][ #  # ]:         23 :                 if (cFlag && !DFlag)
    2084                 :            :                 {
    2085 [ #  # ][ #  # ]:          0 :                         if (vUsedLabels.count(prolog_label))
    2086                 :            :                         {
    2087 [ #  # ][ #  # ]:          0 :                                 o << labelPrefix << prolog_label << ":\n";
                 [ #  # ]
    2088                 :            :                         }
    2089 [ #  # ][ #  # ]:          0 :                         if (!startLabelName.empty())
    2090                 :            :                         {
    2091 [ #  # ][ #  # ]:          0 :                                 o << startLabelName << ":\n";
    2092                 :            :                         }
    2093                 :            :                 }
    2094         [ +  - ]:         23 :                 genCondGoto(o, ind, *specMap);
    2095                 :            :         }
    2096                 :            : 
    2097 [ -  + ][ #  # ]:         23 :         if (cFlag && !condName.empty())
         [ #  # ][ -  + ]
    2098                 :            :         {
    2099 [ #  # ][ #  # ]:          0 :                 if (condDivider.length())
    2100                 :            :                 {
    2101 [ #  # ][ #  # ]:          0 :                         o << replaceParam(condDivider, condDividerParam, condName) << "\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2102                 :            :                 }
    2103                 :            : 
    2104         [ #  # ]:          0 :                 if (DFlag)
    2105                 :            :                 {
    2106 [ #  # ][ #  # ]:          0 :                         o << condName << " -> " << (start_label+1) << "\n";
         [ #  # ][ #  # ]
    2107                 :            :                 }
    2108                 :            :                 else
    2109                 :            :                 {
    2110 [ #  # ][ #  # ]:          0 :                         o << condPrefix << condName << ":\n";
                 [ #  # ]
    2111                 :            :                 }
    2112                 :            :         }
    2113 [ -  + ][ #  # ]:         23 :         if (cFlag && bFlag && BitMap::first)
                 [ #  # ]
    2114                 :            :         {
    2115 [ #  # ][ #  # ]:          0 :                 o << indent(ind++) << "{\n";
         [ #  # ][ #  # ]
    2116         [ #  # ]:          0 :                 BitMap::gen(o, ind, lbChar, ubChar <= 256 ? ubChar : 256);
    2117                 :            :         }
    2118                 :            : 
    2119                 :            :         // The start_label is not always the first to be emitted, so we may have to jump. c.f. Initial::emit()
    2120 [ +  - ][ -  + ]:         23 :         if (vUsedLabels.count(start_label+1))
    2121                 :            :         {
    2122         [ #  # ]:          0 :                 vUsedLabels.insert(start_label);
    2123 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << "goto " << labelPrefix << start_label << ";\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    2124                 :            :         }
    2125                 :            : 
    2126                 :            :         // Generate code
    2127         [ +  + ]:        280 :         for (s = head; s; s = s->next)
    2128                 :            :         {
    2129                 :        257 :                 bool readCh = false;
    2130         [ +  - ]:        257 :                 s->emit(o, ind, readCh, condName);
    2131         [ +  - ]:        257 :                 s->go.genGoto(o, ind, s, s->next, readCh);
    2132                 :            :         }
    2133                 :            : 
    2134 [ -  + ][ #  # ]:         23 :         if (cFlag && bFlag && BitMap::first)
                 [ #  # ]
    2135                 :            :         {
    2136 [ #  # ][ #  # ]:          0 :                 o << indent(--ind) << "}\n";
         [ #  # ][ #  # ]
    2137                 :            :         }
    2138                 :            :         // Generate epilog
    2139 [ -  + ][ #  # ]:         23 :         if ((!cFlag || isLastCond) && bPrologBrace)
                 [ +  - ]
    2140                 :            :         {
    2141 [ +  - ][ +  - ]:         23 :                 o << indent(--ind) << "}\n";
         [ +  - ][ +  - ]
    2142                 :            :         }
    2143                 :            : 
    2144                 :            :         // Cleanup
    2145         [ -  + ]:         23 :         if (BitMap::first)
    2146                 :            :         {
    2147 [ #  # ][ #  # ]:          0 :                 delete BitMap::first;
    2148                 :          0 :                 BitMap::first = NULL;
    2149                 :            :         }
    2150                 :            : 
    2151         [ +  - ]:         23 :         bUseStartLabel = false;
    2152                 :         23 : }
    2153                 :            : 
    2154                 :          0 : static void genGetStateGotoSub(std::ostream &o, unsigned ind, unsigned start_label, int cMin, int cMax)
    2155                 :            : {
    2156         [ #  # ]:          0 :         if (cMin == cMax)
    2157                 :            :         {
    2158         [ #  # ]:          0 :                 if (cMin == -1)
    2159                 :            :                 {
    2160 [ #  # ][ #  # ]:          0 :                         o << indent(ind) << "goto " << labelPrefix << start_label << ";\n";
         [ #  # ][ #  # ]
                 [ #  # ]
    2161                 :            :                 }
    2162                 :            :                 else
    2163                 :            :                 {
    2164 [ #  # ][ #  # ]:          0 :                         o << indent(ind) << "goto " << mapCodeName["yyFillLabel"] << cMin << ";\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2165                 :            :                 }
    2166                 :            :         }
    2167                 :            :         else
    2168                 :            :         {
    2169                 :          0 :                 int cMid = cMin + ((cMax - cMin + 1) / 2);
    2170                 :            : 
    2171 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << "if (" << genGetState() << " < " << cMid << ") {\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2172                 :          0 :                 genGetStateGotoSub(o, ind + 1, start_label, cMin, cMid - 1);
    2173 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << "} else {\n";
    2174                 :          0 :                 genGetStateGotoSub(o, ind + 1, start_label, cMid, cMax);
    2175 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << "}\n";
    2176                 :            :         }
    2177                 :          0 : }
    2178                 :            : 
    2179                 :         23 : void genGetStateGoto(std::ostream &o, unsigned& ind, unsigned start_label)
    2180                 :            : {
    2181 [ -  + ][ #  # ]:         23 :         if (fFlag && !bWroteGetState)
    2182                 :            :         {
    2183                 :          0 :                 vUsedLabels.insert(start_label);
    2184         [ #  # ]:          0 :                 if (gFlag)
    2185                 :            :                 {
    2186 [ #  # ][ #  # ]:          0 :                         o << indent(ind++) << "static void *" << mapCodeName["yystable"] << "[" << "] = {\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2187                 :            : 
    2188         [ #  # ]:          0 :                         for (size_t i=0; i<last_fill_index; ++i)
    2189                 :            :                         {
    2190 [ #  # ][ #  # ]:          0 :                                 o << indent(ind) << "&&" << mapCodeName["yyFillLabel"] << i << ",\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2191                 :            :                         }
    2192                 :            : 
    2193 [ #  # ][ #  # ]:          0 :                         o << indent(--ind) << "};\n";
    2194                 :          0 :                         o << "\n";
    2195                 :            : 
    2196 [ #  # ][ #  # ]:          0 :                         o << indent(ind) << "if (" << genGetState();
         [ #  # ][ #  # ]
                 [ #  # ]
    2197         [ #  # ]:          0 :                         if (bUseStateAbort)
    2198                 :            :                         {
    2199                 :          0 :                                 o << " == -1) {\n";
    2200                 :            :                         }
    2201                 :            :                         else
    2202                 :            :                         {
    2203                 :          0 :                                 o << " < 0) {\n";
    2204                 :            :                         }
    2205 [ #  # ][ #  # ]:          0 :                         o << indent(++ind) << "goto " << labelPrefix << start_label << ";\n";
         [ #  # ][ #  # ]
                 [ #  # ]
    2206         [ #  # ]:          0 :                         if (bUseStateAbort)
    2207                 :            :                         {
    2208 [ #  # ][ #  # ]:          0 :                                 o << indent(--ind) << "} else if (" << genGetState() << " < -1) {\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2209 [ #  # ][ #  # ]:          0 :                                 o << indent(++ind) << "abort();\n";
    2210                 :            :                         }
    2211 [ #  # ][ #  # ]:          0 :                         o << indent(--ind) << "}\n";
    2212                 :            : 
    2213 [ #  # ][ #  # ]:          0 :                         o << indent(ind) << "goto *" << mapCodeName["yystable"] << "[" << genGetState() << "];\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    2214                 :            :                 }
    2215         [ #  # ]:          0 :                 else if (bFlag)
    2216                 :            :                 {
    2217                 :          0 :                         genGetStateGotoSub(o, ind, start_label, -1, last_fill_index-1);
    2218         [ #  # ]:          0 :                         if (bUseStateAbort)
    2219                 :            :                         {
    2220 [ #  # ][ #  # ]:          0 :                                 o << indent(ind) << "abort();\n";
    2221                 :            :                         }
    2222                 :            :                 }
    2223                 :            :                 else
    2224                 :            :                 {
    2225 [ #  # ][ #  # ]:          0 :                         o << indent(ind) << "switch (" << genGetState() << ") {\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2226         [ #  # ]:          0 :                         if (bUseStateAbort)
    2227                 :            :                         {
    2228 [ #  # ][ #  # ]:          0 :                                 o << indent(ind) << "default: abort();\n";
    2229 [ #  # ][ #  # ]:          0 :                                 o << indent(ind) << "case -1: goto " << labelPrefix << start_label << ";\n";
         [ #  # ][ #  # ]
                 [ #  # ]
    2230                 :            :                         }
    2231                 :            :                         else
    2232                 :            :                         {
    2233 [ #  # ][ #  # ]:          0 :                                 o << indent(ind) << "default: goto " << labelPrefix << start_label << ";\n";
         [ #  # ][ #  # ]
                 [ #  # ]
    2234                 :            :                         }
    2235                 :            :         
    2236         [ #  # ]:          0 :                         for (size_t i=0; i<last_fill_index; ++i)
    2237                 :            :                         {
    2238 [ #  # ][ #  # ]:          0 :                                 o << indent(ind) << "case " << i << ": goto " << mapCodeName["yyFillLabel"] << i << ";\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2239                 :            :                         }
    2240                 :            :         
    2241 [ #  # ][ #  # ]:          0 :                         o << indent(ind) << "}\n";
    2242                 :            :                 }
    2243         [ #  # ]:          0 :                 if (bUseStateNext)
    2244                 :            :                 {
    2245                 :          0 :                         o << mapCodeName["yyNext"] << ":\n";
    2246                 :            :                 }
    2247                 :          0 :                 bWroteGetState = true;
    2248                 :            :         }
    2249                 :         23 : }
    2250                 :            : 
    2251                 :         23 : void genCondTable(std::ostream &o, unsigned ind, const RegExpMap& specMap)
    2252                 :            : {
    2253 [ -  + ][ #  # ]:         23 :         if (cFlag && !bWroteCondCheck && gFlag && specMap.size())
         [ #  # ][ #  # ]
                 [ -  + ]
    2254                 :            :         {
    2255 [ #  # ][ #  # ]:          0 :                 RegExpIndices  vCondList(specMap.size());
         [ #  # ][ #  # ]
    2256                 :            : 
    2257 [ #  # ][ #  # ]:          0 :                 for(RegExpMap::const_iterator itSpec = specMap.begin(); itSpec != specMap.end(); ++itSpec)
                 [ #  # ]
    2258                 :            :                 {
    2259 [ #  # ][ #  # ]:          0 :                         vCondList[itSpec->second.first] = itSpec->first;
                 [ #  # ]
    2260                 :            :                 }
    2261                 :            : 
    2262 [ #  # ][ #  # ]:          0 :                 o << indent(ind++) << "static void *" << mapCodeName["yyctable"] << "[" << specMap.size() << "] = {\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2263                 :            : 
    2264 [ #  # ][ #  # ]:          0 :                 for(RegExpIndices::const_iterator it = vCondList.begin(); it != vCondList.end(); ++it)
         [ #  # ][ #  # ]
                 [ #  # ]
    2265                 :            :                 {
    2266 [ #  # ][ #  # ]:          0 :                         o << indent(ind) << "&&" << condPrefix << *it << ",\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    2267                 :            :                 }
    2268 [ #  # ][ #  # ]:          0 :                 o << indent(--ind) << "};\n";
         [ #  # ][ #  # ]
                 [ #  # ]
    2269                 :            :         }
    2270                 :         23 : }
    2271                 :            : 
    2272                 :          0 : static void genCondGotoSub(std::ostream &o, unsigned ind, RegExpIndices& vCondList, unsigned cMin, unsigned cMax)
    2273                 :            : {
    2274         [ #  # ]:          0 :         if (cMin == cMax)
    2275                 :            :         {
    2276 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << "goto " << condPrefix << vCondList[cMin] << ";\n";
         [ #  # ][ #  # ]
                 [ #  # ]
    2277                 :            :         }
    2278                 :            :         else
    2279                 :            :         {
    2280                 :          0 :                 unsigned cMid = cMin + ((cMax - cMin + 1) / 2);
    2281                 :            : 
    2282 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << "if (" << genGetCondition() << " < " << cMid << ") {\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2283                 :          0 :                 genCondGotoSub(o, ind + 1, vCondList, cMin, cMid - 1);
    2284 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << "} else {\n";
    2285                 :          0 :                 genCondGotoSub(o, ind + 1, vCondList, cMid, cMax);
    2286 [ #  # ][ #  # ]:          0 :                 o << indent(ind) << "}\n";
    2287                 :            :         }
    2288                 :          0 : }
    2289                 :            : 
    2290                 :         23 : void genCondGoto(std::ostream &o, unsigned ind, const RegExpMap& specMap)
    2291                 :            : {
    2292 [ -  + ][ #  # ]:         23 :         if (cFlag && !bWroteCondCheck && specMap.size())
         [ #  # ][ -  + ]
    2293                 :            :         {
    2294         [ #  # ]:          0 :                 if (gFlag)
    2295                 :            :                 {
    2296 [ #  # ][ #  # ]:          0 :                         o << indent(ind) << "goto *" << mapCodeName["yyctable"] << "[" << genGetCondition() << "];\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    2297                 :            :                 }
    2298                 :            :                 else
    2299                 :            :                 {
    2300         [ #  # ]:          0 :                         if (sFlag)
    2301                 :            :                         {
    2302 [ #  # ][ #  # ]:          0 :                                 RegExpIndices  vCondList(specMap.size());
         [ #  # ][ #  # ]
    2303                 :            :                         
    2304 [ #  # ][ #  # ]:          0 :                                 for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it)
                 [ #  # ]
    2305                 :            :                                 {
    2306 [ #  # ][ #  # ]:          0 :                                         vCondList[it->second.first] = it->first;
                 [ #  # ]
    2307                 :            :                                 }
    2308 [ #  # ][ #  # ]:          0 :                                 genCondGotoSub(o, ind, vCondList, 0, vCondList.size() - 1);
    2309                 :            :                         }
    2310         [ #  # ]:          0 :                         else if (DFlag)
    2311                 :            :                         {
    2312 [ #  # ][ #  # ]:          0 :                                 for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it)
                 [ #  # ]
    2313                 :            :                                 {
    2314 [ #  # ][ #  # ]:          0 :                                         o << "0 -> " << it->first << " [label=\"state=" << it->first << "\"]\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    2315                 :            :                                 }
    2316                 :            :                         }
    2317                 :            :                         else
    2318                 :            :                         {
    2319 [ #  # ][ #  # ]:          0 :                                 o << indent(ind) << "switch (" << genGetCondition() << ") {\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2320                 :            :         
    2321 [ #  # ][ #  # ]:          0 :                                 for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it)
                 [ #  # ]
    2322                 :            :                                 {
    2323 [ #  # ][ #  # ]:          0 :                                         o << indent(ind) << "case " << condEnumPrefix << it->first << ": goto " << condPrefix << it->first << ";\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2324                 :            :                                 }
    2325 [ #  # ][ #  # ]:          0 :                                 o << indent(ind) << "}\n";
    2326                 :            :                         }
    2327                 :            :                 }
    2328                 :          0 :                 bWroteCondCheck = true;
    2329                 :            :         }
    2330                 :         23 : }
    2331                 :            : 
    2332                 :          0 : void genTypes(std::string& o, unsigned ind, const RegExpMap& specMap)
    2333                 :            : {
    2334         [ #  # ]:          0 :         o.clear();
    2335                 :            : 
    2336 [ #  # ][ #  # ]:          0 :         o += indent(ind++) + "enum " + mapCodeName["YYCONDTYPE"] + " {\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2337                 :            : 
    2338 [ #  # ][ #  # ]:          0 :         RegExpIndices  vCondList(specMap.size());
         [ #  # ][ #  # ]
    2339                 :            : 
    2340 [ #  # ][ #  # ]:          0 :         for(RegExpMap::const_iterator itSpecMap = specMap.begin(); itSpecMap != specMap.end(); ++itSpecMap)
                 [ #  # ]
    2341                 :            :         {
    2342                 :            :                 // If an entry is < 0 then we did the 0/empty correction twice.
    2343         [ #  # ]:          0 :                 assert(itSpecMap->second.first >= 0);
    2344 [ #  # ][ #  # ]:          0 :                 vCondList[itSpecMap->second.first] = itSpecMap->first;
                 [ #  # ]
    2345                 :            :         }
    2346                 :            : 
    2347 [ #  # ][ #  # ]:          0 :         for(RegExpIndices::const_iterator itCondType = vCondList.begin(); itCondType != vCondList.end(); ++itCondType)
         [ #  # ][ #  # ]
                 [ #  # ]
    2348                 :            :         {
    2349 [ #  # ][ #  # ]:          0 :                 o += indent(ind) + condEnumPrefix + *itCondType + ",\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    2350                 :            :         }
    2351                 :            : 
    2352 [ #  # ][ #  # ]:          0 :         o += indent(--ind) + "};\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2353                 :          0 : }
    2354                 :            : 
    2355                 :          0 : void genHeader(std::ostream &o, unsigned ind, const RegExpMap& specMap)
    2356                 :            : {
    2357                 :          0 :         o << "/* Generated by re2c " PACKAGE_VERSION;
    2358         [ #  # ]:          0 :         if (!bNoGenerationDate)
    2359                 :            :         {
    2360         [ #  # ]:          0 :                 o << " on ";
    2361                 :          0 :                 time_t now = time(&now);
    2362         [ #  # ]:          0 :                 o.write(ctime(&now), 24);
    2363                 :            :         }
    2364                 :          0 :         o << " */\n";
    2365                 :          0 :         o << "\n";
    2366                 :            :         // now the type(s)
    2367                 :          0 :         genTypes(typesInline, ind, specMap);
    2368                 :          0 :         o << typesInline;
    2369                 :          0 : }
    2370                 :            : 
    2371                 :          0 : void Scanner::config(const Str& cfg, int num)
    2372                 :            : {
    2373 [ #  # ][ #  # ]:          0 :         if (cfg.to_string() == "indent:top")
    2374                 :            :         {
    2375         [ #  # ]:          0 :                 if (num < 0)
    2376                 :            :                 {
    2377                 :          0 :                         fatal("configuration 'indent:top' must be a positive integer");
    2378                 :            :                 }
    2379                 :          0 :                 topIndent = num;
    2380                 :            :         }
    2381 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "yybm:hex")
    2382                 :            :         {
    2383                 :          0 :                 yybmHexTable = num != 0;
    2384                 :            :         }
    2385 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "startlabel")
    2386                 :            :         {
    2387                 :          0 :                 bUseStartLabel = num != 0;
    2388                 :          0 :                 startLabelName = "";
    2389                 :            :         }
    2390 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "state:abort")
    2391                 :            :         {
    2392                 :          0 :                 bUseStateAbort = num != 0;
    2393                 :            :         }
    2394 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "state:nextlabel")
    2395                 :            :         {
    2396                 :          0 :                 bUseStateNext = num != 0;
    2397                 :            :         }
    2398 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "yyfill:enable")
    2399                 :            :         {
    2400                 :          0 :                 bUseYYFill = num != 0;
    2401                 :            :         }
    2402 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "yyfill:parameter")
    2403                 :            :         {
    2404                 :          0 :                 bUseYYFillParam = num != 0;
    2405                 :            :         }
    2406 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "yyfill:check")
    2407                 :            :         {
    2408                 :          0 :                 bUseYYFillCheck = num != 0;
    2409                 :            :         }
    2410 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "cgoto:threshold")
    2411                 :            :         {
    2412                 :          0 :                 cGotoThreshold = num;
    2413                 :            :         }
    2414 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "yych:conversion")
    2415                 :            :         {
    2416         [ #  # ]:          0 :                 if (num)
    2417                 :            :                 {
    2418                 :          0 :                         yychConversion  = "(";
    2419                 :          0 :                         yychConversion += mapCodeName["YYCTYPE"];
    2420                 :          0 :                         yychConversion += ")";
    2421                 :            :                 }
    2422                 :            :                 else
    2423                 :            :                 {
    2424                 :          0 :                         yychConversion  = "";
    2425                 :            :                 }
    2426                 :            :         }
    2427 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "yych:emit")
    2428                 :            :         {
    2429                 :          0 :                 bEmitYYCh = num != 0;
    2430                 :            :         }
    2431 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "define:YYFILL:naked")
    2432                 :            :         {
    2433                 :          0 :                 bUseYYFillNaked = num != 0;
    2434                 :            :         }
    2435 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "define:YYGETCONDITION:naked")
    2436                 :            :         {
    2437                 :          0 :                 bUseYYGetConditionNaked = num != 0;
    2438                 :            :         }
    2439 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "define:YYGETSTATE:naked")
    2440                 :            :         {
    2441                 :          0 :                 bUseYYGetStateNaked = num != 0;
    2442                 :            :         }
    2443 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "define:YYSETSTATE:naked")
    2444                 :            :         {
    2445                 :          0 :                 bUseYYSetStateNaked = num != 0;
    2446                 :            :         }
    2447 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "flags:u")
    2448                 :            :         {
    2449         [ #  # ]:          0 :                 if (!rFlag)
    2450                 :            :                 {
    2451 [ #  # ][ #  # ]:          0 :                         fatalf("cannot use configuration name '%s' without -r flag", cfg.to_string().c_str());
    2452                 :            :                 }
    2453                 :          0 :                 uFlag = num != 0;
    2454                 :            :         }
    2455 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "flags:w")
    2456                 :            :         {
    2457         [ #  # ]:          0 :                 if (!rFlag)
    2458                 :            :                 {
    2459 [ #  # ][ #  # ]:          0 :                         fatalf("cannot use configuration name '%s' without -r flag", cfg.to_string().c_str());
    2460                 :            :                 }
    2461                 :          0 :                 wFlag = num != 0;
    2462                 :            :         }
    2463                 :            :         else
    2464                 :            :         {
    2465 [ #  # ][ #  # ]:          0 :                 fatalf("unrecognized configuration name '%s' or illegal integer value", cfg.to_string().c_str());
    2466                 :            :         }
    2467                 :          0 : }
    2468                 :            : 
    2469                 :       2414 : static std::set<std::string> mapVariableKeys;
    2470                 :       2414 : static std::set<std::string> mapDefineKeys;
    2471                 :       2414 : static std::set<std::string> mapLabelKeys;
    2472                 :            : 
    2473                 :          0 : void Scanner::config(const Str& cfg, const Str& val)
    2474                 :            : {
    2475 [ #  # ][ #  # ]:          0 :         if (mapDefineKeys.empty())
    2476                 :            :         {
    2477 [ #  # ][ #  # ]:          0 :                 mapVariableKeys.insert("variable:yyaccept");
                 [ #  # ]
    2478 [ #  # ][ #  # ]:          0 :                 mapVariableKeys.insert("variable:yybm");
                 [ #  # ]
    2479 [ #  # ][ #  # ]:          0 :                 mapVariableKeys.insert("variable:yych");
                 [ #  # ]
    2480 [ #  # ][ #  # ]:          0 :                 mapVariableKeys.insert("variable:yyctable");
                 [ #  # ]
    2481 [ #  # ][ #  # ]:          0 :                 mapVariableKeys.insert("variable:yystable");
                 [ #  # ]
    2482 [ #  # ][ #  # ]:          0 :                 mapVariableKeys.insert("variable:yytarget");
                 [ #  # ]
    2483 [ #  # ][ #  # ]:          0 :                 mapDefineKeys.insert("define:YYCONDTYPE");
                 [ #  # ]
    2484 [ #  # ][ #  # ]:          0 :                 mapDefineKeys.insert("define:YYCTXMARKER");
                 [ #  # ]
    2485 [ #  # ][ #  # ]:          0 :                 mapDefineKeys.insert("define:YYCTYPE");
                 [ #  # ]
    2486 [ #  # ][ #  # ]:          0 :                 mapDefineKeys.insert("define:YYCURSOR");
                 [ #  # ]
    2487 [ #  # ][ #  # ]:          0 :                 mapDefineKeys.insert("define:YYDEBUG");
                 [ #  # ]
    2488 [ #  # ][ #  # ]:          0 :                 mapDefineKeys.insert("define:YYFILL");
                 [ #  # ]
    2489 [ #  # ][ #  # ]:          0 :                 mapDefineKeys.insert("define:YYGETCONDITION");
                 [ #  # ]
    2490 [ #  # ][ #  # ]:          0 :                 mapDefineKeys.insert("define:YYGETSTATE");
                 [ #  # ]
    2491 [ #  # ][ #  # ]:          0 :                 mapDefineKeys.insert("define:YYLIMIT");
                 [ #  # ]
    2492 [ #  # ][ #  # ]:          0 :                 mapDefineKeys.insert("define:YYMARKER");
                 [ #  # ]
    2493 [ #  # ][ #  # ]:          0 :                 mapDefineKeys.insert("define:YYSETCONDITION");
                 [ #  # ]
    2494 [ #  # ][ #  # ]:          0 :                 mapDefineKeys.insert("define:YYSETSTATE");
                 [ #  # ]
    2495 [ #  # ][ #  # ]:          0 :                 mapLabelKeys.insert("label:yyFillLabel");
                 [ #  # ]
    2496 [ #  # ][ #  # ]:          0 :                 mapLabelKeys.insert("label:yyNext");
                 [ #  # ]
    2497                 :            :         }
    2498                 :            : 
    2499         [ #  # ]:          0 :         std::string strVal;
    2500                 :            : 
    2501 [ #  # ][ #  # ]:          0 :         if (val.len >= 2 && val.str[0] == val.str[val.len-1] 
         [ #  # ][ #  # ]
    2502                 :          0 :         && (val.str[0] == '"' || val.str[0] == '\''))
    2503                 :            :         {
    2504                 :          0 :                 SubStr tmp(val.str + 1, val.len - 2);
    2505         [ #  # ]:          0 :                 unescape(tmp, strVal);
    2506                 :            :         }
    2507                 :            :         else
    2508                 :            :         {
    2509 [ #  # ][ #  # ]:          0 :                 strVal = val.to_string();
                 [ #  # ]
    2510                 :            :         }
    2511                 :            : 
    2512 [ #  # ][ #  # ]:          0 :         if (cfg.to_string() == "indent:string")
         [ #  # ][ #  # ]
    2513                 :            :         {
    2514         [ #  # ]:          0 :                 indString = strVal;
    2515                 :            :         }
    2516 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "startlabel")
         [ #  # ][ #  # ]
    2517                 :            :         {
    2518         [ #  # ]:          0 :                 startLabelName = strVal;
    2519         [ #  # ]:          0 :                 bUseStartLabel = !startLabelName.empty();
    2520                 :            :         }
    2521 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "labelprefix")
         [ #  # ][ #  # ]
    2522                 :            :         {
    2523         [ #  # ]:          0 :                 labelPrefix = strVal;
    2524                 :            :         }
    2525 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "condprefix")
         [ #  # ][ #  # ]
    2526                 :            :         {
    2527         [ #  # ]:          0 :                 condPrefix = strVal;
    2528                 :            :         }
    2529 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "condenumprefix")
         [ #  # ][ #  # ]
    2530                 :            :         {
    2531         [ #  # ]:          0 :                 condEnumPrefix = strVal;
    2532                 :            :         }
    2533 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "cond:divider")
         [ #  # ][ #  # ]
    2534                 :            :         {
    2535         [ #  # ]:          0 :                 condDivider = strVal;
    2536                 :            :         }
    2537 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "cond:divider@cond")
         [ #  # ][ #  # ]
    2538                 :            :         {
    2539         [ #  # ]:          0 :                 condDividerParam = strVal;
    2540                 :            :         }
    2541 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "cond:goto")
         [ #  # ][ #  # ]
    2542                 :            :         {
    2543         [ #  # ]:          0 :                 condGoto = strVal;
    2544                 :            :         }
    2545 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "cond:goto@cond")
         [ #  # ][ #  # ]
    2546                 :            :         {
    2547         [ #  # ]:          0 :                 condGotoParam = strVal;
    2548                 :            :         }
    2549 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "define:YYFILL@len")
         [ #  # ][ #  # ]
    2550                 :            :         {
    2551         [ #  # ]:          0 :                 yyFillLength = strVal;
    2552                 :          0 :                 bUseYYFillParam = false;
    2553                 :            :         }
    2554 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "define:YYSETCONDITION@cond")
         [ #  # ][ #  # ]
    2555                 :            :         {
    2556         [ #  # ]:          0 :                 yySetConditionParam = strVal;
    2557                 :          0 :                 bUseYYSetConditionParam = false;
    2558                 :            :         }
    2559 [ #  # ][ #  # ]:          0 :         else if (cfg.to_string() == "define:YYSETSTATE@state")
         [ #  # ][ #  # ]
    2560                 :            :         {
    2561         [ #  # ]:          0 :                 yySetStateParam = strVal;
    2562                 :          0 :                 bUseYYSetStateParam = false;
    2563                 :            :         }
    2564 [ #  # ][ #  # ]:          0 :         else if (mapVariableKeys.find(cfg.to_string()) != mapVariableKeys.end())
         [ #  # ][ #  # ]
                 [ #  # ]
    2565                 :            :     {
    2566 [ #  # ][ #  # ]:          0 :         if ((bFirstPass || rFlag) && !mapCodeName.insert(
         [ #  # ][ #  # ]
    2567                 :            :                         std::make_pair(cfg.to_string().substr(sizeof("variable:") - 1), strVal)
    2568 [ #  # ][ #  # ]:          0 :                         ).second)
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    2569                 :            :         {
    2570 [ #  # ][ #  # ]:          0 :                         fatalf("variable '%s' already being used and cannot be changed", cfg.to_string().c_str());
         [ #  # ][ #  # ]
    2571                 :            :         }
    2572                 :            :     }
    2573 [ #  # ][ #  # ]:          0 :         else if (mapDefineKeys.find(cfg.to_string()) != mapDefineKeys.end())
         [ #  # ][ #  # ]
                 [ #  # ]
    2574                 :            :     {
    2575 [ #  # ][ #  # ]:          0 :         if ((bFirstPass || rFlag) && !mapCodeName.insert(
         [ #  # ][ #  # ]
    2576                 :            :                         std::make_pair(cfg.to_string().substr(sizeof("define:") - 1), strVal)
    2577 [ #  # ][ #  # ]:          0 :                         ).second)
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    2578                 :            :         {
    2579 [ #  # ][ #  # ]:          0 :                         fatalf("define '%s' already being used and cannot be changed", cfg.to_string().c_str());
         [ #  # ][ #  # ]
    2580                 :            :                 }
    2581                 :            :     }
    2582 [ #  # ][ #  # ]:          0 :         else if (mapLabelKeys.find(cfg.to_string()) != mapLabelKeys.end())
         [ #  # ][ #  # ]
                 [ #  # ]
    2583                 :            :     {
    2584 [ #  # ][ #  # ]:          0 :         if ((bFirstPass || rFlag) && !mapCodeName.insert(
         [ #  # ][ #  # ]
    2585                 :            :                         std::make_pair(cfg.to_string().substr(sizeof("label:") - 1), strVal)
    2586 [ #  # ][ #  # ]:          0 :                         ).second)
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    2587                 :            :         {
    2588 [ #  # ][ #  # ]:          0 :                         fatalf("label '%s' already being used and cannot be changed", cfg.to_string().c_str());
         [ #  # ][ #  # ]
    2589                 :            :         }
    2590                 :            :     }
    2591                 :            :         else
    2592                 :            :         {
    2593         [ #  # ]:          0 :                 std::string msg = "unrecognized configuration name '";
    2594 [ #  # ][ #  # ]:          0 :                 msg += cfg.to_string();
                 [ #  # ]
    2595         [ #  # ]:          0 :                 msg += "' or illegal string value";
    2596 [ #  # ][ #  # ]:          0 :                 fatal(msg.c_str());
                 [ #  # ]
    2597         [ #  # ]:          0 :         }
    2598                 :          0 : }
    2599                 :            : 
    2600                 :         72 : ScannerState::ScannerState()
    2601                 :            :         : tok(NULL), ptr(NULL), cur(NULL), pos(NULL), ctx(NULL)
    2602                 :            :         , bot(NULL), lim(NULL), top(NULL), eof(NULL)
    2603                 :            :         , tchar(0), tline(0), cline(1), iscfg(0)
    2604                 :         72 :         , in_parse(false)
    2605                 :            : {
    2606                 :         72 : }
    2607                 :            : 
    2608                 :         72 : Scanner::Scanner(std::istream& i, std::ostream& o)
    2609                 :         72 :         : ScannerState(), in(i), out(o)
    2610                 :            : {
    2611                 :         72 : }
    2612                 :            : 
    2613                 :          0 : char *Scanner::fill(char *cursor, unsigned need)
    2614                 :            : {
    2615         [ #  # ]:          0 :         if(!eof)
    2616                 :            :         {
    2617                 :            :                 unsigned cnt;
    2618                 :            :                 /* Do not get rid of anything when rFlag is active. Otherwise
    2619                 :            :                  * get rid of everything that was already handedout. */
    2620         [ #  # ]:          0 :                 if (!rFlag)
    2621                 :            :                 {
    2622                 :          0 :                         cnt = tok - bot;
    2623         [ #  # ]:          0 :                         if (cnt)
    2624                 :            :                         {
    2625                 :          0 :                                 memmove(bot, tok, top - tok);
    2626                 :          0 :                                 tok  = bot;
    2627                 :          0 :                                 ptr -= cnt;
    2628                 :          0 :                                 cur -= cnt;
    2629                 :          0 :                                 pos -= cnt;
    2630                 :          0 :                                 lim -= cnt;
    2631                 :          0 :                                 ctx -= cnt;
    2632                 :          0 :                                 cursor -= cnt;
    2633                 :            :                         }
    2634                 :            :                 }
    2635                 :            :                 /* In crease buffer size. */
    2636         [ #  # ]:          0 :                 if (BSIZE > need)
    2637                 :            :                 {
    2638                 :          0 :                         need = BSIZE;
    2639                 :            :                 }
    2640         [ #  # ]:          0 :                 if (static_cast<unsigned>(top - lim) < need)
    2641                 :            :                 {
    2642                 :          0 :                         char *buf = new char[(lim - bot) + need];
    2643         [ #  # ]:          0 :                         if (!buf)
    2644                 :            :                         {
    2645                 :          0 :                                 fatal("Out of memory");
    2646                 :            :                         }
    2647                 :          0 :                         memcpy(buf, bot, lim - bot);
    2648                 :          0 :                         tok = &buf[tok - bot];
    2649                 :          0 :                         ptr = &buf[ptr - bot];
    2650                 :          0 :                         cur = &buf[cur - bot];
    2651                 :          0 :                         pos = &buf[pos - bot];
    2652                 :          0 :                         lim = &buf[lim - bot];
    2653                 :          0 :                         top = &lim[need];
    2654                 :          0 :                         ctx = &buf[ctx - bot];
    2655                 :          0 :                         cursor = &buf[cursor - bot];
    2656         [ #  # ]:          0 :                         delete [] bot;
    2657                 :          0 :                         bot = buf;
    2658                 :            :                 }
    2659                 :            :                 /* Append to buffer. */
    2660                 :          0 :                 in.read(lim, need);
    2661         [ #  # ]:          0 :                 if ((cnt = in.gcount()) != need)
    2662                 :            :                 {
    2663                 :          0 :                         eof = &lim[cnt];
    2664                 :          0 :                         *eof++ = '\0';
    2665                 :            :                 }
    2666                 :          0 :                 lim += cnt;
    2667                 :            :         }
    2668                 :          0 :         return cursor;
    2669                 :            : }
    2670                 :            : 
    2671                 :          0 : void Scanner::set_in_parse(bool new_in_parse)
    2672                 :            : {
    2673                 :          0 :         in_parse = new_in_parse;
    2674                 :          0 : }
    2675                 :            : 
    2676                 :          0 : void Scanner::fatal_at(unsigned line, unsigned ofs, const char *msg) const
    2677                 :            : {
    2678 [ #  # ][ #  # ]:          0 :   throw re2c_error("regex error:" + std::string(msg), tchar + ofs + 1);
                 [ #  # ]
    2679                 :            : }
    2680                 :            : 
    2681                 :          0 : void Scanner::fatal(unsigned ofs, const char *msg) const
    2682                 :            : {
    2683         [ #  # ]:          0 :         fatal_at(in_parse ? tline : cline, ofs, msg);
    2684                 :          0 : }
    2685                 :            : 
    2686                 :          0 : void Scanner::fatalf_at(unsigned line, const char* fmt, ...) const
    2687                 :            : {
    2688                 :            :         char szBuf[4096];
    2689                 :            : 
    2690                 :            :         va_list args;
    2691                 :            :         
    2692                 :          0 :         va_start(args, fmt);
    2693                 :          0 :         vsnprintf(szBuf, sizeof(szBuf), fmt, args);
    2694                 :          0 :         va_end(args);
    2695                 :            :         
    2696                 :          0 :         szBuf[sizeof(szBuf)-1] = '0';
    2697                 :            :         
    2698         [ #  # ]:          0 :         fatal_at(line, 0, szBuf);
    2699                 :          0 : }
    2700                 :            : 
    2701                 :          0 : void Scanner::fatalf(const char *fmt, ...) const
    2702                 :            : {
    2703                 :            :         char szBuf[4096];
    2704                 :            : 
    2705                 :            :         va_list args;
    2706                 :            :         
    2707                 :          0 :         va_start(args, fmt);
    2708                 :          0 :         vsnprintf(szBuf, sizeof(szBuf), fmt, args);
    2709                 :          0 :         va_end(args);
    2710                 :            :         
    2711                 :          0 :         szBuf[sizeof(szBuf)-1] = '0';
    2712                 :            :         
    2713         [ #  # ]:          0 :         fatal(szBuf);
    2714                 :          0 : }
    2715                 :            : 
    2716                 :        144 : Scanner::~Scanner()
    2717                 :            : {
    2718         [ -  + ]:         72 :         if (bot)
    2719                 :            :         {
    2720         [ #  # ]:          0 :                 delete [] bot;
    2721                 :            :         }
    2722         [ -  + ]:        144 : }
    2723                 :            : 
    2724                 :          0 : void Scanner::check_token_length(char *pos, unsigned len) const
    2725                 :            : {
    2726 [ #  # ][ #  # ]:          0 :         if (pos < bot || pos + len > top)
    2727                 :            :         {
    2728                 :          0 :                 fatal("Token exceeds limit");
    2729                 :            :         }
    2730                 :          0 : }
    2731                 :            : 
    2732                 :          0 : Str Scanner::raw_token(std::string enclosure) const
    2733                 :            : {
    2734 [ #  # ][ #  # ]:          0 :         return Str(std::string(enclosure + token().to_string() + enclosure).c_str());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2735                 :            : }
    2736                 :            : 
    2737                 :          0 : void Scanner::reuse()
    2738                 :            : {
    2739                 :          0 :         next_label = 0;
    2740                 :          0 :         next_fill_index = 0;
    2741                 :          0 :         bWroteGetState = false;
    2742                 :          0 :         bWroteCondCheck = false;
    2743                 :          0 :         mapCodeName.clear();
    2744                 :          0 : }
    2745                 :            : 
    2746                 :          0 : void Scanner::restore_state(const ScannerState& state)
    2747                 :            : {
    2748                 :          0 :         int diff = bot - state.bot;
    2749                 :          0 :         char *old_bot = bot;
    2750                 :          0 :         char *old_lim = lim;
    2751                 :          0 :         char *old_top = top;
    2752                 :          0 :         char *old_eof = eof;
    2753                 :          0 :         *(ScannerState*)this = state;
    2754         [ #  # ]:          0 :         if (diff)
    2755                 :            :         {
    2756                 :          0 :                 tok -= diff;
    2757                 :          0 :                 ptr -= diff;
    2758                 :          0 :                 cur -= diff;
    2759                 :          0 :                 pos -= diff;
    2760                 :          0 :                 ctx -= diff;            
    2761                 :          0 :                 bot = old_bot;
    2762                 :          0 :                 lim = old_lim;
    2763                 :          0 :                 top = old_top;
    2764                 :          0 :                 eof = old_eof;
    2765                 :            :         }
    2766                 :          0 : }
    2767                 :            : 
    2768 [ +  - ][ +  - ]:       7242 : } // end namespace re2c

Generated by: LCOV version 1.9