Files for 2.1b1 distribution.
[python/dscho.git] / Parser / firstsets.c
blobd6c4084d066815a92e20640a2513e3254200f87c
2 /* Computation of FIRST stets */
4 #include "pgenheaders.h"
5 #include "grammar.h"
6 #include "token.h"
8 extern int Py_DebugFlag;
10 /* Forward */
11 static void calcfirstset(grammar *, dfa *);
13 void
14 addfirstsets(grammar *g)
16 int i;
17 dfa *d;
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);
27 static void
28 calcfirstset(grammar *g, dfa *d)
30 int i, j;
31 state *s;
32 arc *a;
33 int nsyms;
34 int *sym;
35 int nbits;
36 static bitset dummy;
37 bitset result;
38 int type;
39 dfa *d1;
40 label *l0;
42 if (Py_DebugFlag)
43 printf("Calculate FIRST set for '%s'\n", d->d_name);
45 if (dummy == NULL)
46 dummy = newbitset(1);
47 if (d->d_first == dummy) {
48 fprintf(stderr, "Left-recursion for '%s'\n", d->d_name);
49 return;
51 if (d->d_first != NULL) {
52 fprintf(stderr, "Re-calculating FIRST set for '%s' ???\n",
53 d->d_name);
55 d->d_first = dummy;
57 l0 = g->g_ll.ll_label;
58 nbits = g->g_ll.ll_nlabels;
59 result = newbitset(nbits);
61 sym = PyMem_NEW(int, 1);
62 if (sym == NULL)
63 Py_FatalError("no mem for new sym in calcfirstset");
64 nsyms = 1;
65 sym[0] = findlabel(&g->g_ll, d->d_type, (char *)NULL);
67 s = &d->d_state[d->d_initial];
68 for (i = 0; i < s->s_narcs; i++) {
69 a = &s->s_arc[i];
70 for (j = 0; j < nsyms; j++) {
71 if (sym[j] == a->a_lbl)
72 break;
74 if (j >= nsyms) { /* New label */
75 PyMem_RESIZE(sym, int, nsyms + 1);
76 if (sym == NULL)
77 Py_FatalError(
78 "no mem to resize sym in calcfirstset");
79 sym[nsyms++] = a->a_lbl;
80 type = l0[a->a_lbl].lb_type;
81 if (ISNONTERMINAL(type)) {
82 d1 = PyGrammar_FindDFA(g, type);
83 if (d1->d_first == dummy) {
84 fprintf(stderr,
85 "Left-recursion below '%s'\n",
86 d->d_name);
88 else {
89 if (d1->d_first == NULL)
90 calcfirstset(g, d1);
91 mergebitset(result,
92 d1->d_first, nbits);
95 else if (ISTERMINAL(type)) {
96 addbit(result, a->a_lbl);
100 d->d_first = result;
101 if (Py_DebugFlag) {
102 printf("FIRST set for '%s': {", d->d_name);
103 for (i = 0; i < nbits; i++) {
104 if (testbit(result, i))
105 printf(" %s", PyGrammar_LabelRepr(&l0[i]));
107 printf(" }\n");