зеркало из https://github.com/mozilla/pjs.git
413 строки
8.2 KiB
C
413 строки
8.2 KiB
C
char rcsid_trim[] = "$Id: trim.c,v 1.1 1998-12-17 06:36:49 fur%netscape.com Exp $";
|
|
|
|
#include <stdio.h>
|
|
#include "b.h"
|
|
#include "fe.h"
|
|
|
|
Relation *allpairs;
|
|
|
|
int trimflag = 0;
|
|
int debugTrim = 0;
|
|
|
|
static void siblings ARGS((int, int));
|
|
static void findAllNexts ARGS((void));
|
|
static Relation *newAllPairs ARGS((void));
|
|
|
|
static void
|
|
siblings(i, j) int i; int j;
|
|
{
|
|
int k;
|
|
List pl;
|
|
DeltaCost Max;
|
|
int foundmax;
|
|
|
|
allpairs[i][j].sibComputed = 1;
|
|
|
|
if (i == 1) {
|
|
return; /* never trim start symbol */
|
|
}
|
|
if (i==j) {
|
|
return;
|
|
}
|
|
|
|
ZEROCOST(Max);
|
|
foundmax = 0;
|
|
|
|
for (k = 1; k < max_nonterminal; k++) {
|
|
DeltaCost tmp;
|
|
|
|
if (k==i || k==j) {
|
|
continue;
|
|
}
|
|
if (!allpairs[k][i].rule) {
|
|
continue;
|
|
}
|
|
if (!allpairs[k][j].rule) {
|
|
return;
|
|
}
|
|
ASSIGNCOST(tmp, allpairs[k][j].chain);
|
|
MINUSCOST(tmp, allpairs[k][i].chain);
|
|
if (foundmax) {
|
|
if (LESSCOST(Max, tmp)) {
|
|
ASSIGNCOST(Max, tmp);
|
|
}
|
|
} else {
|
|
foundmax = 1;
|
|
ASSIGNCOST(Max, tmp);
|
|
}
|
|
}
|
|
|
|
for (pl = rules; pl; pl = pl->next) {
|
|
Rule p = (Rule) pl->x;
|
|
Operator op = p->pat->op;
|
|
List oprule;
|
|
DeltaCost Min;
|
|
int foundmin;
|
|
|
|
if (!op) {
|
|
continue;
|
|
}
|
|
switch (op->arity) {
|
|
case 0:
|
|
continue;
|
|
case 1:
|
|
if (!allpairs[p->pat->children[0]->num ][ i].rule) {
|
|
continue;
|
|
}
|
|
foundmin = 0;
|
|
for (oprule = op->table->rules; oprule; oprule = oprule->next) {
|
|
Rule s = (Rule) oprule->x;
|
|
DeltaPtr Cx;
|
|
DeltaPtr Csj;
|
|
DeltaPtr Cpi;
|
|
DeltaCost tmp;
|
|
|
|
if (!allpairs[p->lhs->num ][ s->lhs->num].rule
|
|
|| !allpairs[s->pat->children[0]->num ][ j].rule) {
|
|
continue;
|
|
}
|
|
Cx = allpairs[p->lhs->num ][ s->lhs->num].chain;
|
|
Csj= allpairs[s->pat->children[0]->num ][ j].chain;
|
|
Cpi= allpairs[p->pat->children[0]->num ][ i].chain;
|
|
ASSIGNCOST(tmp, Cx);
|
|
ADDCOST(tmp, s->delta);
|
|
ADDCOST(tmp, Csj);
|
|
MINUSCOST(tmp, Cpi);
|
|
MINUSCOST(tmp, p->delta);
|
|
if (foundmin) {
|
|
if (LESSCOST(tmp, Min)) {
|
|
ASSIGNCOST(Min, tmp);
|
|
}
|
|
} else {
|
|
foundmin = 1;
|
|
ASSIGNCOST(Min, tmp);
|
|
}
|
|
}
|
|
if (!foundmin) {
|
|
return;
|
|
}
|
|
if (foundmax) {
|
|
if (LESSCOST(Max, Min)) {
|
|
ASSIGNCOST(Max, Min);
|
|
}
|
|
} else {
|
|
foundmax = 1;
|
|
ASSIGNCOST(Max, Min);
|
|
}
|
|
break;
|
|
case 2:
|
|
/* do first dimension */
|
|
if (allpairs[p->pat->children[0]->num ][ i].rule) {
|
|
foundmin = 0;
|
|
for (oprule = op->table->rules; oprule; oprule = oprule->next) {
|
|
Rule s = (Rule) oprule->x;
|
|
DeltaPtr Cx;
|
|
DeltaPtr Cb;
|
|
DeltaPtr Csj;
|
|
DeltaPtr Cpi;
|
|
DeltaCost tmp;
|
|
|
|
if (allpairs[p->lhs->num ][ s->lhs->num].rule
|
|
&& allpairs[s->pat->children[0]->num ][ j].rule
|
|
&& allpairs[s->pat->children[1]->num ][ p->pat->children[1]->num].rule) {
|
|
Cx = allpairs[p->lhs->num ][ s->lhs->num].chain;
|
|
Csj= allpairs[s->pat->children[0]->num ][ j].chain;
|
|
Cpi= allpairs[p->pat->children[0]->num ][ i].chain;
|
|
Cb = allpairs[s->pat->children[1]->num ][ p->pat->children[1]->num].chain;
|
|
ASSIGNCOST(tmp, Cx);
|
|
ADDCOST(tmp, s->delta);
|
|
ADDCOST(tmp, Csj);
|
|
ADDCOST(tmp, Cb);
|
|
MINUSCOST(tmp, Cpi);
|
|
MINUSCOST(tmp, p->delta);
|
|
if (foundmin) {
|
|
if (LESSCOST(tmp, Min)) {
|
|
ASSIGNCOST(Min, tmp);
|
|
}
|
|
} else {
|
|
foundmin = 1;
|
|
ASSIGNCOST(Min, tmp);
|
|
}
|
|
}
|
|
}
|
|
if (!foundmin) {
|
|
return;
|
|
}
|
|
if (foundmax) {
|
|
if (LESSCOST(Max, Min)) {
|
|
ASSIGNCOST(Max, Min);
|
|
}
|
|
} else {
|
|
foundmax = 1;
|
|
ASSIGNCOST(Max, Min);
|
|
}
|
|
}
|
|
/* do second dimension */
|
|
if (allpairs[p->pat->children[1]->num ][ i].rule) {
|
|
foundmin = 0;
|
|
for (oprule = op->table->rules; oprule; oprule = oprule->next) {
|
|
Rule s = (Rule) oprule->x;
|
|
DeltaPtr Cx;
|
|
DeltaPtr Cb;
|
|
DeltaPtr Csj;
|
|
DeltaPtr Cpi;
|
|
DeltaCost tmp;
|
|
|
|
if (allpairs[p->lhs->num ][ s->lhs->num].rule
|
|
&& allpairs[s->pat->children[1]->num ][ j].rule
|
|
&& allpairs[s->pat->children[0]->num ][ p->pat->children[0]->num].rule) {
|
|
Cx = allpairs[p->lhs->num ][ s->lhs->num].chain;
|
|
Csj= allpairs[s->pat->children[1]->num ][ j].chain;
|
|
Cpi= allpairs[p->pat->children[1]->num ][ i].chain;
|
|
Cb = allpairs[s->pat->children[0]->num ][ p->pat->children[0]->num].chain;
|
|
ASSIGNCOST(tmp, Cx);
|
|
ADDCOST(tmp, s->delta);
|
|
ADDCOST(tmp, Csj);
|
|
ADDCOST(tmp, Cb);
|
|
MINUSCOST(tmp, Cpi);
|
|
MINUSCOST(tmp, p->delta);
|
|
if (foundmin) {
|
|
if (LESSCOST(tmp, Min)) {
|
|
ASSIGNCOST(Min, tmp);
|
|
}
|
|
} else {
|
|
foundmin = 1;
|
|
ASSIGNCOST(Min, tmp);
|
|
}
|
|
}
|
|
}
|
|
if (!foundmin) {
|
|
return;
|
|
}
|
|
if (foundmax) {
|
|
if (LESSCOST(Max, Min)) {
|
|
ASSIGNCOST(Max, Min);
|
|
}
|
|
} else {
|
|
foundmax = 1;
|
|
ASSIGNCOST(Max, Min);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
assert(0);
|
|
}
|
|
}
|
|
allpairs[i ][ j].sibFlag = foundmax;
|
|
ASSIGNCOST(allpairs[i ][ j].sibling, Max);
|
|
}
|
|
|
|
static void
|
|
findAllNexts()
|
|
{
|
|
int i,j;
|
|
int last;
|
|
|
|
for (i = 1; i < max_nonterminal; i++) {
|
|
last = 0;
|
|
for (j = 1; j < max_nonterminal; j++) {
|
|
if (allpairs[i ][j].rule) {
|
|
allpairs[i ][ last].nextchain = j;
|
|
last = j;
|
|
}
|
|
}
|
|
}
|
|
/*
|
|
for (i = 1; i < max_nonterminal; i++) {
|
|
last = 0;
|
|
for (j = 1; j < max_nonterminal; j++) {
|
|
if (allpairs[i ][j].sibFlag) {
|
|
allpairs[i ][ last].nextsibling = j;
|
|
last = j;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
static Relation *
|
|
newAllPairs()
|
|
{
|
|
int i;
|
|
Relation *rv;
|
|
|
|
rv = (Relation*) zalloc(max_nonterminal * sizeof(Relation));
|
|
for (i = 0; i < max_nonterminal; i++) {
|
|
rv[i] = (Relation) zalloc(max_nonterminal * sizeof(struct relation));
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
void
|
|
findAllPairs()
|
|
{
|
|
List pl;
|
|
int changes;
|
|
int j;
|
|
|
|
allpairs = newAllPairs();
|
|
for (pl = chainrules; pl; pl = pl->next) {
|
|
Rule p = (Rule) pl->x;
|
|
NonTerminalNum rhs = p->pat->children[0]->num;
|
|
NonTerminalNum lhs = p->lhs->num;
|
|
Relation r = &allpairs[lhs ][ rhs];
|
|
|
|
if (LESSCOST(p->delta, r->chain)) {
|
|
ASSIGNCOST(r->chain, p->delta);
|
|
r->rule = p;
|
|
}
|
|
}
|
|
for (j = 1; j < max_nonterminal; j++) {
|
|
Relation r = &allpairs[j ][ j];
|
|
ZEROCOST(r->chain);
|
|
r->rule = &stub_rule;
|
|
}
|
|
changes = 1;
|
|
while (changes) {
|
|
changes = 0;
|
|
for (pl = chainrules; pl; pl = pl->next) {
|
|
Rule p = (Rule) pl->x;
|
|
NonTerminalNum rhs = p->pat->children[0]->num;
|
|
NonTerminalNum lhs = p->lhs->num;
|
|
int i;
|
|
|
|
for (i = 1; i < max_nonterminal; i++) {
|
|
Relation r = &allpairs[rhs ][ i];
|
|
Relation s = &allpairs[lhs ][ i];
|
|
DeltaCost dc;
|
|
if (!r->rule) {
|
|
continue;
|
|
}
|
|
ASSIGNCOST(dc, p->delta);
|
|
ADDCOST(dc, r->chain);
|
|
if (!s->rule || LESSCOST(dc, s->chain)) {
|
|
s->rule = p;
|
|
ASSIGNCOST(s->chain, dc);
|
|
changes = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
findAllNexts();
|
|
}
|
|
|
|
void
|
|
trim(t) Item_Set t;
|
|
{
|
|
int m,n;
|
|
static short *vec = 0;
|
|
int last;
|
|
|
|
assert(!t->closed);
|
|
debug(debugTrim, printf("Begin Trim\n"));
|
|
debug(debugTrim, dumpItem_Set(t));
|
|
|
|
last = 0;
|
|
if (!vec) {
|
|
vec = (short*) zalloc(max_nonterminal * sizeof(*vec));
|
|
}
|
|
for (m = 1; m < max_nonterminal; m++) {
|
|
if (t->virgin[m].rule) {
|
|
vec[last++] = m;
|
|
}
|
|
}
|
|
for (m = 0; m < last; m++) {
|
|
DeltaCost tmp;
|
|
int j;
|
|
int i;
|
|
|
|
i = vec[m];
|
|
|
|
for (j = allpairs[i ][ 0].nextchain; j; j = allpairs[i ][ j].nextchain) {
|
|
|
|
if (i == j) {
|
|
continue;
|
|
}
|
|
if (!t->virgin[j].rule) {
|
|
continue;
|
|
}
|
|
ASSIGNCOST(tmp, t->virgin[j].delta);
|
|
ADDCOST(tmp, allpairs[i ][ j].chain);
|
|
if (!LESSCOST(t->virgin[i].delta, tmp)) {
|
|
t->virgin[i].rule = 0;
|
|
ZEROCOST(t->virgin[i].delta);
|
|
debug(debugTrim, printf("Trimmed Chain (%d,%d)\n", i,j));
|
|
goto outer;
|
|
}
|
|
|
|
}
|
|
if (!trimflag) {
|
|
continue;
|
|
}
|
|
for (n = 0; n < last; n++) {
|
|
j = vec[n];
|
|
if (i == j) {
|
|
continue;
|
|
}
|
|
|
|
if (!t->virgin[j].rule) {
|
|
continue;
|
|
}
|
|
|
|
if (!allpairs[i][j].sibComputed) {
|
|
siblings(i,j);
|
|
}
|
|
if (!allpairs[i][j].sibFlag) {
|
|
continue;
|
|
}
|
|
ASSIGNCOST(tmp, t->virgin[j].delta);
|
|
ADDCOST(tmp, allpairs[i ][ j].sibling);
|
|
if (!LESSCOST(t->virgin[i].delta, tmp)) {
|
|
t->virgin[i].rule = 0;
|
|
ZEROCOST(t->virgin[i].delta);
|
|
goto outer;
|
|
}
|
|
}
|
|
|
|
outer: ;
|
|
}
|
|
|
|
debug(debugTrim, dumpItem_Set(t));
|
|
debug(debugTrim, printf("End Trim\n"));
|
|
}
|
|
|
|
void
|
|
dumpRelation(r) Relation r;
|
|
{
|
|
printf("{ %d %ld %d %ld }", r->rule->erulenum, (long) r->chain, r->sibFlag, (long) r->sibling);
|
|
}
|
|
|
|
void
|
|
dumpAllPairs()
|
|
{
|
|
int i,j;
|
|
|
|
printf("Dumping AllPairs\n");
|
|
for (i = 1; i < max_nonterminal; i++) {
|
|
for (j = 1; j < max_nonterminal; j++) {
|
|
dumpRelation(&allpairs[i ][j]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|