blob: 295f67d4f234c8fadd329ac45d073e772bca63cd [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
Thomas Wouters23c9e002000-07-22 19:20:54 +000023addfirstsets(grammar *g)
Guido van Rossum3f5da241990-12-20 15:06:42 +000024{
25 int i;
26 dfa *d;
27
28 printf("Adding FIRST sets ...\n");
29 for (i = 0; i < g->g_ndfas; i++) {
30 d = &g->g_dfa[i];
31 if (d->d_first == NULL)
32 calcfirstset(g, d);
33 }
34}
35
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000036static void
Thomas Wouters23c9e002000-07-22 19:20:54 +000037calcfirstset(grammar *g, dfa *d)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000038{
39 int i, j;
40 state *s;
41 arc *a;
42 int nsyms;
43 int *sym;
44 int nbits;
45 static bitset dummy;
46 bitset result;
47 int type;
48 dfa *d1;
49 label *l0;
50
Guido van Rossum86bea461997-04-29 21:03:06 +000051 if (Py_DebugFlag)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052 printf("Calculate FIRST set for '%s'\n", d->d_name);
53
54 if (dummy == NULL)
55 dummy = newbitset(1);
56 if (d->d_first == dummy) {
57 fprintf(stderr, "Left-recursion for '%s'\n", d->d_name);
58 return;
59 }
60 if (d->d_first != NULL) {
61 fprintf(stderr, "Re-calculating FIRST set for '%s' ???\n",
62 d->d_name);
63 }
64 d->d_first = dummy;
65
66 l0 = g->g_ll.ll_label;
67 nbits = g->g_ll.ll_nlabels;
68 result = newbitset(nbits);
69
Guido van Rossum86bea461997-04-29 21:03:06 +000070 sym = PyMem_NEW(int, 1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000071 if (sym == NULL)
Guido van Rossum86bea461997-04-29 21:03:06 +000072 Py_FatalError("no mem for new sym in calcfirstset");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073 nsyms = 1;
74 sym[0] = findlabel(&g->g_ll, d->d_type, (char *)NULL);
75
76 s = &d->d_state[d->d_initial];
77 for (i = 0; i < s->s_narcs; i++) {
78 a = &s->s_arc[i];
79 for (j = 0; j < nsyms; j++) {
80 if (sym[j] == a->a_lbl)
81 break;
82 }
83 if (j >= nsyms) { /* New label */
Guido van Rossum86bea461997-04-29 21:03:06 +000084 PyMem_RESIZE(sym, int, nsyms + 1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000085 if (sym == NULL)
Guido van Rossum86bea461997-04-29 21:03:06 +000086 Py_FatalError(
87 "no mem to resize sym in calcfirstset");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000088 sym[nsyms++] = a->a_lbl;
89 type = l0[a->a_lbl].lb_type;
90 if (ISNONTERMINAL(type)) {
Guido van Rossum86bea461997-04-29 21:03:06 +000091 d1 = PyGrammar_FindDFA(g, type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000092 if (d1->d_first == dummy) {
93 fprintf(stderr,
94 "Left-recursion below '%s'\n",
95 d->d_name);
96 }
97 else {
98 if (d1->d_first == NULL)
99 calcfirstset(g, d1);
Guido van Rossum86bea461997-04-29 21:03:06 +0000100 mergebitset(result,
101 d1->d_first, nbits);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000102 }
103 }
104 else if (ISTERMINAL(type)) {
105 addbit(result, a->a_lbl);
106 }
107 }
108 }
109 d->d_first = result;
Guido van Rossum86bea461997-04-29 21:03:06 +0000110 if (Py_DebugFlag) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000111 printf("FIRST set for '%s': {", d->d_name);
112 for (i = 0; i < nbits; i++) {
113 if (testbit(result, i))
Guido van Rossum86bea461997-04-29 21:03:06 +0000114 printf(" %s", PyGrammar_LabelRepr(&l0[i]));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000115 }
116 printf(" }\n");
117 }
118}