blob: b4a9e3c749d9d9aec65c9a1f27bb5d27f429dd85 [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* Computation of FIRST stets */
2
Guido van Rossum3f5da241990-12-20 15:06:42 +00003#include "pgenheaders.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004#include "grammar.h"
5#include "token.h"
6
7extern int debugging;
8
Guido van Rossum3f5da241990-12-20 15:06:42 +00009/* Forward */
10static void calcfirstset PROTO((grammar *, dfa *));
11
12void
13addfirstsets(g)
14 grammar *g;
15{
16 int i;
17 dfa *d;
18
19 printf("Adding FIRST sets ...\n");
20 for (i = 0; i < g->g_ndfas; i++) {
21 d = &g->g_dfa[i];
22 if (d->d_first == NULL)
23 calcfirstset(g, d);
24 }
25}
26
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000027static void
28calcfirstset(g, d)
29 grammar *g;
30 dfa *d;
31{
32 int i, j;
33 state *s;
34 arc *a;
35 int nsyms;
36 int *sym;
37 int nbits;
38 static bitset dummy;
39 bitset result;
40 int type;
41 dfa *d1;
42 label *l0;
43
44 if (debugging)
45 printf("Calculate FIRST set for '%s'\n", d->d_name);
46
47 if (dummy == NULL)
48 dummy = newbitset(1);
49 if (d->d_first == dummy) {
50 fprintf(stderr, "Left-recursion for '%s'\n", d->d_name);
51 return;
52 }
53 if (d->d_first != NULL) {
54 fprintf(stderr, "Re-calculating FIRST set for '%s' ???\n",
55 d->d_name);
56 }
57 d->d_first = dummy;
58
59 l0 = g->g_ll.ll_label;
60 nbits = g->g_ll.ll_nlabels;
61 result = newbitset(nbits);
62
63 sym = NEW(int, 1);
64 if (sym == NULL)
65 fatal("no mem for new sym in calcfirstset");
66 nsyms = 1;
67 sym[0] = findlabel(&g->g_ll, d->d_type, (char *)NULL);
68
69 s = &d->d_state[d->d_initial];
70 for (i = 0; i < s->s_narcs; i++) {
71 a = &s->s_arc[i];
72 for (j = 0; j < nsyms; j++) {
73 if (sym[j] == a->a_lbl)
74 break;
75 }
76 if (j >= nsyms) { /* New label */
77 RESIZE(sym, int, nsyms + 1);
78 if (sym == NULL)
79 fatal("no mem to resize sym in calcfirstset");
80 sym[nsyms++] = a->a_lbl;
81 type = l0[a->a_lbl].lb_type;
82 if (ISNONTERMINAL(type)) {
83 d1 = finddfa(g, type);
84 if (d1->d_first == dummy) {
85 fprintf(stderr,
86 "Left-recursion below '%s'\n",
87 d->d_name);
88 }
89 else {
90 if (d1->d_first == NULL)
91 calcfirstset(g, d1);
92 mergebitset(result, d1->d_first, nbits);
93 }
94 }
95 else if (ISTERMINAL(type)) {
96 addbit(result, a->a_lbl);
97 }
98 }
99 }
100 d->d_first = result;
101 if (debugging) {
102 printf("FIRST set for '%s': {", d->d_name);
103 for (i = 0; i < nbits; i++) {
104 if (testbit(result, i))
105 printf(" %s", labelrepr(&l0[i]));
106 }
107 printf(" }\n");
108 }
109}