blob: 7ff10b215553f4b4b45d12471297b23e88f6cfb1 [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* 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
10static void
11fixstate(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
73static void
74fixdfa(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
85void
86addaccelerators(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}