Change lemon so that it does not generate yytestcase() macros on destructor
cases since destructors are commonly unreachable in a reasonable grammar.
For the reduce-rule switch, gather all no-ops into the "default:" case. (CVS 6757)

FossilOrigin-Name: caebfe82cb1b1215a85ed48fe97360c5422c52e0
diff --git a/tool/lemon.c b/tool/lemon.c
index 167b136..8336e9a 100644
--- a/tool/lemon.c
+++ b/tool/lemon.c
@@ -3862,12 +3862,9 @@
       if( sp==0 || sp->type!=TERMINAL ) continue;
       if( once ){
         fprintf(out, "      /* TERMINAL Destructor */\n"); lineno++;
-        fprintf(out,"    case %d: /* %s */\n", sp->index, sp->name); lineno++;
         once = 0;
-      }else{
-        fprintf(out,"    case %d: /* %s */ yytestcase(yymajor==%d)\n",
-                sp->index, sp->name, sp->index); lineno++;
       }
+      fprintf(out,"    case %d: /* %s */\n", sp->index, sp->name); lineno++;
     }
     for(i=0; i<lemp->nsymbol && lemp->symbols[i]->type!=TERMINAL; i++);
     if( i<lemp->nsymbol ){
@@ -3884,13 +3881,9 @@
           sp->index<=0 || sp->destructor!=0 ) continue;
       if( once ){
         fprintf(out, "      /* Default NON-TERMINAL Destructor */\n"); lineno++;
-        fprintf(out,"    case %d: /* %s */\n",
-                sp->index, sp->name); lineno++;
         once = 0;
-      }else{
-        fprintf(out,"    case %d: /* %s */ yytestcase(yymajor==%d);\n",
-                sp->index, sp->name, sp->index); lineno++;
       }
+      fprintf(out,"    case %d: /* %s */\n", sp->index, sp->name); lineno++;
       dflt_sp = sp;
     }
     if( dflt_sp!=0 ){
@@ -3909,8 +3902,8 @@
       if( sp2 && sp2->type!=TERMINAL && sp2->destructor
           && sp2->dtnum==sp->dtnum
           && strcmp(sp->destructor,sp2->destructor)==0 ){
-         fprintf(out,"    case %d: /* %s */ yytestcase(yymajor==%d);\n",
-                 sp2->index, sp2->name, sp2->index); lineno++;
+         fprintf(out,"    case %d: /* %s */\n",
+                 sp2->index, sp2->name); lineno++;
          sp2->destructor = 0;
       }
     }
@@ -3938,9 +3931,11 @@
   for(rp=lemp->rule; rp; rp=rp->next){
     translate_code(lemp, rp);
   }
+  /* First output rules other than the default: rule */
   for(rp=lemp->rule; rp; rp=rp->next){
-    struct rule *rp2;
+    struct rule *rp2;               /* Other rules with the same action */
     if( rp->code==0 ) continue;
+    if( rp->code[0]=='\n' && rp->code[1]==0 ) continue; /* Will be default: */
     fprintf(out,"      case %d: /* ", rp->index);
     writeRuleText(out, rp);
     fprintf(out, " */\n"); lineno++;
@@ -3954,7 +3949,19 @@
     }
     emit_code(out,rp,lemp,&lineno);
     fprintf(out,"        break;\n"); lineno++;
+    rp->code = 0;
   }
+  /* Finally, output the default: rule.  We choose as the default: all
+  ** empty actions. */
+  fprintf(out,"      default:\n"); lineno++;
+  for(rp=lemp->rule; rp; rp=rp->next){
+    if( rp->code==0 ) continue;
+    assert( rp->code[0]=='\n' && rp->code[1]==0 );
+    fprintf(out,"      /* (%d) ", rp->index);
+    writeRuleText(out, rp);
+    fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->index); lineno++;
+  }
+  fprintf(out,"        break;\n"); lineno++;
   tplt_xfer(lemp->name,in,out,&lineno);
 
   /* Generate code which executes if a parse fails */