/ Check-in [06719b74]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Lemon change: compile the resulting parser with -DYYSTACKDEPTH=0 or set the "%stack_size" parameter to 0 in the grammar and the parser stack will be dynamically allocated using realloc() and free(). The default behavior is to have a finite depth stack. (CVS 3738)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 06719b741ab1a2df0371f6d587563cc81eb8880a
User & Date: drh 2007-03-29 01:44:46
Context
2007-03-29
02:26
Get LEMON working again when YYSTACKDEPTH is greater than zero. (CVS 3739) check-in: e72c81db user: drh tags: trunk
01:44
Lemon change: compile the resulting parser with -DYYSTACKDEPTH=0 or set the "%stack_size" parameter to 0 in the grammar and the parser stack will be dynamically allocated using realloc() and free(). The default behavior is to have a finite depth stack. (CVS 3738) check-in: 06719b74 user: drh tags: trunk
00:08
Patch so the the code compiles with -DSQLITE_OMIT_CHECK=1. (CVS 3737) check-in: 72cea358 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to tool/lemon.c.

  3510   3510     if( lemp->wildcard ){
  3511   3511       fprintf(out,"#define YYWILDCARD %d\n",
  3512   3512          lemp->wildcard->index); lineno++;
  3513   3513     }
  3514   3514     print_stack_union(out,lemp,&lineno,mhflag);
  3515   3515     fprintf(out, "#ifndef YYSTACKDEPTH\n"); lineno++;
  3516   3516     if( lemp->stacksize ){
  3517         -    if( atoi(lemp->stacksize)<=0 ){
  3518         -      ErrorMsg(lemp->filename,0,
  3519         -"Illegal stack size: [%s].  The stack size should be an integer constant.",
  3520         -        lemp->stacksize);
  3521         -      lemp->errorcnt++;
  3522         -      lemp->stacksize = "100";
  3523         -    }
  3524   3517       fprintf(out,"#define YYSTACKDEPTH %s\n",lemp->stacksize);  lineno++;
  3525   3518     }else{
  3526   3519       fprintf(out,"#define YYSTACKDEPTH 100\n");  lineno++;
  3527   3520     }
  3528   3521     fprintf(out, "#endif\n"); lineno++;
  3529   3522     if( mhflag ){
  3530   3523       fprintf(out,"#if INTERFACE\n"); lineno++;

Changes to tool/lempar.c.

    40     40   **                       states combined.  "int" is used otherwise.
    41     41   **    ParseTOKENTYPE     is the data type used for minor tokens given 
    42     42   **                       directly to the parser from the tokenizer.
    43     43   **    YYMINORTYPE        is the data type used for all minor tokens.
    44     44   **                       This is typically a union of many types, one of
    45     45   **                       which is ParseTOKENTYPE.  The entry in the union
    46     46   **                       for base tokens is called "yy0".
    47         -**    YYSTACKDEPTH       is the maximum depth of the parser's stack.
           47  +**    YYSTACKDEPTH       is the maximum depth of the parser's stack.  If
           48  +**                       zero the stack is dynamically sized using realloc()
    48     49   **    ParseARG_SDECL     A static variable declaration for the %extra_argument
    49     50   **    ParseARG_PDECL     A parameter declaration for the %extra_argument
    50     51   **    ParseARG_STORE     Code to store %extra_argument into yypParser
    51     52   **    ParseARG_FETCH     Code to extract %extra_argument from yypParser
    52     53   **    YYNSTATE           the combined number of states.
    53     54   **    YYNRULE            the number of rules in the grammar
    54     55   **    YYERRORSYMBOL      is the code number of the error symbol.  If not
................................................................................
   148    149   
   149    150   /* The state of the parser is completely contained in an instance of
   150    151   ** the following structure */
   151    152   struct yyParser {
   152    153     int yyidx;                    /* Index of top element in stack */
   153    154     int yyerrcnt;                 /* Shifts left before out of the error */
   154    155     ParseARG_SDECL                /* A place to hold %extra_argument */
          156  +#if YYSTACKDEPTH<=0
          157  +  int yystksz;                  /* Current side of the stack */
          158  +  yyStackEntry *yystack;        /* The parser's stack */
          159  +#else
   155    160     yyStackEntry yystack[YYSTACKDEPTH];  /* The parser's stack */
          161  +#endif
   156    162   };
   157    163   typedef struct yyParser yyParser;
   158    164   
   159    165   #ifndef NDEBUG
   160    166   #include <stdio.h>
   161    167   static FILE *yyTraceFILE = 0;
   162    168   static char *yyTracePrompt = 0;
................................................................................
   216    222       return "Unknown";
   217    223     }
   218    224   #else
   219    225     return "";
   220    226   #endif
   221    227   }
   222    228   
          229  +#if YYSTACKDEPTH<=0
          230  +/*
          231  +** Try to increase the size of the parser stack.
          232  +*/
          233  +static void yyGrowStack(yyParser *p){
          234  +  int newSize;
          235  +  yyStackEntry *pNew;
          236  +
          237  +  newSize = p->yystksz*2 + 100;
          238  +  pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
          239  +  if( pNew ){
          240  +    p->yystack = pNew;
          241  +    p->yystksz = newSize;
          242  +#ifndef NDEBUG
          243  +    if( yyTraceFILE ){
          244  +      fprintf(yyTraceFILE,"%sStack grows to %d entries!\n",
          245  +              yyTracePrompt, p->yystksz);
          246  +    }
          247  +#endif
          248  +  }
          249  +}
          250  +#endif
          251  +
   223    252   /* 
   224    253   ** This function allocates a new parser.
   225    254   ** The only argument is a pointer to a function which works like
   226    255   ** malloc.
   227    256   **
   228    257   ** Inputs:
   229    258   ** A pointer to the function used to allocate memory.
................................................................................
   233    262   ** to Parse and ParseFree.
   234    263   */
   235    264   void *ParseAlloc(void *(*mallocProc)(size_t)){
   236    265     yyParser *pParser;
   237    266     pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
   238    267     if( pParser ){
   239    268       pParser->yyidx = -1;
          269  +#if YYSTACKDEPTH<=0
          270  +    yyGrowStack(pParser);
          271  +#endif
   240    272     }
   241    273     return pParser;
   242    274   }
   243    275   
   244    276   /* The following function deletes the value associated with a
   245    277   ** symbol.  The symbol can be either a terminal or nonterminal.
   246    278   ** "yymajor" is the symbol code, and "yypminor" is a pointer to
................................................................................
   304    336   void ParseFree(
   305    337     void *p,                    /* The parser to be deleted */
   306    338     void (*freeProc)(void*)     /* Function used to reclaim memory */
   307    339   ){
   308    340     yyParser *pParser = (yyParser*)p;
   309    341     if( pParser==0 ) return;
   310    342     while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
          343  +#if YYSTACKDEPTH<=0
          344  +  free(pParser->yystack);
          345  +#endif
   311    346     (*freeProc)((void*)pParser);
   312    347   }
   313    348   
   314    349   /*
   315    350   ** Find the appropriate action for a parser given the terminal
   316    351   ** look-ahead token iLookAhead.
   317    352   **
................................................................................
   394    429     i += iLookAhead;
   395    430     if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
   396    431       return yy_default[stateno];
   397    432     }else{
   398    433       return yy_action[i];
   399    434     }
   400    435   }
          436  +
          437  +/*
          438  +** The following routine is called if the stack overflows.
          439  +*/
          440  +static void yyStackOverflow(yyParser *yypParser){
          441  +   ParseARG_FETCH;
          442  +   yypParser->yyidx--;
          443  +#ifndef NDEBUG
          444  +   if( yyTraceFILE ){
          445  +     fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
          446  +   }
          447  +#endif
          448  +   while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
          449  +   /* Here code is inserted which will execute if the parser
          450  +   ** stack every overflows */
          451  +%%
          452  +   ParseARG_STORE; /* Suppress warning about unused %extra_argument var */
          453  +}
   401    454   
   402    455   /*
   403    456   ** Perform a shift action.
   404    457   */
   405    458   static void yy_shift(
   406    459     yyParser *yypParser,          /* The parser to be shifted */
   407    460     int yyNewState,               /* The new state to shift in */
   408    461     int yyMajor,                  /* The major token to shift in */
   409    462     YYMINORTYPE *yypMinor         /* Pointer ot the minor token to shift in */
   410    463   ){
   411    464     yyStackEntry *yytos;
   412    465     yypParser->yyidx++;
          466  +#if YYSTACKDEPTH>0 
   413    467     if( yypParser->yyidx>=YYSTACKDEPTH ){
   414         -     ParseARG_FETCH;
   415         -     yypParser->yyidx--;
   416         -#ifndef NDEBUG
   417         -     if( yyTraceFILE ){
   418         -       fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
   419         -     }
   420         -#endif
   421         -     while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
   422         -     /* Here code is inserted which will execute if the parser
   423         -     ** stack every overflows */
   424         -%%
   425         -     ParseARG_STORE; /* Suppress warning about unused %extra_argument var */
   426         -     return;
          468  +    yyStackOverflow(yypParser);
          469  +    return;
          470  +  }
          471  +#else
          472  +  if( yypParser->yyidx>=yypParser->yystksz ){
          473  +    yyGrowStack(yypParser);
          474  +    if( yypParser->yyidx>=yypParser->yystksz ){
          475  +      yyStackOverflow(yypParser);
          476  +      return;
          477  +    }
   427    478     }
          479  +#endif
   428    480     yytos = &yypParser->yystack[yypParser->yyidx];
   429    481     yytos->stateno = yyNewState;
   430    482     yytos->major = yyMajor;
   431    483     yytos->minor = *yypMinor;
   432    484   #ifndef NDEBUG
   433    485     if( yyTraceFILE && yypParser->yyidx>0 ){
   434    486       int i;
................................................................................
   612    664     int yyendofinput;     /* True if we are at the end of input */
   613    665     int yyerrorhit = 0;   /* True if yymajor has invoked an error */
   614    666     yyParser *yypParser;  /* The parser */
   615    667   
   616    668     /* (re)initialize the parser, if necessary */
   617    669     yypParser = (yyParser*)yyp;
   618    670     if( yypParser->yyidx<0 ){
   619         -    /* if( yymajor==0 ) return; // not sure why this was here... */
          671  +    if( yypParser->yystksz <=0 ){
          672  +      yyStackOverflow(yypParser);
          673  +      return;
          674  +    }
   620    675       yypParser->yyidx = 0;
   621    676       yypParser->yyerrcnt = -1;
   622    677       yypParser->yystack[0].stateno = 0;
   623    678       yypParser->yystack[0].major = 0;
   624    679     }
   625    680     yyminorunion.yy0 = yyminor;
   626    681     yyendofinput = (yymajor==0);