blob: b27ed2e2c2a3e0904db2a92cc8ae8baa03768c14 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009******************************************************************/
10
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011/* Computation of FIRST stets */
12
Guido van Rossum3f5da241990-12-20 15:06:42 +000013#include "pgenheaders.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000014#include "grammar.h"
15#include "token.h"
16
Guido van Rossum86bea461997-04-29 21:03:06 +000017extern int Py_DebugFlag;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000018
Guido van Rossum3f5da241990-12-20 15:06:42 +000019/* Forward */
Tim Petersdbd9ba62000-07-09 03:09:57 +000020static void calcfirstset(grammar *, dfa *);
Guido van Rossum3f5da241990-12-20 15:06:42 +000021
22void
23addfirstsets(g)
24 grammar *g;
25{
26 int i;
27 dfa *d;
28
29 printf("Adding FIRST sets ...\n");
30 for (i = 0; i < g->g_ndfas; i++) {
31 d = &g->g_dfa[i];
32 if (d->d_first == NULL)
33 calcfirstset(g, d);
34 }
35}
36
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000037static void
38calcfirstset(g, d)
39 grammar *g;
40 dfa *d;
41{
42 int i, j;
43 state *s;
44 arc *a;
45 int nsyms;
46 int *sym;
47 int nbits;
48 static bitset dummy;
49 bitset result;
50 int type;
51 dfa *d1;
52 label *l0;
53
Guido van Rossum86bea461997-04-29 21:03:06 +000054 if (Py_DebugFlag)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000055 printf("Calculate FIRST set for '%s'\n", d->d_name);
56
57 if (dummy == NULL)
58 dummy = newbitset(1);
59 if (d->d_first == dummy) {
60 fprintf(stderr, "Left-recursion for '%s'\n", d->d_name);
61 return;
62 }
63 if (d->d_first != NULL) {
64 fprintf(stderr, "Re-calculating FIRST set for '%s' ???\n",
65 d->d_name);
66 }
67 d->d_first = dummy;
68
69 l0 = g->g_ll.ll_label;
70 nbits = g->g_ll.ll_nlabels;
71 result = newbitset(nbits);
72
Guido van Rossum86bea461997-04-29 21:03:06 +000073 sym = PyMem_NEW(int, 1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000074 if (sym == NULL)
Guido van Rossum86bea461997-04-29 21:03:06 +000075 Py_FatalError("no mem for new sym in calcfirstset");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000076 nsyms = 1;
77 sym[0] = findlabel(&g->g_ll, d->d_type, (char *)NULL);
78
79 s = &d->d_state[d->d_initial];
80 for (i = 0; i < s->s_narcs; i++) {
81 a = &s->s_arc[i];
82 for (j = 0; j < nsyms; j++) {
83 if (sym[j] == a->a_lbl)
84 break;
85 }
86 if (j >= nsyms) { /* New label */
Guido van Rossum86bea461997-04-29 21:03:06 +000087 PyMem_RESIZE(sym, int, nsyms + 1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000088 if (sym == NULL)
Guido van Rossum86bea461997-04-29 21:03:06 +000089 Py_FatalError(
90 "no mem to resize sym in calcfirstset");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091 sym[nsyms++] = a->a_lbl;
92 type = l0[a->a_lbl].lb_type;
93 if (ISNONTERMINAL(type)) {
Guido van Rossum86bea461997-04-29 21:03:06 +000094 d1 = PyGrammar_FindDFA(g, type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000095 if (d1->d_first == dummy) {
96 fprintf(stderr,
97 "Left-recursion below '%s'\n",
98 d->d_name);
99 }
100 else {
101 if (d1->d_first == NULL)
102 calcfirstset(g, d1);
Guido van Rossum86bea461997-04-29 21:03:06 +0000103 mergebitset(result,
104 d1->d_first, nbits);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000105 }
106 }
107 else if (ISTERMINAL(type)) {
108 addbit(result, a->a_lbl);
109 }
110 }
111 }
112 d->d_first = result;
Guido van Rossum86bea461997-04-29 21:03:06 +0000113 if (Py_DebugFlag) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000114 printf("FIRST set for '%s': {", d->d_name);
115 for (i = 0; i < nbits; i++) {
116 if (testbit(result, i))
Guido van Rossum86bea461997-04-29 21:03:06 +0000117 printf(" %s", PyGrammar_LabelRepr(&l0[i]));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000118 }
119 printf(" }\n");
120 }
121}