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