From cafbc8b50aab3353cc19632bed7bca5872d9a8ed Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 20 Mar 2016 09:30:44 -0500 Subject: [PATCH] Lemon update 2009-11-03 13:02:26 on branch trunk - Adjust the lemon implementation so that it always computes the same PDA regardless of qsort() implementation on the host platform. In other words, make all sorts in lemon stable. (user: drh) --- tools/lemon/lemon.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index 026e3f1d9..b22db6977 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -374,6 +374,9 @@ struct action *ap2; if( rc==0 && ap1->type==REDUCE ){ rc = ap1->x.rp->index - ap2->x.rp->index; } + if( rc==0 ){ + rc = ap2 - ap1; + } return rc; } @@ -1591,7 +1594,7 @@ static void *merge(void *a,void *b,int (*cmp)(),size_t offset) }else if( b==0 ){ head = a; }else{ - if( (*cmp)(a,b)<0 ){ + if( (*cmp)(a,b)<=0 ){ ptr = a; a = NEXT(a); }else{ @@ -1600,7 +1603,7 @@ static void *merge(void *a,void *b,int (*cmp)(),size_t offset) } head = ptr; while( a && b ){ - if( (*cmp)(a,b)<0 ){ + if( (*cmp)(a,b)<=0 ){ NEXT(ptr) = a; ptr = a; a = NEXT(a); @@ -1649,7 +1652,7 @@ static void *msort(void *list,void *next,int (*cmp)()) set[i] = ep; } ep = 0; - for(i=0; inAction - p1->nAction; + int c; + c = p2->nAction - p1->nAction; + if( c==0 ){ + c = p2->iOrder - p1->iOrder; + } + assert( c!=0 || p1==p2 ); + return c; } /* @@ -3728,6 +3738,7 @@ int mhflag; /* Output in makeheaders format if true */ ** action table to a minimum, the heuristic of placing the largest action ** sets first is used. */ + for(i=0; instate*2; i++) ax[i].iOrder = i; qsort(ax, lemp->nstate*2, sizeof(ax[0]), axset_compare); pActtab = acttab_alloc(); for(i=0; instate*2 && ax[i].nAction>0; i++){ @@ -4145,7 +4156,11 @@ static int stateResortCompare(const void *a, const void *b){ n = pB->nNtAct - pA->nNtAct; if( n==0 ){ n = pB->nTknAct - pA->nTknAct; + if( n==0 ){ + n = pB->statenum - pA->statenum; + } } + assert( n!=0 ); return n; } @@ -4449,6 +4464,7 @@ char *x; int Symbolcmpp(struct symbol **a, struct symbol **b){ int i1 = (**a).index + 10000000*((**a).name[0]>'Z'); int i2 = (**b).index + 10000000*((**b).name[0]>'Z'); + assert( i1!=i2 || strcmp((**a).name,(**b).name)==0 ); return i1-i2; }