/ Check-in [be47a6f5]
Login

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

Overview
Comment:Add the %extra_context directive to lemon, as an alternative to %extra_argument. Use this to improve the performance of the parser.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: be47a6f5262a43f477700579512fe7112a0872faedcbbe5c3383d13a08af6440
User & Date: drh 2018-04-21 13:51:42
Context
2018-04-21
14:11
A few more tests for upsert. check-in: b78005b6 user: dan tags: trunk
13:51
Add the %extra_context directive to lemon, as an alternative to %extra_argument. Use this to improve the performance of the parser. check-in: be47a6f5 user: drh tags: trunk
03:06
Fix UPSERT so that it plays nicely with AUTOINCREMENT. check-in: 359725ab user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to doc/lemon.html.

    95     95   As of this writing, the following command-line options are supported:
    96     96   <ul>
    97     97   <li><b>-b</b>
    98     98   Show only the basis for each parser state in the report file.
    99     99   <li><b>-c</b>
   100    100   Do not compress the generated action tables.  The parser will be a
   101    101   little larger and slower, but it will detect syntax errors sooner.
          102  +<li><b>-d</b><i>directory</i>
          103  +Write all output files into <i>directory</i>.  Normally, output files
          104  +are written into the directory that contains the input grammar file.
   102    105   <li><b>-D<i>name</i></b>
   103    106   Define C preprocessor macro <i>name</i>.  This macro is usable by
   104    107   "<tt><a href='#pifdef'>%ifdef</a></tt>" and
   105    108   "<tt><a href='#pifdef'>%ifndef</a></tt>" lines
   106    109   in the grammar file.
   107    110   <li><b>-g</b>
   108    111   Do not generate a parser.  Instead write the input grammar to standard
................................................................................
   675    678   </pre></p>
   676    679   
   677    680   <p>Then the Parse() function generated will have an 4th parameter
   678    681   of type "MyStruct*" and all action routines will have access to
   679    682   a variable named "pAbc" that is the value of the 4th parameter
   680    683   in the most recent call to Parse().</p>
   681    684   
          685  +<p>The <tt>%extra_context</tt> directive works the same except that it
          686  +is passed in on the ParseAlloc() or ParseInit() routines instead of
          687  +on Parse().
          688  +
          689  +<a name='extractx'></a>
          690  +<h4>The <tt>%extra_context</tt> directive</h4>
          691  +
          692  +The <tt>%extra_context</tt> directive instructs Lemon to add a 2th parameter
          693  +to the parameter list of the ParseAlloc() and ParseInif() functions.  Lemon
          694  +doesn't do anything itself with these extra argument, but it does
          695  +store the value make it available to C-code action routines, destructors,
          696  +and so forth.  For example, if the grammar file contains:</p>
          697  +
          698  +<p><pre>
          699  +    %extra_context { MyStruct *pAbc }
          700  +</pre></p>
          701  +
          702  +<p>Then the ParseAlloc() and ParseInit() functions will have an 2th parameter
          703  +of type "MyStruct*" and all action routines will have access to
          704  +a variable named "pAbc" that is the value of that 2th parameter.</p>
          705  +
          706  +<p>The <tt>%extra_argument</tt> directive works the same except that it
          707  +is passed in on the Parse() routine instead of on ParseAlloc()/ParseInit().
          708  +
   682    709   <a name='pfallback'></a>
   683    710   <h4>The <tt>%fallback</tt> directive</h4>
   684    711   
   685    712   <p>The <tt>%fallback</tt> directive specifies an alternative meaning for one
   686    713   or more tokens.  The alternative meaning is tried if the original token
   687    714   would have generated a syntax error.</p>
   688    715   

