/ Check-in [28215096]
Login

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

Overview
Comment:Enhance lemon so that a @X instead of just X in the code expands to the major token value rather than the minor token value. Use this to make the parser a few hundred bytes smaller. (CVS 1895)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 28215096e0748b5b02776ddb4c964e0161bc0f16
User & Date: drh 2004-08-19 15:12:26
Context
2004-08-20
14:08
Optimizations in the hash table module. (CVS 1896) check-in: d5b0269e user: drh tags: trunk
2004-08-19
15:12
Enhance lemon so that a @X instead of just X in the code expands to the major token value rather than the minor token value. Use this to make the parser a few hundred bytes smaller. (CVS 1895) check-in: 28215096 user: drh tags: trunk
13:29
Add the SQLITE_BUSY_RESERVED_LOCK compile-time option. (CVS 1894) check-in: 25fe7a42 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/parse.y.

    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains SQLite's grammar for SQL.  Process this file
    13     13   ** using the lemon parser generator to generate C code that runs
    14     14   ** the parser.  Lemon will also generate a header file containing
    15     15   ** numeric codes for all of the tokens.
    16     16   **
    17         -** @(#) $Id: parse.y,v 1.132 2004/08/01 00:10:45 drh Exp $
           17  +** @(#) $Id: parse.y,v 1.133 2004/08/19 15:12:26 drh Exp $
    18     18   */
    19     19   %token_prefix TK_
    20     20   %token_type {Token}
    21     21   %default_type {Token}
    22     22   %extra_argument {Parse *pParse}
    23     23   %syntax_error {
    24     24     if( pParse->zErrMsg==0 ){
................................................................................
   534    534   /////////////////////////// Expression Processing /////////////////////////////
   535    535   //
   536    536   
   537    537   %type expr {Expr*}
   538    538   %destructor expr {sqlite3ExprDelete($$);}
   539    539   
   540    540   expr(A) ::= LP(B) expr(X) RP(E). {A = X; sqlite3ExprSpan(A,&B,&E); }
   541         -expr(A) ::= NULL(X).             {A = sqlite3Expr(TK_NULL, 0, 0, &X);}
          541  +expr(A) ::= NULL(X).             {A = sqlite3Expr(@X, 0, 0, &X);}
   542    542   expr(A) ::= ID(X).               {A = sqlite3Expr(TK_ID, 0, 0, &X);}
   543    543   expr(A) ::= JOIN_KW(X).          {A = sqlite3Expr(TK_ID, 0, 0, &X);}
   544    544   expr(A) ::= nm(X) DOT nm(Y). {
   545    545     Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &X);
   546    546     Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &Y);
   547    547     A = sqlite3Expr(TK_DOT, temp1, temp2, 0);
   548    548   }
................................................................................
   549    549   expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). {
   550    550     Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &X);
   551    551     Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &Y);
   552    552     Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &Z);
   553    553     Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0);
   554    554     A = sqlite3Expr(TK_DOT, temp1, temp4, 0);
   555    555   }
   556         -expr(A) ::= INTEGER(X).      {A = sqlite3Expr(TK_INTEGER, 0, 0, &X);}
   557         -expr(A) ::= FLOAT(X).        {A = sqlite3Expr(TK_FLOAT, 0, 0, &X);}
   558         -expr(A) ::= STRING(X).       {A = sqlite3Expr(TK_STRING, 0, 0, &X);}
   559         -expr(A) ::= BLOB(X).         {A = sqlite3Expr(TK_BLOB, 0, 0, &X);}
          556  +expr(A) ::= INTEGER(X).      {A = sqlite3Expr(@X, 0, 0, &X);}
          557  +expr(A) ::= FLOAT(X).        {A = sqlite3Expr(@X, 0, 0, &X);}
          558  +expr(A) ::= STRING(X).       {A = sqlite3Expr(@X, 0, 0, &X);}
          559  +expr(A) ::= BLOB(X).         {A = sqlite3Expr(@X, 0, 0, &X);}
   560    560   expr(A) ::= VARIABLE(X).     {
   561    561     A = sqlite3Expr(TK_VARIABLE, 0, 0, &X);
   562    562     if( A ) A->iTable = ++pParse->nVar;
   563    563   }
   564    564   expr(A) ::= ID(X) LP exprlist(Y) RP(E). {
   565    565     A = sqlite3ExprFunction(Y, &X);
   566    566     sqlite3ExprSpan(A,&X,&E);
   567    567   }
   568    568   expr(A) ::= ID(X) LP STAR RP(E). {
   569    569     A = sqlite3ExprFunction(0, &X);
   570    570     sqlite3ExprSpan(A,&X,&E);
   571    571   }
   572         -expr(A) ::= expr(X) AND expr(Y).   {A = sqlite3Expr(TK_AND, X, Y, 0);}
   573         -expr(A) ::= expr(X) OR expr(Y).    {A = sqlite3Expr(TK_OR, X, Y, 0);}
   574         -expr(A) ::= expr(X) LT expr(Y).    {A = sqlite3Expr(TK_LT, X, Y, 0);}
   575         -expr(A) ::= expr(X) GT expr(Y).    {A = sqlite3Expr(TK_GT, X, Y, 0);}
   576         -expr(A) ::= expr(X) LE expr(Y).    {A = sqlite3Expr(TK_LE, X, Y, 0);}
   577         -expr(A) ::= expr(X) GE expr(Y).    {A = sqlite3Expr(TK_GE, X, Y, 0);}
   578         -expr(A) ::= expr(X) NE expr(Y).    {A = sqlite3Expr(TK_NE, X, Y, 0);}
   579         -expr(A) ::= expr(X) EQ expr(Y).    {A = sqlite3Expr(TK_EQ, X, Y, 0);}
   580         -expr(A) ::= expr(X) BITAND expr(Y). {A = sqlite3Expr(TK_BITAND, X, Y, 0);}
   581         -expr(A) ::= expr(X) BITOR expr(Y).  {A = sqlite3Expr(TK_BITOR, X, Y, 0);}
   582         -expr(A) ::= expr(X) LSHIFT expr(Y). {A = sqlite3Expr(TK_LSHIFT, X, Y, 0);}
   583         -expr(A) ::= expr(X) RSHIFT expr(Y). {A = sqlite3Expr(TK_RSHIFT, X, Y, 0);}
          572  +expr(A) ::= expr(X) AND(OP) expr(Y).    {A = sqlite3Expr(@OP, X, Y, 0);}
          573  +expr(A) ::= expr(X) OR(OP) expr(Y).     {A = sqlite3Expr(@OP, X, Y, 0);}
          574  +expr(A) ::= expr(X) LT(OP) expr(Y).     {A = sqlite3Expr(@OP, X, Y, 0);}
          575  +expr(A) ::= expr(X) GT(OP) expr(Y).     {A = sqlite3Expr(@OP, X, Y, 0);}
          576  +expr(A) ::= expr(X) LE(OP) expr(Y).     {A = sqlite3Expr(@OP, X, Y, 0);}
          577  +expr(A) ::= expr(X) GE(OP) expr(Y).     {A = sqlite3Expr(@OP, X, Y, 0);}
          578  +expr(A) ::= expr(X) NE(OP) expr(Y).     {A = sqlite3Expr(@OP, X, Y, 0);}
          579  +expr(A) ::= expr(X) EQ(OP) expr(Y).     {A = sqlite3Expr(@OP, X, Y, 0);}
          580  +expr(A) ::= expr(X) BITAND(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);}
          581  +expr(A) ::= expr(X) BITOR(OP) expr(Y).  {A = sqlite3Expr(@OP, X, Y, 0);}
          582  +expr(A) ::= expr(X) LSHIFT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);}
          583  +expr(A) ::= expr(X) RSHIFT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);}
   584    584   expr(A) ::= expr(X) likeop(OP) expr(Y).  [LIKE]  {
   585    585     ExprList *pList = sqlite3ExprListAppend(0, Y, 0);
   586    586     pList = sqlite3ExprListAppend(pList, X, 0);
   587    587     A = sqlite3ExprFunction(pList, 0);
   588    588     if( A ) A->op = OP;
   589    589     sqlite3ExprSpan(A, &X->span, &Y->span);
   590    590   }
