| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame^] | 1 | /* Parser accelerator module */ | 
|  | 2 |  | 
|  | 3 | #include <stdio.h> | 
|  | 4 |  | 
|  | 5 | #include "PROTO.h" | 
|  | 6 | #include "grammar.h" | 
|  | 7 | #include "token.h" | 
|  | 8 | #include "malloc.h" | 
|  | 9 |  | 
|  | 10 | static void | 
|  | 11 | fixstate(g, d, s) | 
|  | 12 | grammar *g; | 
|  | 13 | dfa *d; | 
|  | 14 | state *s; | 
|  | 15 | { | 
|  | 16 | arc *a; | 
|  | 17 | int k; | 
|  | 18 | int *accel; | 
|  | 19 | int nl = g->g_ll.ll_nlabels; | 
|  | 20 | s->s_accept = 0; | 
|  | 21 | accel = NEW(int, nl); | 
|  | 22 | for (k = 0; k < nl; k++) | 
|  | 23 | accel[k] = -1; | 
|  | 24 | a = s->s_arc; | 
|  | 25 | for (k = s->s_narcs; --k >= 0; a++) { | 
|  | 26 | int lbl = a->a_lbl; | 
|  | 27 | label *l = &g->g_ll.ll_label[lbl]; | 
|  | 28 | int type = l->lb_type; | 
|  | 29 | if (a->a_arrow >= (1 << 7)) { | 
|  | 30 | printf("XXX too many states!\n"); | 
|  | 31 | continue; | 
|  | 32 | } | 
|  | 33 | if (ISNONTERMINAL(type)) { | 
|  | 34 | dfa *d1 = finddfa(g, type); | 
|  | 35 | int ibit; | 
|  | 36 | if (type - NT_OFFSET >= (1 << 7)) { | 
|  | 37 | printf("XXX too high nonterminal number!\n"); | 
|  | 38 | continue; | 
|  | 39 | } | 
|  | 40 | for (ibit = 0; ibit < g->g_ll.ll_nlabels; ibit++) { | 
|  | 41 | if (testbit(d1->d_first, ibit)) { | 
|  | 42 | if (accel[ibit] != -1) | 
|  | 43 | printf("XXX ambiguity!\n"); | 
|  | 44 | accel[ibit] = a->a_arrow | (1 << 7) | | 
|  | 45 | ((type - NT_OFFSET) << 8); | 
|  | 46 | } | 
|  | 47 | } | 
|  | 48 | } | 
|  | 49 | else if (lbl == EMPTY) | 
|  | 50 | s->s_accept = 1; | 
|  | 51 | else if (lbl >= 0 && lbl < nl) | 
|  | 52 | accel[lbl] = a->a_arrow; | 
|  | 53 | } | 
|  | 54 | while (nl > 0 && accel[nl-1] == -1) | 
|  | 55 | nl--; | 
|  | 56 | for (k = 0; k < nl && accel[k] == -1;) | 
|  | 57 | k++; | 
|  | 58 | if (k < nl) { | 
|  | 59 | int i; | 
|  | 60 | s->s_accel = NEW(int, nl-k); | 
|  | 61 | if (s->s_accel == NULL) { | 
|  | 62 | fprintf(stderr, "no mem to add parser accelerators\n"); | 
|  | 63 | exit(1); | 
|  | 64 | } | 
|  | 65 | s->s_lower = k; | 
|  | 66 | s->s_upper = nl; | 
|  | 67 | for (i = 0; k < nl; i++, k++) | 
|  | 68 | s->s_accel[i] = accel[k]; | 
|  | 69 | } | 
|  | 70 | DEL(accel); | 
|  | 71 | } | 
|  | 72 |  | 
|  | 73 | static void | 
|  | 74 | fixdfa(g, d) | 
|  | 75 | grammar *g; | 
|  | 76 | dfa *d; | 
|  | 77 | { | 
|  | 78 | state *s; | 
|  | 79 | int j; | 
|  | 80 | s = d->d_state; | 
|  | 81 | for (j = 0; j < d->d_nstates; j++, s++) | 
|  | 82 | fixstate(g, d, s); | 
|  | 83 | } | 
|  | 84 |  | 
|  | 85 | void | 
|  | 86 | addaccelerators(g) | 
|  | 87 | grammar *g; | 
|  | 88 | { | 
|  | 89 | dfa *d; | 
|  | 90 | int i; | 
|  | 91 | #ifdef DEBUG | 
|  | 92 | printf("Adding parser accellerators ...\n"); | 
|  | 93 | #endif | 
|  | 94 | d = g->g_dfa; | 
|  | 95 | for (i = g->g_ndfas; --i >= 0; d++) | 
|  | 96 | fixdfa(g, d); | 
|  | 97 | g->g_accel = 1; | 
|  | 98 | #ifdef DEBUG | 
|  | 99 | printf("Done.\n"); | 
|  | 100 | #endif | 
|  | 101 | } |