Changes to src/parse.y.

    20     20   
    21     21   // The type of the data attached to each token is Token.  This is also the
    22     22   // default type for non-terminals.
    23     23   //
    24     24   %token_type {Token}
    25     25   %default_type {Token}
    26     26   
    27         -// The generated parser function takes a 4th argument as follows:
    28         -%extra_argument {Parse *pParse}
           27  +// An extra argument to the constructor for the parser, which is available
           28  +// to all actions.
           29  +%extra_context {Parse *pParse}
    29     30   
    30     31   // This code runs whenever there is a syntax error
    31     32   //
    32     33   %syntax_error {
    33     34     UNUSED_PARAMETER(yymajor);  /* Silence some compiler warnings */
    34     35     if( TOKEN.z[0] ){
    35     36       sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);

Changes to src/sqliteInt.h.

  4209   4209   char sqlite3IndexColumnAffinity(sqlite3*, Index*, int);
  4210   4210   #endif
  4211   4211   
  4212   4212   /*
  4213   4213   ** The interface to the LEMON-generated parser
  4214   4214   */
  4215   4215   #ifndef SQLITE_AMALGAMATION
  4216         -  void *sqlite3ParserAlloc(void*(*)(u64));
         4216  +  void *sqlite3ParserAlloc(void*(*)(u64), Parse*);
  4217   4217     void sqlite3ParserFree(void*, void(*)(void*));
  4218   4218   #endif
  4219         -void sqlite3Parser(void*, int, Token, Parse*);
         4219  +void sqlite3Parser(void*, int, Token);
  4220   4220   #ifdef YYTRACKMAXSTACKDEPTH
  4221   4221     int sqlite3ParserStackPeak(void*);
  4222   4222   #endif
  4223   4223   
  4224   4224   void sqlite3AutoLoadExtensions(sqlite3*);
  4225   4225   #ifndef SQLITE_OMIT_LOAD_EXTENSION
  4226   4226     void sqlite3CloseExtensions(sqlite3*);

Changes to src/tokenize.c.

   492    492     }
   493    493     pParse->rc = SQLITE_OK;
   494    494     pParse->zTail = zSql;
   495    495     assert( pzErrMsg!=0 );
   496    496     /* sqlite3ParserTrace(stdout, "parser: "); */
   497    497   #ifdef sqlite3Parser_ENGINEALWAYSONSTACK
   498    498     pEngine = &sEngine;
   499         -  sqlite3ParserInit(pEngine);
          499  +  sqlite3ParserInit(pEngine, pParse);
   500    500   #else
   501         -  pEngine = sqlite3ParserAlloc(sqlite3Malloc);
          501  +  pEngine = sqlite3ParserAlloc(sqlite3Malloc, pParse);
   502    502     if( pEngine==0 ){
   503    503       sqlite3OomFault(db);
   504    504       return SQLITE_NOMEM_BKPT;
   505    505     }
   506    506   #endif
   507    507     assert( pParse->pNewTable==0 );
   508    508     assert( pParse->pNewTrigger==0 );
................................................................................
   538    538           sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql);
   539    539           break;
   540    540         }
   541    541         zSql += n;
   542    542       }else{
   543    543         pParse->sLastToken.z = zSql;
   544    544         pParse->sLastToken.n = n;
   545         -      sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
          545  +      sqlite3Parser(pEngine, tokenType, pParse->sLastToken);
   546    546         lastTokenParsed = tokenType;
   547    547         zSql += n;
   548    548         if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
   549    549       }
   550    550     }
   551    551     assert( nErr==0 );
   552    552     pParse->zTail = zSql;

Changes to tool/lemon.c.

   392    392     int maxAction;           /* Maximum action value of any kind */
   393    393     struct symbol **symbols; /* Sorted array of pointers to symbols */
   394    394     int errorcnt;            /* Number of errors */
   395    395     struct symbol *errsym;   /* The error symbol */
   396    396     struct symbol *wildcard; /* Token that matches anything */
   397    397     char *name;              /* Name of the generated parser */
   398    398     char *arg;               /* Declaration of the 3th argument to parser */
          399  +  char *ctx;               /* Declaration of 2nd argument to constructor */
   399    400     char *tokentype;         /* Type of terminal symbols in the parser stack */
   400    401     char *vartype;           /* The default type of non-terminal symbols */
   401    402     char *start;             /* Name of the start symbol for the grammar */
   402    403     char *stacksize;         /* Size of the parser stack */
   403    404     char *include;           /* Code to put at the start of the C file */
   404    405     char *error;             /* Code to execute when an error is seen */
   405    406     char *overflow;          /* Code to execute on a stack overflow */
