-C Avoid\sa\sfew\sunnecessary\sfstat()s\son\sjournal\sfiles.
-D 2016-03-16T19:10:46.537
+C Enhance\sLemon\sso\sthat\sit\sreorders\sthe\sreduce\srules\ssuch\sthat\srules\swithout\nactions\soccur\sat\sthe\send\sand\sso\sthat\sthe\sfirst\srule\sis\snumber\s0.\s\sThis\nreduces\sthe\ssize\sof\sthe\sjump\stable\son\sthe\sreduce\sswitch,\sand\shelps\sthe\sparser\nto\srun\sfaster.
+D 2016-03-16T19:45:54.638
F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
-F tool/lemon.c 251f5c3f21b553240cbdd42dd187a51bb2372cd3
-F tool/lempar.c d5114c7d13aa3af1e27ff3d02e4dea6eadec7ddf
+F tool/lemon.c cfbfe061a4b2766512f6b484882eee2c86a14506
+F tool/lempar.c 404ea3dc27dbeed343f0e61b1d36e97b9f5f0fb6
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 96ea9909429f0b3b4a67002e8340ae3f7dc0b73f f3c0579e931799088e9a83757e25bae229120697
-R 2179dd350d027a0023ff0b4d274ede19
-T +closed f3c0579e931799088e9a83757e25bae229120697
+P dbf84705913c0845ca4e75eb30c91536c754efeb
+R 864f536bc3cc564acb40b05c95555e64
U drh
-Z 6f4affaf464559d5d4fad621b1dda7eb
+Z 3c44460af79cebe8997bb55087f66950
const char *codeSuffix; /* Breakdown code after code[] above */
struct symbol *precsym; /* Precedence symbol for this rule */
int index; /* An index number for this rule */
+ int iRule; /* Rule number as used in the generated tables */
Boolean canReduce; /* True if this rule is ever reduced */
struct rule *nextlhs; /* Next rule with the same LHS */
struct rule *next; /* Next rule in the global list */
struct lemon {
struct state **sorted; /* Table of states sorted by state number */
struct rule *rule; /* List of all rules */
+ struct rule *startRule; /* First rule */
int nstate; /* Number of states */
int nxstate; /* nstate with tail degenerate states removed */
int nrule; /* Number of rules */
ErrorMsg(lemp->filename,0,
"The specified start symbol \"%s\" is not \
in a nonterminal of the grammar. \"%s\" will be used as the start \
-symbol instead.",lemp->start,lemp->rule->lhs->name);
+symbol instead.",lemp->start,lemp->startRule->lhs->name);
lemp->errorcnt++;
- sp = lemp->rule->lhs;
+ sp = lemp->startRule->lhs;
}
}else{
- sp = lemp->rule->lhs;
+ sp = lemp->startRule->lhs;
}
/* Make sure the start symbol doesn't occur on the right-hand side of
/* Add the accepting token */
if( lemp->start ){
sp = Symbol_find(lemp->start);
- if( sp==0 ) sp = lemp->rule->lhs;
+ if( sp==0 ) sp = lemp->startRule->lhs;
}else{
- sp = lemp->rule->lhs;
+ sp = lemp->startRule->lhs;
}
/* Add to the first state (which is always the starting state of the
** finite state machine) an action to ACCEPT if the lookahead is the
lemon_strcpy(user_templatename, z);
}
+/* Merge together to lists of rules order by rule.iRule */
+static struct rule *Rule_merge(struct rule *pA, struct rule *pB){
+ struct rule *pFirst = 0;
+ struct rule **ppPrev = &pFirst;
+ while( pA && pB ){
+ if( pA->iRule<pB->iRule ){
+ *ppPrev = pA;
+ ppPrev = &pA->next;
+ pA = pA->next;
+ }else{
+ *ppPrev = pB;
+ ppPrev = &pB->next;
+ pB = pB->next;
+ }
+ }
+ if( pA ){
+ *ppPrev = pA;
+ }else{
+ *ppPrev = pB;
+ }
+ return pFirst;
+}
+
+/*
+** Sort a list of rules in order of increasing iRule value
+*/
+static struct rule *Rule_sort(struct rule *rp){
+ int i;
+ struct rule *pNext;
+ struct rule *x[32];
+ memset(x, 0, sizeof(x));
+ while( rp ){
+ pNext = rp->next;
+ rp->next = 0;
+ for(i=0; i<sizeof(x)/sizeof(x[0]) && x[i]; i++){
+ rp = Rule_merge(x[i], rp);
+ x[i] = 0;
+ }
+ x[i] = rp;
+ rp = pNext;
+ }
+ rp = 0;
+ for(i=0; i<sizeof(x)/sizeof(x[0]); i++){
+ rp = Rule_merge(x[i], rp);
+ }
+ return rp;
+}
+
/* forward reference */
static const char *minimum_size_type(int lwr, int upr, int *pnByte);
int i;
int exitcode;
struct lemon lem;
+ struct rule *rp;
OptInit(argv,options,stderr);
if( version ){
for(i=1; ISUPPER(lem.symbols[i]->name[0]); i++);
lem.nterminal = i;
+ /* Assign sequential rule numbers */
+ for(i=0, rp=lem.rule; rp; rp=rp->next){
+ rp->iRule = rp->code ? i++ : -1;
+ }
+ for(rp=lem.rule; rp; rp=rp->next){
+ if( rp->iRule<0 ) rp->iRule = i++;
+ }
+ lem.startRule = lem.rule;
+ lem.rule = Rule_sort(lem.rule);
+
/* Generate a reprint of the grammar, if requested on the command line */
if( rpflag ){
Reprint(&lem);
}
case REDUCE: {
struct rule *rp = ap->x.rp;
- fprintf(fp,"%*s reduce %-7d",indent,ap->sp->name,rp->index);
+ fprintf(fp,"%*s reduce %-7d",indent,ap->sp->name,rp->iRule);
RulePrint(fp, rp, -1);
break;
}
case SHIFTREDUCE: {
struct rule *rp = ap->x.rp;
- fprintf(fp,"%*s shift-reduce %-7d",indent,ap->sp->name,rp->index);
+ fprintf(fp,"%*s shift-reduce %-7d",indent,ap->sp->name,rp->iRule);
RulePrint(fp, rp, -1);
break;
}
case SRCONFLICT:
case RRCONFLICT:
fprintf(fp,"%*s reduce %-7d ** Parsing conflict **",
- indent,ap->sp->name,ap->x.rp->index);
+ indent,ap->sp->name,ap->x.rp->iRule);
break;
case SSCONFLICT:
fprintf(fp,"%*s shift %-7d ** Parsing conflict **",
case RD_RESOLVED:
if( showPrecedenceConflict ){
fprintf(fp,"%*s reduce %-7d -- dropped by precedence",
- indent,ap->sp->name,ap->x.rp->index);
+ indent,ap->sp->name,ap->x.rp->iRule);
}else{
result = 0;
}
while( cfp ){
char buf[20];
if( cfp->dot==cfp->rp->nrhs ){
- lemon_sprintf(buf,"(%d)",cfp->rp->index);
+ lemon_sprintf(buf,"(%d)",cfp->rp->iRule);
fprintf(fp," %5s ",buf);
}else{
fprintf(fp," ");
int act;
switch( ap->type ){
case SHIFT: act = ap->x.stp->statenum; break;
- case SHIFTREDUCE: act = ap->x.rp->index + lemp->nstate; break;
- case REDUCE: act = ap->x.rp->index + lemp->nstate+lemp->nrule; break;
+ case SHIFTREDUCE: act = ap->x.rp->iRule + lemp->nstate; break;
+ case REDUCE: act = ap->x.rp->iRule + lemp->nstate+lemp->nrule; break;
case ERROR: act = lemp->nstate + lemp->nrule*2; break;
case ACCEPT: act = lemp->nstate + lemp->nrule*2 + 1; break;
default: act = -1; break;
** when tracing REDUCE actions.
*/
for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){
- assert( rp->index==i );
+ assert( rp->iRule==i );
fprintf(out," /* %3d */ \"", i);
writeRuleText(out, rp);
fprintf(out,"\",\n"); lineno++;
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);
+ fprintf(out," case %d: /* ", rp->iRule);
writeRuleText(out, rp);
fprintf(out, " */\n"); lineno++;
for(rp2=rp->next; rp2; rp2=rp2->next){
if( rp2->code==rp->code ){
- fprintf(out," case %d: /* ", rp2->index);
+ fprintf(out," case %d: /* ", rp2->iRule);
writeRuleText(out, rp2);
- fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->index); lineno++;
+ fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->iRule); lineno++;
rp2->code = 0;
}
}
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);
+ fprintf(out," /* (%d) ", rp->iRule);
writeRuleText(out, rp);
- fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->index); lineno++;
+ fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++;
}
fprintf(out," break;\n"); lineno++;
tplt_xfer(lemp->name,in,out,&lineno);
** Find the appropriate action for a parser given the terminal
** look-ahead token iLookAhead.
*/
-static int yy_find_shift_action(
+static unsigned int yy_find_shift_action(
yyParser *pParser, /* The parser */
YYCODETYPE iLookAhead /* The look-ahead token */
){
*/
static void yy_reduce(
yyParser *yypParser, /* The parser */
- int yyruleno /* Number of the rule by which to reduce */
+ unsigned int yyruleno /* Number of the rule by which to reduce */
){
int yygoto; /* The next state */
int yyact; /* The next action */
ParseARG_FETCH;
yymsp = &yypParser->yystack[yypParser->yyidx];
#ifndef NDEBUG
- if( yyTraceFILE && yyruleno>=0
- && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
+ if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
yysize = yyRuleInfo[yyruleno].nrhs;
fprintf(yyTraceFILE, "%sReduce [%s], go to state %d.\n", yyTracePrompt,
yyRuleName[yyruleno], yymsp[-yysize].stateno);
%%
/********** End reduce actions ************************************************/
};
- assert( yyruleno>=0 && yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
+ assert( yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
yygoto = yyRuleInfo[yyruleno].lhs;
yysize = yyRuleInfo[yyruleno].nrhs;
yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
ParseARG_PDECL /* Optional %extra_argument parameter */
){
YYMINORTYPE yyminorunion;
- int yyact; /* The parser action. */
+ unsigned int yyact; /* The parser action. */
#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
int yyendofinput; /* True if we are at the end of input */
#endif