acceler.c revision 3f5da24ea304e674a9abbdcffc4d671e32aa70f1
1/* Parser accelerator module */ 2 3/* The parser as originally conceived had disappointing performance. 4 This module does some precomputation that speeds up the selection 5 of a DFA based upon a token, turning a search through an array 6 into a simple indexing operation. The parser now cannot work 7 without the accelerators installed. Note that the accelerators 8 are installed dynamically when the parser is initialized, they 9 are not part of the static data structure written on graminit.[ch] 10 by the parser generator. */ 11 12#include "pgenheaders.h" 13#include "grammar.h" 14#include "token.h" 15#include "parser.h" 16 17/* Forward references */ 18static void fixdfa PROTO((grammar *, dfa *)); 19static void fixstate PROTO((grammar *, dfa *, state *)); 20 21void 22addaccelerators(g) 23 grammar *g; 24{ 25 dfa *d; 26 int i; 27#ifdef DEBUG 28 printf("Adding parser accellerators ...\n"); 29#endif 30 d = g->g_dfa; 31 for (i = g->g_ndfas; --i >= 0; d++) 32 fixdfa(g, d); 33 g->g_accel = 1; 34#ifdef DEBUG 35 printf("Done.\n"); 36#endif 37} 38 39static void 40fixdfa(g, d) 41 grammar *g; 42 dfa *d; 43{ 44 state *s; 45 int j; 46 s = d->d_state; 47 for (j = 0; j < d->d_nstates; j++, s++) 48 fixstate(g, d, s); 49} 50 51static void 52fixstate(g, d, s) 53 grammar *g; 54 dfa *d; 55 state *s; 56{ 57 arc *a; 58 int k; 59 int *accel; 60 int nl = g->g_ll.ll_nlabels; 61 s->s_accept = 0; 62 accel = NEW(int, nl); 63 for (k = 0; k < nl; k++) 64 accel[k] = -1; 65 a = s->s_arc; 66 for (k = s->s_narcs; --k >= 0; a++) { 67 int lbl = a->a_lbl; 68 label *l = &g->g_ll.ll_label[lbl]; 69 int type = l->lb_type; 70 if (a->a_arrow >= (1 << 7)) { 71 printf("XXX too many states!\n"); 72 continue; 73 } 74 if (ISNONTERMINAL(type)) { 75 dfa *d1 = finddfa(g, type); 76 int ibit; 77 if (type - NT_OFFSET >= (1 << 7)) { 78 printf("XXX too high nonterminal number!\n"); 79 continue; 80 } 81 for (ibit = 0; ibit < g->g_ll.ll_nlabels; ibit++) { 82 if (testbit(d1->d_first, ibit)) { 83 if (accel[ibit] != -1) 84 printf("XXX ambiguity!\n"); 85 accel[ibit] = a->a_arrow | (1 << 7) | 86 ((type - NT_OFFSET) << 8); 87 } 88 } 89 } 90 else if (lbl == EMPTY) 91 s->s_accept = 1; 92 else if (lbl >= 0 && lbl < nl) 93 accel[lbl] = a->a_arrow; 94 } 95 while (nl > 0 && accel[nl-1] == -1) 96 nl--; 97 for (k = 0; k < nl && accel[k] == -1;) 98 k++; 99 if (k < nl) { 100 int i; 101 s->s_accel = NEW(int, nl-k); 102 if (s->s_accel == NULL) { 103 fprintf(stderr, "no mem to add parser accelerators\n"); 104 exit(1); 105 } 106 s->s_lower = k; 107 s->s_upper = nl; 108 for (i = 0; k < nl; i++, k++) 109 s->s_accel[i] = accel[k]; 110 } 111 DEL(accel); 112} 113