................................................................................
  2488   2489             psp->declargslot = &(psp->gp->accept);
  2489   2490           }else if( strcmp(x,"parse_failure")==0 ){
  2490   2491             psp->declargslot = &(psp->gp->failure);
  2491   2492           }else if( strcmp(x,"stack_overflow")==0 ){
  2492   2493             psp->declargslot = &(psp->gp->overflow);
  2493   2494           }else if( strcmp(x,"extra_argument")==0 ){
  2494   2495             psp->declargslot = &(psp->gp->arg);
         2496  +          psp->insertLineMacro = 0;
         2497  +        }else if( strcmp(x,"extra_context")==0 ){
         2498  +          psp->declargslot = &(psp->gp->ctx);
  2495   2499             psp->insertLineMacro = 0;
  2496   2500           }else if( strcmp(x,"token_type")==0 ){
  2497   2501             psp->declargslot = &(psp->gp->tokentype);
  2498   2502             psp->insertLineMacro = 0;
  2499   2503           }else if( strcmp(x,"default_type")==0 ){
  2500   2504             psp->declargslot = &(psp->gp->vartype);
  2501   2505             psp->insertLineMacro = 0;
................................................................................
  4194   4198     name = lemp->name ? lemp->name : "Parse";
  4195   4199     if( lemp->arg && lemp->arg[0] ){
  4196   4200       i = lemonStrlen(lemp->arg);
  4197   4201       while( i>=1 && ISSPACE(lemp->arg[i-1]) ) i--;
  4198   4202       while( i>=1 && (ISALNUM(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--;
  4199   4203       fprintf(out,"#define %sARG_SDECL %s;\n",name,lemp->arg);  lineno++;
  4200   4204       fprintf(out,"#define %sARG_PDECL ,%s\n",name,lemp->arg);  lineno++;
  4201         -    fprintf(out,"#define %sARG_FETCH %s = yypParser->%s\n",
         4205  +    fprintf(out,"#define %sARG_PARAM ,%s\n",name,&lemp->arg[i]);  lineno++;
         4206  +    fprintf(out,"#define %sARG_FETCH %s=yypParser->%s;\n",
  4202   4207                    name,lemp->arg,&lemp->arg[i]);  lineno++;
  4203         -    fprintf(out,"#define %sARG_STORE yypParser->%s = %s\n",
         4208  +    fprintf(out,"#define %sARG_STORE yypParser->%s=%s;\n",
  4204   4209                    name,&lemp->arg[i],&lemp->arg[i]);  lineno++;
  4205   4210     }else{
  4206         -    fprintf(out,"#define %sARG_SDECL\n",name);  lineno++;
  4207         -    fprintf(out,"#define %sARG_PDECL\n",name);  lineno++;
         4211  +    fprintf(out,"#define %sARG_SDECL\n",name); lineno++;
         4212  +    fprintf(out,"#define %sARG_PDECL\n",name); lineno++;
         4213  +    fprintf(out,"#define %sARG_PARAM\n",name); lineno++;
  4208   4214       fprintf(out,"#define %sARG_FETCH\n",name); lineno++;
  4209   4215       fprintf(out,"#define %sARG_STORE\n",name); lineno++;
  4210   4216     }
         4217  +  if( lemp->ctx && lemp->ctx[0] ){
         4218  +    i = lemonStrlen(lemp->ctx);
         4219  +    while( i>=1 && ISSPACE(lemp->ctx[i-1]) ) i--;
         4220  +    while( i>=1 && (ISALNUM(lemp->ctx[i-1]) || lemp->ctx[i-1]=='_') ) i--;
         4221  +    fprintf(out,"#define %sCTX_SDECL %s;\n",name,lemp->ctx);  lineno++;
         4222  +    fprintf(out,"#define %sCTX_PDECL ,%s\n",name,lemp->ctx);  lineno++;
         4223  +    fprintf(out,"#define %sCTX_PARAM ,%s\n",name,&lemp->ctx[i]);  lineno++;
         4224  +    fprintf(out,"#define %sCTX_FETCH %s=yypParser->%s;\n",
         4225  +                 name,lemp->ctx,&lemp->ctx[i]);  lineno++;
         4226  +    fprintf(out,"#define %sCTX_STORE yypParser->%s=%s;\n",
         4227  +                 name,&lemp->ctx[i],&lemp->ctx[i]);  lineno++;
         4228  +  }else{
         4229  +    fprintf(out,"#define %sCTX_SDECL\n",name); lineno++;
         4230  +    fprintf(out,"#define %sCTX_PDECL\n",name); lineno++;
         4231  +    fprintf(out,"#define %sCTX_PARAM\n",name); lineno++;
         4232  +    fprintf(out,"#define %sCTX_FETCH\n",name); lineno++;
         4233  +    fprintf(out,"#define %sCTX_STORE\n",name); lineno++;
         4234  +  }
  4211   4235     if( mhflag ){
  4212   4236       fprintf(out,"#endif\n"); lineno++;
  4213   4237     }
  4214   4238     if( lemp->errsym && lemp->errsym->useCnt ){
  4215   4239       fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++;
  4216   4240       fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++;
  4217   4241     }

Changes to tool/lempar.c.

    62     62   **                       This is typically a union of many types, one of
    63     63   **                       which is ParseTOKENTYPE.  The entry in the union
    64     64   **                       for terminal symbols is called "yy0".
    65     65   **    YYSTACKDEPTH       is the maximum depth of the parser's stack.  If
    66     66   **                       zero the stack is dynamically sized using realloc()
    67     67   **    ParseARG_SDECL     A static variable declaration for the %extra_argument
    68     68   **    ParseARG_PDECL     A parameter declaration for the %extra_argument
           69  +**    ParseARG_PARAM     Code to pass %extra_argument as a subroutine parameter
    69     70   **    ParseARG_STORE     Code to store %extra_argument into yypParser
    70     71   **    ParseARG_FETCH     Code to extract %extra_argument from yypParser
           72  +**    ParseCTX_*         As ParseARG_ except for %extra_context
    71     73   **    YYERRORSYMBOL      is the code number of the error symbol.  If not
    72     74   **                       defined, then do no error processing.
    73     75   **    YYNSTATE           the combined number of states.
    74     76   **    YYNRULE            the number of rules in the grammar
    75     77   **    YYNTOKEN           Number of terminal symbols
    76     78   **    YY_MAX_SHIFT       Maximum value for shift actions
    77     79   **    YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
................................................................................
   207    209   #ifdef YYTRACKMAXSTACKDEPTH
   208    210     int yyhwm;                    /* High-water mark of the stack */
   209    211   #endif
   210    212   #ifndef YYNOERRORRECOVERY
   211    213     int yyerrcnt;                 /* Shifts left before out of the error */
   212    214   #endif
   213    215     ParseARG_SDECL                /* A place to hold %extra_argument */
          216  +  ParseCTX_SDECL                /* A place to hold %extra_context */
   214    217   #if YYSTACKDEPTH<=0
   215    218     int yystksz;                  /* Current side of the stack */
   216    219     yyStackEntry *yystack;        /* The parser's stack */
   217    220     yyStackEntry yystk0;          /* First stack entry */
   218    221   #else
   219    222     yyStackEntry yystack[YYSTACKDEPTH];  /* The parser's stack */
   220    223     yyStackEntry *yystackEnd;            /* Last entry in the stack */
................................................................................
   311    314   */
   312    315   #ifndef YYMALLOCARGTYPE
   313    316   # define YYMALLOCARGTYPE size_t
   314    317   #endif
   315    318   
   316    319   /* Initialize a new parser that has already been allocated.
   317    320   */
   318         -void ParseInit(void *yypParser){
   319         -  yyParser *pParser = (yyParser*)yypParser;
          321  +void ParseInit(void *yypRawParser ParseCTX_PDECL){
          322  +  yyParser *yypParser = (yyParser*)yypRawParser;
          323  +  ParseCTX_STORE
   320    324   #ifdef YYTRACKMAXSTACKDEPTH
   321         -  pParser->yyhwm = 0;
          325  +  yypParser->yyhwm = 0;
   322    326   #endif
   323    327   #if YYSTACKDEPTH<=0
   324         -  pParser->yytos = NULL;
   325         -  pParser->yystack = NULL;
   326         -  pParser->yystksz = 0;
   327         -  if( yyGrowStack(pParser) ){
   328         -    pParser->yystack = &pParser->yystk0;
   329         -    pParser->yystksz = 1;
          328  +  yypParser->yytos = NULL;
          329  +  yypParser->yystack = NULL;
          330  +  yypParser->yystksz = 0;
          331  +  if( yyGrowStack(yypParser) ){
          332  +    yypParser->yystack = &yypParser->yystk0;
          333  +    yypParser->yystksz = 1;
   330    334     }
   331    335   #endif
   332    336   #ifndef YYNOERRORRECOVERY
   333         -  pParser->yyerrcnt = -1;
          337  +  yypParser->yyerrcnt = -1;
   334    338   #endif
   335         -  pParser->yytos = pParser->yystack;
   336         -  pParser->yystack[0].stateno = 0;
   337         -  pParser->yystack[0].major = 0;
          339  +  yypParser->yytos = yypParser->yystack;
          340  +  yypParser->yystack[0].stateno = 0;
          341  +  yypParser->yystack[0].major = 0;
   338    342   #if YYSTACKDEPTH>0
   339         -  pParser->yystackEnd = &pParser->yystack[YYSTACKDEPTH-1];
          343  +  yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1];
   340    344   #endif
   341    345   }
   342    346   
   343    347   #ifndef Parse_ENGINEALWAYSONSTACK
   344    348   /* 
   345    349   ** This function allocates a new parser.
   346    350   ** The only argument is a pointer to a function which works like
................................................................................
   349    353   ** Inputs:
   350    354   ** A pointer to the function used to allocate memory.
   351    355   **
   352    356   ** Outputs:
   353    357   ** A pointer to a parser.  This pointer is used in subsequent calls
   354    358   ** to Parse and ParseFree.
   355    359   */
   356         -void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){
   357         -  yyParser *pParser;
   358         -  pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) );
   359         -  if( pParser ) ParseInit(pParser);
   360         -  return pParser;
          360  +void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE) ParseCTX_PDECL){
          361  +  yyParser *yypParser;
          362  +  yypParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) );
          363  +  if( yypParser ){
          364  +    ParseCTX_STORE
          365  +    ParseInit(yypParser ParseCTX_PARAM);
          366  +  }
          367  +  return (void*)yypParser;
   361    368   }
   362    369   #endif /* Parse_ENGINEALWAYSONSTACK */
   363    370   
   364    371   
   365    372   /* The following function deletes the "minor type" or semantic value
   366    373   ** associated with a symbol.  The symbol can be either a terminal
   367    374   ** or nonterminal. "yymajor" is the symbol code, and "yypminor" is
................................................................................
   370    377   ** directives of the input grammar.
   371    378   */
   372    379   static void yy_destructor(
   373    380     yyParser *yypParser,    /* The parser */
   374    381     YYCODETYPE yymajor,     /* Type code for object to destroy */
   375    382     YYMINORTYPE *yypminor   /* The object to be destroyed */
   376    383   ){
   377         -  ParseARG_FETCH;
          384  +  ParseARG_FETCH
          385  +  ParseCTX_FETCH
   378    386     switch( yymajor ){
   379    387       /* Here is inserted the actions which take place when a
   380    388       ** terminal or non-terminal is destroyed.  This can happen
   381    389       ** when the symbol is popped from the stack during a
   382    390       ** reduce or during error processing or when a parser is 
   383    391       ** being destroyed before it is finished parsing.
   384    392       **
................................................................................
   592    600     return yy_action[i];
   593    601   }
   594    602   
   595    603   /*
   596    604   ** The following routine is called if the stack overflows.
   597    605   */
   598    606   static void yyStackOverflow(yyParser *yypParser){
   599         -   ParseARG_FETCH;
          607  +   ParseARG_FETCH
          608  +   ParseCTX_FETCH
   600    609   #ifndef NDEBUG
   601    610      if( yyTraceFILE ){
   602    611        fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
   603    612      }
   604    613   #endif
   605    614      while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
   606    615      /* Here code is inserted which will execute if the parser
   607    616      ** stack every overflows */
   608    617   /******** Begin %stack_overflow code ******************************************/
   609    618   %%
   610    619   /******** End %stack_overflow code ********************************************/
   611         -   ParseARG_STORE; /* Suppress warning about unused %extra_argument var */
          620  +   ParseARG_STORE /* Suppress warning about unused %extra_argument var */
          621  +   ParseCTX_STORE
   612    622   }
   613    623   
   614    624   /*
   615    625   ** Print tracing information for a SHIFT action
   616    626   */
   617    627   #ifndef NDEBUG
   618    628   static void yyTraceShift(yyParser *yypParser, int yyNewState, const char *zTag){
................................................................................
   697    707   ** means that the extra parameters have no performance impact.
   698    708   */
   699    709   static void yy_reduce(
   700    710     yyParser *yypParser,         /* The parser */
   701    711     unsigned int yyruleno,       /* Number of the rule by which to reduce */
   702    712     int yyLookahead,             /* Lookahead token, or YYNOCODE if none */
   703    713     ParseTOKENTYPE yyLookaheadToken  /* Value of the lookahead token */
          714  +  ParseCTX_PDECL                   /* %extra_context */
   704    715   ){
   705    716     int yygoto;                     /* The next state */
   706    717     int yyact;                      /* The next action */
   707    718     yyStackEntry *yymsp;            /* The top of the parser's stack */
   708    719     int yysize;                     /* Amount to pop the stack */
   709         -  ParseARG_FETCH;
          720  +  ParseARG_FETCH
   710    721     (void)yyLookahead;
   711    722     (void)yyLookaheadToken;
   712    723     yymsp = yypParser->yytos;
   713    724   #ifndef NDEBUG
   714    725     if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
   715    726       yysize = yyRuleInfo[yyruleno].nrhs;
   716    727       if( yysize ){
................................................................................
   785    796   /*
   786    797   ** The following code executes when the parse fails
   787    798   */
   788    799   #ifndef YYNOERRORRECOVERY
   789    800   static void yy_parse_failed(
   790    801     yyParser *yypParser           /* The parser */
   791    802   ){
   792         -  ParseARG_FETCH;
          803  +  ParseARG_FETCH
          804  +  ParseCTX_FETCH
   793    805   #ifndef NDEBUG
   794    806     if( yyTraceFILE ){
   795    807       fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
   796    808     }
   797    809   #endif
   798    810     while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
   799    811     /* Here code is inserted which will be executed whenever the
   800    812     ** parser fails */
   801    813   /************ Begin %parse_failure code ***************************************/
   802    814   %%
   803    815   /************ End %parse_failure code *****************************************/
   804         -  ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
          816  +  ParseARG_STORE /* Suppress warning about unused %extra_argument variable */
          817  +  ParseCTX_STORE
   805    818   }
   806    819   #endif /* YYNOERRORRECOVERY */
   807    820   
   808    821   /*
   809    822   ** The following code executes when a syntax error first occurs.
   810    823   */
   811    824   static void yy_syntax_error(
   812    825     yyParser *yypParser,           /* The parser */
   813    826     int yymajor,                   /* The major type of the error token */
   814    827     ParseTOKENTYPE yyminor         /* The minor type of the error token */
   815    828   ){
   816         -  ParseARG_FETCH;
          829  +  ParseARG_FETCH
          830  +  ParseCTX_FETCH
   817    831   #define TOKEN yyminor
   818    832   /************ Begin %syntax_error code ****************************************/
   819    833   %%
   820    834   /************ End %syntax_error code ******************************************/
   821         -  ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
          835  +  ParseARG_STORE /* Suppress warning about unused %extra_argument variable */
          836  +  ParseCTX_STORE
   822    837   }
   823    838   
   824    839   /*
   825    840   ** The following is executed when the parser accepts
   826    841   */
   827    842   static void yy_accept(
   828    843     yyParser *yypParser           /* The parser */
   829    844   ){
   830         -  ParseARG_FETCH;
          845  +  ParseARG_FETCH
          846  +  ParseCTX_FETCH
   831    847   #ifndef NDEBUG
   832    848     if( yyTraceFILE ){
   833    849       fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
   834    850     }
   835    851   #endif
   836    852   #ifndef YYNOERRORRECOVERY
   837    853     yypParser->yyerrcnt = -1;
................................................................................
   838    854   #endif
   839    855     assert( yypParser->yytos==yypParser->yystack );
   840    856     /* Here code is inserted which will be executed whenever the
   841    857     ** parser accepts */
   842    858   /*********** Begin %parse_accept code *****************************************/
   843    859   %%
   844    860   /*********** End %parse_accept code *******************************************/
   845         -  ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
          861  +  ParseARG_STORE /* Suppress warning about unused %extra_argument variable */
          862  +  ParseCTX_STORE
   846    863   }
   847    864   
   848    865   /* The main parser program.
   849    866   ** The first argument is a pointer to a structure obtained from
   850    867   ** "ParseAlloc" which describes the current state of the parser.
   851    868   ** The second argument is the major token number.  The third is
   852    869   ** the minor token.  The fourth optional argument is whatever the
................................................................................
   874    891     unsigned int yyact;   /* The parser action. */
   875    892   #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
   876    893     int yyendofinput;     /* True if we are at the end of input */
   877    894   #endif
   878    895   #ifdef YYERRORSYMBOL
   879    896     int yyerrorhit = 0;   /* True if yymajor has invoked an error */
   880    897   #endif
   881         -  yyParser *yypParser;  /* The parser */
          898  +  yyParser *yypParser = (yyParser*)yyp;  /* The parser */
          899  +  ParseCTX_FETCH
          900  +  ParseARG_STORE
   882    901   
   883         -  yypParser = (yyParser*)yyp;
   884    902     assert( yypParser->yytos!=0 );
   885    903   #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
   886    904     yyendofinput = (yymajor==0);
   887    905   #endif
   888         -  ParseARG_STORE;
   889    906   
   890    907   #ifndef NDEBUG
   891    908     if( yyTraceFILE ){
   892    909       int stateno = yypParser->yytos->stateno;
   893    910       if( stateno < YY_MIN_REDUCE ){
   894    911         fprintf(yyTraceFILE,"%sInput '%s' in state %d\n",
   895    912                 yyTracePrompt,yyTokenName[yymajor],stateno);
................................................................................
   899    916       }
   900    917     }
   901    918   #endif
   902    919   
   903    920     do{
   904    921       yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
   905    922       if( yyact >= YY_MIN_REDUCE ){
   906         -      yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor,yyminor);
          923  +      yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor,yyminor ParseCTX_PARAM);
   907    924       }else if( yyact <= YY_MAX_SHIFTREDUCE ){
   908    925         yy_shift(yypParser,yyact,yymajor,yyminor);
   909    926   #ifndef YYNOERRORRECOVERY
   910    927         yypParser->yyerrcnt--;
   911    928   #endif
   912    929         yymajor = YYNOCODE;
   913    930       }else if( yyact==YY_ACCEPT_ACTION ){