/ Check-in [3447086c]
Login

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

Overview
Comment:In lemon: coalesce identical destructors. (CVS 5335)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 3447086cd3f6e9b89a8cf61afcf4715977bbf4cd
User & Date: drh 2008-07-01 17:13:57
Context
2008-07-01
17:39
Fix another memory leak related to UNION ALL and sub-selects. (CVS 5336) check-in: 56109b9a user: danielk1977 tags: trunk
17:13
In lemon: coalesce identical destructors. (CVS 5335) check-in: 3447086c user: drh tags: trunk
16:34
In Lemon, if a non-terminal has the same type as a terminal, then reuse the terminal type in the YYMINORTYPE union for the non-terminal. This gives better table compression. (CVS 5334) check-in: 5c9cc22c user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to tool/lemon.c.

   130    130       UNK
   131    131     } assoc;                 /* Associativity if predecence is defined */
   132    132     char *firstset;          /* First-set for all rules of this symbol */
   133    133     Boolean lambda;          /* True if NT and can generate an empty string */
   134    134     int useCnt;              /* Number of times used */
   135    135     char *destructor;        /* Code which executes whenever this symbol is
   136    136                              ** popped from the stack during error processing */
          137  +  int destLineno;          /* Line number for start of destructor */
   137    138     char *datatype;          /* The data type of information held by this
   138    139                              ** object. Only used if type==NONTERMINAL */
   139    140     int dtnum;               /* The data type number.  In the parser, the value
   140    141                              ** stack is a union.  The .yy%d element of this
   141    142                              ** union is the correct data type for this object */
   142    143     /* The following fields are used by MULTITERMINALs only */
   143    144     int nsubsym;             /* Number of constituent symbols in the MULTI */
................................................................................
  1957   1958     int nrhs;                  /* Number of right-hand side symbols seen */
  1958   1959     struct symbol *rhs[MAXRHS];  /* RHS symbols */
  1959   1960     char *alias[MAXRHS];       /* Aliases for each RHS symbol (or NULL) */
  1960   1961     struct rule *prevrule;     /* Previous rule parsed */
  1961   1962     char *declkeyword;         /* Keyword of a declaration */
  1962   1963     char **declargslot;        /* Where the declaration argument should be put */
  1963   1964     int insertLineMacro;       /* Add #line before declaration insert */
         1965  +  int *decllinenoslot;       /* Where to write declaration line number */
  1964   1966     enum e_assoc declassoc;    /* Assign this association to decl arguments */
  1965   1967     int preccounter;           /* Assign this precedence to decl arguments */
  1966   1968     struct rule *firstrule;    /* Pointer to first rule in the grammar */
  1967   1969     struct rule *lastrule;     /* Pointer to the most recently parsed rule */
  1968   1970   };
  1969   1971   
  1970   1972   /* Parse a single token */
