Home | History | Annotate | Line # | Download | only in dist
lalr.c revision 1.1.1.1
      1 /*	$NetBSD: lalr.c,v 1.1.1.1 2009/10/29 00:46:53 christos Exp $	*/
      2 
      3 /* Id: lalr.c,v 1.9 2009/10/27 09:49:27 tom Exp */
      4 
      5 #include "defs.h"
      6 
      7 typedef struct shorts
      8 {
      9     struct shorts *next;
     10     Value_t value;
     11 }
     12 shorts;
     13 
     14 static Value_t map_goto(int state, int symbol);
     15 static Value_t **transpose(Value_t ** R, int n);
     16 static void add_lookback_edge(int stateno, int ruleno, int gotono);
     17 static void build_relations(void);
     18 static void compute_FOLLOWS(void);
     19 static void compute_lookaheads(void);
     20 static void digraph(Value_t ** relation);
     21 static void initialize_F(void);
     22 static void initialize_LA(void);
     23 static void set_accessing_symbol(void);
     24 static void set_goto_map(void);
     25 static void set_maxrhs(void);
     26 static void set_reduction_table(void);
     27 static void set_shift_table(void);
     28 static void set_state_table(void);
     29 static void traverse(int i);
     30 
     31 static int tokensetsize;
     32 Value_t *lookaheads;
     33 Value_t *LAruleno;
     34 unsigned *LA;
     35 Value_t *accessing_symbol;
     36 core **state_table;
     37 shifts **shift_table;
     38 reductions **reduction_table;
     39 Value_t *goto_map;
     40 Value_t *from_state;
     41 Value_t *to_state;
     42 
     43 static Value_t infinity;
     44 static int maxrhs;
     45 static int ngotos;
     46 static unsigned *F;
     47 static Value_t **includes;
     48 static shorts **lookback;
     49 static Value_t **R;
     50 static Value_t *INDEX;
     51 static Value_t *VERTICES;
     52 static Value_t top;
     53 
     54 void
     55 lalr(void)
     56 {
     57     tokensetsize = WORDSIZE(ntokens);
     58 
     59     set_state_table();
     60     set_accessing_symbol();
     61     set_shift_table();
     62     set_reduction_table();
     63     set_maxrhs();
     64     initialize_LA();
     65     set_goto_map();
     66     initialize_F();
     67     build_relations();
     68     compute_FOLLOWS();
     69     compute_lookaheads();
     70 }
     71 
     72 static void
     73 set_state_table(void)
     74 {
     75     core *sp;
     76 
     77     state_table = NEW2(nstates, core *);
     78     for (sp = first_state; sp; sp = sp->next)
     79 	state_table[sp->number] = sp;
     80 }
     81 
     82 static void
     83 set_accessing_symbol(void)
     84 {
     85     core *sp;
     86 
     87     accessing_symbol = NEW2(nstates, Value_t);
     88     for (sp = first_state; sp; sp = sp->next)
     89 	accessing_symbol[sp->number] = sp->accessing_symbol;
     90 }
     91 
     92 static void
     93 set_shift_table(void)
     94 {
     95     shifts *sp;
     96 
     97     shift_table = NEW2(nstates, shifts *);
     98     for (sp = first_shift; sp; sp = sp->next)
     99 	shift_table[sp->number] = sp;
    100 }
    101 
    102 static void
    103 set_reduction_table(void)
    104 {
    105     reductions *rp;
    106 
    107     reduction_table = NEW2(nstates, reductions *);
    108     for (rp = first_reduction; rp; rp = rp->next)
    109 	reduction_table[rp->number] = rp;
    110 }
    111 
    112 static void
    113 set_maxrhs(void)
    114 {
    115     Value_t *itemp;
    116     Value_t *item_end;
    117     int length;
    118     int max;
    119 
    120     length = 0;
    121     max = 0;
    122     item_end = ritem + nitems;
    123     for (itemp = ritem; itemp < item_end; itemp++)
    124     {
    125 	if (*itemp >= 0)
    126 	{
    127 	    length++;
    128 	}
    129 	else
    130 	{
    131 	    if (length > max)
    132 		max = length;
    133 	    length = 0;
    134 	}
    135     }
    136 
    137     maxrhs = max;
    138 }
    139 
    140 static void
    141 initialize_LA(void)
    142 {
    143     int i, j, k;
    144     reductions *rp;
    145 
    146     lookaheads = NEW2(nstates + 1, Value_t);
    147 
    148     k = 0;
    149     for (i = 0; i < nstates; i++)
    150     {
    151 	lookaheads[i] = (Value_t) k;
    152 	rp = reduction_table[i];
    153 	if (rp)
    154 	    k += rp->nreds;
    155     }
    156     lookaheads[nstates] = (Value_t) k;
    157 
    158     LA = NEW2(k * tokensetsize, unsigned);
    159     LAruleno = NEW2(k, Value_t);
    160     lookback = NEW2(k, shorts *);
    161 
    162     k = 0;
    163     for (i = 0; i < nstates; i++)
    164     {
    165 	rp = reduction_table[i];
    166 	if (rp)
    167 	{
    168 	    for (j = 0; j < rp->nreds; j++)
    169 	    {
    170 		LAruleno[k] = rp->rules[j];
    171 		k++;
    172 	    }
    173 	}
    174     }
    175 }
    176 
    177 static void
    178 set_goto_map(void)
    179 {
    180     shifts *sp;
    181     int i;
    182     int symbol;
    183     int k;
    184     Value_t *temp_map;
    185     Value_t state2;
    186     Value_t state1;
    187 
    188     goto_map = NEW2(nvars + 1, Value_t) - ntokens;
    189     temp_map = NEW2(nvars + 1, Value_t) - ntokens;
    190 
    191     ngotos = 0;
    192     for (sp = first_shift; sp; sp = sp->next)
    193     {
    194 	for (i = sp->nshifts - 1; i >= 0; i--)
    195 	{
    196 	    symbol = accessing_symbol[sp->shift[i]];
    197 
    198 	    if (ISTOKEN(symbol))
    199 		break;
    200 
    201 	    if (ngotos == MAXSHORT)
    202 		fatal("too many gotos");
    203 
    204 	    ngotos++;
    205 	    goto_map[symbol]++;
    206 	}
    207     }
    208 
    209     k = 0;
    210     for (i = ntokens; i < nsyms; i++)
    211     {
    212 	temp_map[i] = (Value_t) k;
    213 	k += goto_map[i];
    214     }
    215 
    216     for (i = ntokens; i < nsyms; i++)
    217 	goto_map[i] = temp_map[i];
    218 
    219     goto_map[nsyms] = (Value_t) ngotos;
    220     temp_map[nsyms] = (Value_t) ngotos;
    221 
    222     from_state = NEW2(ngotos, Value_t);
    223     to_state = NEW2(ngotos, Value_t);
    224 
    225     for (sp = first_shift; sp; sp = sp->next)
    226     {
    227 	state1 = sp->number;
    228 	for (i = sp->nshifts - 1; i >= 0; i--)
    229 	{
    230 	    state2 = sp->shift[i];
    231 	    symbol = accessing_symbol[state2];
    232 
    233 	    if (ISTOKEN(symbol))
    234 		break;
    235 
    236 	    k = temp_map[symbol]++;
    237 	    from_state[k] = state1;
    238 	    to_state[k] = state2;
    239 	}
    240     }
    241 
    242     FREE(temp_map + ntokens);
    243 }
    244 
    245 /*  Map_goto maps a state/symbol pair into its numeric representation.	*/
    246 
    247 static Value_t
    248 map_goto(int state, int symbol)
    249 {
    250     int high;
    251     int low;
    252     int middle;
    253     int s;
    254 
    255     low = goto_map[symbol];
    256     high = goto_map[symbol + 1];
    257 
    258     for (;;)
    259     {
    260 	assert(low <= high);
    261 	middle = (low + high) >> 1;
    262 	s = from_state[middle];
    263 	if (s == state)
    264 	    return (Value_t) (middle);
    265 	else if (s < state)
    266 	    low = middle + 1;
    267 	else
    268 	    high = middle - 1;
    269     }
    270 }
    271 
    272 static void
    273 initialize_F(void)
    274 {
    275     int i;
    276     int j;
    277     int k;
    278     shifts *sp;
    279     Value_t *edge;
    280     unsigned *rowp;
    281     Value_t *rp;
    282     Value_t **reads;
    283     int nedges;
    284     int stateno;
    285     int symbol;
    286     int nwords;
    287 
    288     nwords = ngotos * tokensetsize;
    289     F = NEW2(nwords, unsigned);
    290 
    291     reads = NEW2(ngotos, Value_t *);
    292     edge = NEW2(ngotos + 1, Value_t);
    293     nedges = 0;
    294 
    295     rowp = F;
    296     for (i = 0; i < ngotos; i++)
    297     {
    298 	stateno = to_state[i];
    299 	sp = shift_table[stateno];
    300 
    301 	if (sp)
    302 	{
    303 	    k = sp->nshifts;
    304 
    305 	    for (j = 0; j < k; j++)
    306 	    {
    307 		symbol = accessing_symbol[sp->shift[j]];
    308 		if (ISVAR(symbol))
    309 		    break;
    310 		SETBIT(rowp, symbol);
    311 	    }
    312 
    313 	    for (; j < k; j++)
    314 	    {
    315 		symbol = accessing_symbol[sp->shift[j]];
    316 		if (nullable[symbol])
    317 		    edge[nedges++] = map_goto(stateno, symbol);
    318 	    }
    319 
    320 	    if (nedges)
    321 	    {
    322 		reads[i] = rp = NEW2(nedges + 1, Value_t);
    323 
    324 		for (j = 0; j < nedges; j++)
    325 		    rp[j] = edge[j];
    326 
    327 		rp[nedges] = -1;
    328 		nedges = 0;
    329 	    }
    330 	}
    331 
    332 	rowp += tokensetsize;
    333     }
    334 
    335     SETBIT(F, 0);
    336     digraph(reads);
    337 
    338     for (i = 0; i < ngotos; i++)
    339     {
    340 	if (reads[i])
    341 	    FREE(reads[i]);
    342     }
    343 
    344     FREE(reads);
    345     FREE(edge);
    346 }
    347 
    348 static void
    349 build_relations(void)
    350 {
    351     int i;
    352     int j;
    353     int k;
    354     Value_t *rulep;
    355     Value_t *rp;
    356     shifts *sp;
    357     int length;
    358     int nedges;
    359     int done_flag;
    360     Value_t state1;
    361     Value_t stateno;
    362     int symbol1;
    363     int symbol2;
    364     Value_t *shortp;
    365     Value_t *edge;
    366     Value_t *states;
    367     Value_t **new_includes;
    368 
    369     includes = NEW2(ngotos, Value_t *);
    370     edge = NEW2(ngotos + 1, Value_t);
    371     states = NEW2(maxrhs + 1, Value_t);
    372 
    373     for (i = 0; i < ngotos; i++)
    374     {
    375 	nedges = 0;
    376 	state1 = from_state[i];
    377 	symbol1 = accessing_symbol[to_state[i]];
    378 
    379 	for (rulep = derives[symbol1]; *rulep >= 0; rulep++)
    380 	{
    381 	    length = 1;
    382 	    states[0] = state1;
    383 	    stateno = state1;
    384 
    385 	    for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++)
    386 	    {
    387 		symbol2 = *rp;
    388 		sp = shift_table[stateno];
    389 		k = sp->nshifts;
    390 
    391 		for (j = 0; j < k; j++)
    392 		{
    393 		    stateno = sp->shift[j];
    394 		    if (accessing_symbol[stateno] == symbol2)
    395 			break;
    396 		}
    397 
    398 		states[length++] = stateno;
    399 	    }
    400 
    401 	    add_lookback_edge(stateno, *rulep, i);
    402 
    403 	    length--;
    404 	    done_flag = 0;
    405 	    while (!done_flag)
    406 	    {
    407 		done_flag = 1;
    408 		rp--;
    409 		if (ISVAR(*rp))
    410 		{
    411 		    stateno = states[--length];
    412 		    edge[nedges++] = map_goto(stateno, *rp);
    413 		    if (nullable[*rp] && length > 0)
    414 			done_flag = 0;
    415 		}
    416 	    }
    417 	}
    418 
    419 	if (nedges)
    420 	{
    421 	    includes[i] = shortp = NEW2(nedges + 1, Value_t);
    422 	    for (j = 0; j < nedges; j++)
    423 		shortp[j] = edge[j];
    424 	    shortp[nedges] = -1;
    425 	}
    426     }
    427 
    428     new_includes = transpose(includes, ngotos);
    429 
    430     for (i = 0; i < ngotos; i++)
    431 	if (includes[i])
    432 	    FREE(includes[i]);
    433 
    434     FREE(includes);
    435 
    436     includes = new_includes;
    437 
    438     FREE(edge);
    439     FREE(states);
    440 }
    441 
    442 static void
    443 add_lookback_edge(int stateno, int ruleno, int gotono)
    444 {
    445     int i, k;
    446     int found;
    447     shorts *sp;
    448 
    449     i = lookaheads[stateno];
    450     k = lookaheads[stateno + 1];
    451     found = 0;
    452     while (!found && i < k)
    453     {
    454 	if (LAruleno[i] == ruleno)
    455 	    found = 1;
    456 	else
    457 	    ++i;
    458     }
    459     assert(found);
    460 
    461     sp = NEW(shorts);
    462     sp->next = lookback[i];
    463     sp->value = (Value_t) gotono;
    464     lookback[i] = sp;
    465 }
    466 
    467 static Value_t **
    468 transpose(Value_t ** R2, int n)
    469 {
    470     Value_t **new_R;
    471     Value_t **temp_R;
    472     Value_t *nedges;
    473     Value_t *sp;
    474     int i;
    475     int k;
    476 
    477     nedges = NEW2(n, Value_t);
    478 
    479     for (i = 0; i < n; i++)
    480     {
    481 	sp = R2[i];
    482 	if (sp)
    483 	{
    484 	    while (*sp >= 0)
    485 		nedges[*sp++]++;
    486 	}
    487     }
    488 
    489     new_R = NEW2(n, Value_t *);
    490     temp_R = NEW2(n, Value_t *);
    491 
    492     for (i = 0; i < n; i++)
    493     {
    494 	k = nedges[i];
    495 	if (k > 0)
    496 	{
    497 	    sp = NEW2(k + 1, Value_t);
    498 	    new_R[i] = sp;
    499 	    temp_R[i] = sp;
    500 	    sp[k] = -1;
    501 	}
    502     }
    503 
    504     FREE(nedges);
    505 
    506     for (i = 0; i < n; i++)
    507     {
    508 	sp = R2[i];
    509 	if (sp)
    510 	{
    511 	    while (*sp >= 0)
    512 		*temp_R[*sp++]++ = (Value_t) i;
    513 	}
    514     }
    515 
    516     FREE(temp_R);
    517 
    518     return (new_R);
    519 }
    520 
    521 static void
    522 compute_FOLLOWS(void)
    523 {
    524     digraph(includes);
    525 }
    526 
    527 static void
    528 compute_lookaheads(void)
    529 {
    530     int i, n;
    531     unsigned *fp1, *fp2, *fp3;
    532     shorts *sp, *next;
    533     unsigned *rowp;
    534 
    535     rowp = LA;
    536     n = lookaheads[nstates];
    537     for (i = 0; i < n; i++)
    538     {
    539 	fp3 = rowp + tokensetsize;
    540 	for (sp = lookback[i]; sp; sp = sp->next)
    541 	{
    542 	    fp1 = rowp;
    543 	    fp2 = F + tokensetsize * sp->value;
    544 	    while (fp1 < fp3)
    545 		*fp1++ |= *fp2++;
    546 	}
    547 	rowp = fp3;
    548     }
    549 
    550     for (i = 0; i < n; i++)
    551 	for (sp = lookback[i]; sp; sp = next)
    552 	{
    553 	    next = sp->next;
    554 	    FREE(sp);
    555 	}
    556 
    557     FREE(lookback);
    558     FREE(F);
    559 }
    560 
    561 static void
    562 digraph(Value_t ** relation)
    563 {
    564     int i;
    565 
    566     infinity = (Value_t) (ngotos + 2);
    567     INDEX = NEW2(ngotos + 1, Value_t);
    568     VERTICES = NEW2(ngotos + 1, Value_t);
    569     top = 0;
    570 
    571     R = relation;
    572 
    573     for (i = 0; i < ngotos; i++)
    574 	INDEX[i] = 0;
    575 
    576     for (i = 0; i < ngotos; i++)
    577     {
    578 	if (INDEX[i] == 0 && R[i])
    579 	    traverse(i);
    580     }
    581 
    582     FREE(INDEX);
    583     FREE(VERTICES);
    584 }
    585 
    586 static void
    587 traverse(int i)
    588 {
    589     unsigned *fp1;
    590     unsigned *fp2;
    591     unsigned *fp3;
    592     int j;
    593     Value_t *rp;
    594 
    595     Value_t height;
    596     unsigned *base;
    597 
    598     VERTICES[++top] = (Value_t) i;
    599     INDEX[i] = height = top;
    600 
    601     base = F + i * tokensetsize;
    602     fp3 = base + tokensetsize;
    603 
    604     rp = R[i];
    605     if (rp)
    606     {
    607 	while ((j = *rp++) >= 0)
    608 	{
    609 	    if (INDEX[j] == 0)
    610 		traverse(j);
    611 
    612 	    if (INDEX[i] > INDEX[j])
    613 		INDEX[i] = INDEX[j];
    614 
    615 	    fp1 = base;
    616 	    fp2 = F + j * tokensetsize;
    617 
    618 	    while (fp1 < fp3)
    619 		*fp1++ |= *fp2++;
    620 	}
    621     }
    622 
    623     if (INDEX[i] == height)
    624     {
    625 	for (;;)
    626 	{
    627 	    j = VERTICES[top--];
    628 	    INDEX[j] = infinity;
    629 
    630 	    if (i == j)
    631 		break;
    632 
    633 	    fp1 = base;
    634 	    fp2 = F + j * tokensetsize;
    635 
    636 	    while (fp1 < fp3)
    637 		*fp2++ = *fp1++;
    638 	}
    639     }
    640 }
    641 
    642 #ifdef NO_LEAKS
    643 void
    644 lalr_leaks(void)
    645 {
    646     int i;
    647 
    648     if (includes != 0)
    649     {
    650 	for (i = 0; i < ngotos; i++)
    651 	{
    652 	    free(includes[i]);
    653 	}
    654 	DO_FREE(includes);
    655     }
    656 }
    657 #endif
    658