................................................................................
   595    595     if( A ) A->op = OP;
   596    596     A = sqlite3Expr(TK_NOT, A, 0, 0);
   597    597     sqlite3ExprSpan(A,&X->span,&Y->span);
   598    598   }
   599    599   %type likeop {int}
   600    600   likeop(A) ::= LIKE. {A = TK_LIKE;}
   601    601   likeop(A) ::= GLOB. {A = TK_GLOB;}
   602         -expr(A) ::= expr(X) PLUS expr(Y).  {A = sqlite3Expr(TK_PLUS, X, Y, 0);}
   603         -expr(A) ::= expr(X) MINUS expr(Y). {A = sqlite3Expr(TK_MINUS, X, Y, 0);}
   604         -expr(A) ::= expr(X) STAR expr(Y).  {A = sqlite3Expr(TK_STAR, X, Y, 0);}
   605         -expr(A) ::= expr(X) SLASH expr(Y). {A = sqlite3Expr(TK_SLASH, X, Y, 0);}
   606         -expr(A) ::= expr(X) REM expr(Y).   {A = sqlite3Expr(TK_REM, X, Y, 0);}
   607         -expr(A) ::= expr(X) CONCAT expr(Y). {A = sqlite3Expr(TK_CONCAT, X, Y, 0);}
          602  +expr(A) ::= expr(X) PLUS(OP) expr(Y).   {A = sqlite3Expr(@OP, X, Y, 0);}
          603  +expr(A) ::= expr(X) MINUS(OP) expr(Y).  {A = sqlite3Expr(@OP, X, Y, 0);}
          604  +expr(A) ::= expr(X) STAR(OP) expr(Y).   {A = sqlite3Expr(@OP, X, Y, 0);}
          605  +expr(A) ::= expr(X) SLASH(OP) expr(Y).  {A = sqlite3Expr(@OP, X, Y, 0);}
          606  +expr(A) ::= expr(X) REM(OP) expr(Y).    {A = sqlite3Expr(@OP, X, Y, 0);}
          607  +expr(A) ::= expr(X) CONCAT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);}
   608    608   expr(A) ::= expr(X) ISNULL(E). {
   609    609     A = sqlite3Expr(TK_ISNULL, X, 0, 0);
   610    610     sqlite3ExprSpan(A,&X->span,&E);
   611    611   }
   612    612   expr(A) ::= expr(X) IS NULL(E). {
   613    613     A = sqlite3Expr(TK_ISNULL, X, 0, 0);
   614    614     sqlite3ExprSpan(A,&X->span,&E);
................................................................................
   622    622     sqlite3ExprSpan(A,&X->span,&E);
   623    623   }
   624    624   expr(A) ::= expr(X) IS NOT NULL(E). {
   625    625     A = sqlite3Expr(TK_NOTNULL, X, 0, 0);
   626    626     sqlite3ExprSpan(A,&X->span,&E);
   627    627   }
   628    628   expr(A) ::= NOT(B) expr(X). {
   629         -  A = sqlite3Expr(TK_NOT, X, 0, 0);
          629  +  A = sqlite3Expr(@B, X, 0, 0);
   630    630     sqlite3ExprSpan(A,&B,&X->span);
   631    631   }
   632    632   expr(A) ::= BITNOT(B) expr(X). {
   633         -  A = sqlite3Expr(TK_BITNOT, X, 0, 0);
          633  +  A = sqlite3Expr(@B, X, 0, 0);
   634    634     sqlite3ExprSpan(A,&B,&X->span);
   635    635   }
   636    636   expr(A) ::= MINUS(B) expr(X). [UMINUS] {
   637    637     A = sqlite3Expr(TK_UMINUS, X, 0, 0);
   638    638     sqlite3ExprSpan(A,&B,&X->span);
   639    639   }
   640    640   expr(A) ::= PLUS(B) expr(X). [UPLUS] {

Changes to tool/lemon.c.

  2999   2999     return ret;
  3000   3000   }
  3001   3001   
  3002   3002   /*
  3003   3003   ** Append text to a dynamically allocated string.  If zText is 0 then
  3004   3004   ** reset the string to be empty again.  Always return the complete text
  3005   3005   ** of the string (which is overwritten with each call).
         3006  +**
         3007  +** n bytes of zText are stored.  If n==0 then all of zText up to the first
         3008  +** \000 terminator is stored.  zText can contain up to two instances of
         3009  +** %d.  The values of p1 and p2 are written into the first and second
         3010  +** %d.
         3011  +**
         3012  +** If n==-1, then the previous character is overwritten.
  3006   3013   */
  3007   3014   PRIVATE char *append_str(char *zText, int n, int p1, int p2){
  3008   3015     static char *z = 0;
  3009   3016     static int alloced = 0;
  3010   3017     static int used = 0;
  3011   3018     int i, c;
  3012   3019     char zInt[40];
  3013   3020   
  3014   3021     if( zText==0 ){
  3015   3022       used = 0;
  3016   3023       return z;
  3017   3024     }
  3018         -  if( n<=0 ) n = strlen(zText);
         3025  +  if( n<=0 ){
         3026  +    if( n<0 ){
         3027  +      used += n;
         3028  +      assert( used>=0 );
         3029  +    }
         3030  +    n = strlen(zText);
         3031  +  }
  3019   3032     if( n+sizeof(zInt)*2+used >= alloced ){
  3020   3033       alloced = n + sizeof(zInt)*2 + used + 200;
  3021   3034       z = realloc(z,  alloced);
  3022   3035     }
  3023   3036     if( z==0 ) return "";
  3024   3037     while( n-- > 0 ){
  3025   3038       c = *(zText++);
................................................................................
  3056   3069     for(cp=rp->code; *cp; cp++){
  3057   3070       if( isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_')) ){
  3058   3071         char saved;
  3059   3072         for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++);
  3060   3073         saved = *xp;
  3061   3074         *xp = 0;
  3062   3075         if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){
  3063         -        append_str("yygotominor.yy%d",-1,rp->lhs->dtnum,0);
         3076  +        append_str("yygotominor.yy%d",0,rp->lhs->dtnum,0);
  3064   3077           cp = xp;
  3065   3078           lhsused = 1;
  3066   3079         }else{
  3067   3080           for(i=0; i<rp->nrhs; i++){
  3068   3081             if( rp->rhsalias[i] && strcmp(cp,rp->rhsalias[i])==0 ){
  3069         -            append_str("yymsp[%d].minor.yy%d",-1,
  3070         -                       i-rp->nrhs+1,rp->rhs[i]->dtnum);
         3082  +            if( cp!=rp->code && cp[-1]=='@' ){
         3083  +              /* If the argument is of the form @X then substituted
         3084  +              ** the token number of X, not the value of X */
         3085  +              append_str("yymsp[%d].major",-1,i-rp->nrhs+1,0);
         3086  +            }else{
         3087  +              append_str("yymsp[%d].minor.yy%d",0,
         3088  +                         i-rp->nrhs+1,rp->rhs[i]->dtnum);
         3089  +            }
  3071   3090               cp = xp;
  3072   3091               used[i] = 1;
  3073   3092               break;
  3074   3093             }
  3075   3094           }
  3076   3095         }
  3077   3096         *xp = saved;
................................................................................
  3093   3112       if( rp->rhsalias[i] && !used[i] ){
  3094   3113         ErrorMsg(lemp->filename,rp->ruleline,
  3095   3114           "Label %s for \"%s(%s)\" is never used.",
  3096   3115           rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]);
  3097   3116         lemp->errorcnt++;
  3098   3117       }else if( rp->rhsalias[i]==0 ){
  3099   3118         if( has_destructor(rp->rhs[i],lemp) ){
  3100         -        append_str("  yy_destructor(%d,&yymsp[%d].minor);\n", -1,
         3119  +        append_str("  yy_destructor(%d,&yymsp[%d].minor);\n", 0,
  3101   3120              rp->rhs[i]->index,i-rp->nrhs+1);
  3102   3121         }else{
  3103   3122           /* No destructor defined for this term */
  3104   3123         }
  3105   3124       }
  3106   3125     }
  3107   3126     cp = append_str(0,0,0,0);