................................................................................
  2190   2192           psp->state = RESYNC_AFTER_RULE_ERROR;
  2191   2193         }
  2192   2194         break;
  2193   2195       case WAITING_FOR_DECL_KEYWORD:
  2194   2196         if( isalpha(x[0]) ){
  2195   2197           psp->declkeyword = x;
  2196   2198           psp->declargslot = 0;
         2199  +        psp->decllinenoslot = 0;
  2197   2200           psp->insertLineMacro = 1;
  2198   2201           psp->state = WAITING_FOR_DECL_ARG;
  2199   2202           if( strcmp(x,"name")==0 ){
  2200   2203             psp->declargslot = &(psp->gp->name);
  2201   2204             psp->insertLineMacro = 0;
  2202   2205   	}else if( strcmp(x,"include")==0 ){
  2203   2206             psp->declargslot = &(psp->gp->include);
................................................................................
  2272   2275           ErrorMsg(psp->filename,psp->tokenlineno,
  2273   2276             "Symbol name missing after %destructor keyword");
  2274   2277           psp->errorcnt++;
  2275   2278           psp->state = RESYNC_AFTER_DECL_ERROR;
  2276   2279         }else{
  2277   2280           struct symbol *sp = Symbol_new(x);
  2278   2281           psp->declargslot = &sp->destructor;
         2282  +        psp->decllinenoslot = &sp->destLineno;
  2279   2283           psp->insertLineMacro = 1;
  2280   2284           psp->state = WAITING_FOR_DECL_ARG;
  2281   2285         }
  2282   2286         break;
  2283   2287       case WAITING_FOR_DATATYPE_SYMBOL:
  2284   2288         if( !isalpha(x[0]) ){
  2285   2289           ErrorMsg(psp->filename,psp->tokenlineno,
................................................................................
  2324   2328           if( *psp->declargslot ){
  2325   2329             zOld = *psp->declargslot;
  2326   2330           }else{
  2327   2331             zOld = "";
  2328   2332           }
  2329   2333           nOld = strlen(zOld);
  2330   2334           n = nOld + nNew + 20;
  2331         -        if( psp->insertLineMacro ){
         2335  +        if( psp->insertLineMacro && psp->decllinenoslot
         2336  +            && psp->decllinenoslot[0] ){
  2332   2337             for(z=psp->filename, nBack=0; *z; z++){
  2333   2338               if( *z=='\\' ) nBack++;
  2334   2339             }
  2335   2340             sprintf(zLine, "#line %d ", psp->tokenlineno);
  2336   2341             nLine = strlen(zLine);
  2337   2342             n += nLine + strlen(psp->filename) + nBack;
  2338   2343           }
  2339   2344           *psp->declargslot = zBuf = realloc(*psp->declargslot, n);
  2340   2345           zBuf += nOld;
  2341         -        if( psp->insertLineMacro ){
         2346  +        if( psp->insertLineMacro && psp->decllinenoslot
         2347  +            && psp->decllinenoslot[0] ){
  2342   2348             if( nOld && zBuf[-1]!='\n' ){
  2343   2349               *(zBuf++) = '\n';
  2344   2350             }
  2345   2351             memcpy(zBuf, zLine, nLine);
  2346   2352             zBuf += nLine;
  2347   2353             *(zBuf++) = '"';
  2348   2354             for(z=psp->filename; *z; z++){
................................................................................
  2349   2355               if( *z=='\\' ){
  2350   2356                 *(zBuf++) = '\\';
  2351   2357               }
  2352   2358               *(zBuf++) = *z;
  2353   2359             }
  2354   2360             *(zBuf++) = '"';
  2355   2361             *(zBuf++) = '\n';
         2362  +        }
         2363  +        if( psp->decllinenoslot && psp->decllinenoslot[0]==0 ){
         2364  +          psp->decllinenoslot[0] = psp->tokenlineno;
  2356   2365           }
  2357   2366           memcpy(zBuf, zNew, nNew);
  2358   2367           zBuf += nNew;
  2359   2368           *zBuf = 0;
  2360   2369           psp->state = WAITING_FOR_DECL_OR_RULE;
  2361   2370         }else{
  2362   2371           ErrorMsg(psp->filename,psp->tokenlineno,
................................................................................
  3133   3142    if( sp->type==TERMINAL ){
  3134   3143      cp = lemp->tokendest;
  3135   3144      if( cp==0 ) return;
  3136   3145      fprintf(out,"{\n"); (*lineno)++;
  3137   3146    }else if( sp->destructor ){
  3138   3147      cp = sp->destructor;
  3139   3148      fprintf(out,"{\n"); (*lineno)++;
         3149  +   tplt_linedir(out,sp->destLineno,lemp->outname); (*lineno)++;
  3140   3150    }else if( lemp->vardest ){
  3141   3151      cp = lemp->vardest;
  3142   3152      if( cp==0 ) return;
  3143   3153      fprintf(out,"{\n"); (*lineno)++;
  3144   3154    }else{
  3145   3155      assert( 0 );  /* Cannot happen */
  3146   3156    }
................................................................................
  3829   3839     tplt_xfer(lemp->name,in,out,&lineno);
  3830   3840   
  3831   3841     /* Generate code which executes every time a symbol is popped from
  3832   3842     ** the stack while processing errors or while destroying the parser. 
  3833   3843     ** (In other words, generate the %destructor actions)
  3834   3844     */
  3835   3845     if( lemp->tokendest ){
         3846  +    int once = 1;
  3836   3847       for(i=0; i<lemp->nsymbol; i++){
  3837   3848         struct symbol *sp = lemp->symbols[i];
  3838   3849         if( sp==0 || sp->type!=TERMINAL ) continue;
         3850  +      if( once ){
         3851  +        fprintf(out, "      /* TERMINAL Destructor */\n"); lineno++;
         3852  +        once = 0;
         3853  +      }
  3839   3854         fprintf(out,"    case %d: /* %s */\n",
  3840   3855                 sp->index, sp->name); lineno++;
  3841   3856       }
  3842   3857       for(i=0; i<lemp->nsymbol && lemp->symbols[i]->type!=TERMINAL; i++);
  3843   3858       if( i<lemp->nsymbol ){
  3844   3859         emit_destructor_code(out,lemp->symbols[i],lemp,&lineno);
  3845   3860         fprintf(out,"      break;\n"); lineno++;
  3846   3861       }
  3847   3862     }
  3848   3863     if( lemp->vardest ){
  3849   3864       struct symbol *dflt_sp = 0;
         3865  +    int once = 1;
  3850   3866       for(i=0; i<lemp->nsymbol; i++){
  3851   3867         struct symbol *sp = lemp->symbols[i];
  3852   3868         if( sp==0 || sp->type==TERMINAL ||
  3853   3869             sp->index<=0 || sp->destructor!=0 ) continue;
         3870  +      if( once ){
         3871  +        fprintf(out, "      /* Default NON-TERMINAL Destructor */\n"); lineno++;
         3872  +        once = 0;
         3873  +      }
  3854   3874         fprintf(out,"    case %d: /* %s */\n",
  3855   3875                 sp->index, sp->name); lineno++;
  3856   3876         dflt_sp = sp;
  3857   3877       }
  3858   3878       if( dflt_sp!=0 ){
  3859   3879         emit_destructor_code(out,dflt_sp,lemp,&lineno);
  3860         -      fprintf(out,"      break;\n"); lineno++;
  3861   3880       }
         3881  +    fprintf(out,"      break;\n"); lineno++;
  3862   3882     }
  3863   3883     for(i=0; i<lemp->nsymbol; i++){
  3864   3884       struct symbol *sp = lemp->symbols[i];
  3865   3885       if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue;
  3866   3886       fprintf(out,"    case %d: /* %s */\n",
  3867   3887               sp->index, sp->name); lineno++;
  3868   3888   
................................................................................
  4331   4351       sp->rule = 0;
  4332   4352       sp->fallback = 0;
  4333   4353       sp->prec = -1;
  4334   4354       sp->assoc = UNK;
  4335   4355       sp->firstset = 0;
  4336   4356       sp->lambda = LEMON_FALSE;
  4337   4357       sp->destructor = 0;
         4358  +    sp->destLineno = 0;
  4338   4359       sp->datatype = 0;
  4339   4360       sp->useCnt = 0;
  4340   4361       Symbol_insert(sp,sp->name);
  4341   4362     }
  4342   4363     sp->useCnt++;
  4343   4364     return sp;
  4344   4365   }