blob: 221bf6478f1e36da88d395bb1b8dffe606c3b7e9 [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* Grammar implementation */
2
Guido van Rossum3f5da241990-12-20 15:06:42 +00003#include "pgenheaders.h"
4
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005#include <ctype.h>
6
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007#include "assert.h"
8#include "token.h"
9#include "grammar.h"
10
11extern int debugging;
12
13grammar *
14newgrammar(start)
15 int start;
16{
17 grammar *g;
18
19 g = NEW(grammar, 1);
20 if (g == NULL)
21 fatal("no mem for new grammar");
22 g->g_ndfas = 0;
23 g->g_dfa = NULL;
24 g->g_start = start;
25 g->g_ll.ll_nlabels = 0;
26 g->g_ll.ll_label = NULL;
27 return g;
28}
29
30dfa *
31adddfa(g, type, name)
32 grammar *g;
33 int type;
34 char *name;
35{
36 dfa *d;
37
38 RESIZE(g->g_dfa, dfa, g->g_ndfas + 1);
39 if (g->g_dfa == NULL)
40 fatal("no mem to resize dfa in adddfa");
41 d = &g->g_dfa[g->g_ndfas++];
42 d->d_type = type;
43 d->d_name = name;
44 d->d_nstates = 0;
45 d->d_state = NULL;
46 d->d_initial = -1;
47 d->d_first = NULL;
48 return d; /* Only use while fresh! */
49}
50
51int
52addstate(d)
53 dfa *d;
54{
55 state *s;
56
57 RESIZE(d->d_state, state, d->d_nstates + 1);
58 if (d->d_state == NULL)
59 fatal("no mem to resize state in addstate");
60 s = &d->d_state[d->d_nstates++];
61 s->s_narcs = 0;
62 s->s_arc = NULL;
63 return s - d->d_state;
64}
65
66void
67addarc(d, from, to, lbl)
68 dfa *d;
69 int lbl;
70{
71 state *s;
72 arc *a;
73
74 assert(0 <= from && from < d->d_nstates);
75 assert(0 <= to && to < d->d_nstates);
76
77 s = &d->d_state[from];
78 RESIZE(s->s_arc, arc, s->s_narcs + 1);
79 if (s->s_arc == NULL)
80 fatal("no mem to resize arc list in addarc");
81 a = &s->s_arc[s->s_narcs++];
82 a->a_lbl = lbl;
83 a->a_arrow = to;
84}
85
86int
87addlabel(ll, type, str)
88 labellist *ll;
89 int type;
90 char *str;
91{
92 int i;
93 label *lb;
94
95 for (i = 0; i < ll->ll_nlabels; i++) {
96 if (ll->ll_label[i].lb_type == type &&
97 strcmp(ll->ll_label[i].lb_str, str) == 0)
98 return i;
99 }
100 RESIZE(ll->ll_label, label, ll->ll_nlabels + 1);
101 if (ll->ll_label == NULL)
102 fatal("no mem to resize labellist in addlabel");
103 lb = &ll->ll_label[ll->ll_nlabels++];
104 lb->lb_type = type;
105 lb->lb_str = str; /* XXX strdup(str) ??? */
106 return lb - ll->ll_label;
107}
108
109/* Same, but rather dies than adds */
110
111int
112findlabel(ll, type, str)
113 labellist *ll;
114 int type;
115 char *str;
116{
117 int i;
118 label *lb;
119
120 for (i = 0; i < ll->ll_nlabels; i++) {
121 if (ll->ll_label[i].lb_type == type /*&&
122 strcmp(ll->ll_label[i].lb_str, str) == 0*/)
123 return i;
124 }
125 fprintf(stderr, "Label %d/'%s' not found\n", type, str);
126 abort();
127}
128
Guido van Rossum3f5da241990-12-20 15:06:42 +0000129/* Forward */
130static void translabel PROTO((grammar *, label *));
131
132void
133translatelabels(g)
134 grammar *g;
135{
136 int i;
137
138 printf("Translating labels ...\n");
139 /* Don't translate EMPTY */
140 for (i = EMPTY+1; i < g->g_ll.ll_nlabels; i++)
141 translabel(g, &g->g_ll.ll_label[i]);
142}
143
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000144static void
145translabel(g, lb)
146 grammar *g;
147 label *lb;
148{
149 int i;
150
151 if (debugging)
152 printf("Translating label %s ...\n", labelrepr(lb));
153
154 if (lb->lb_type == NAME) {
155 for (i = 0; i < g->g_ndfas; i++) {
156 if (strcmp(lb->lb_str, g->g_dfa[i].d_name) == 0) {
157 if (debugging)
158 printf("Label %s is non-terminal %d.\n",
159 lb->lb_str,
160 g->g_dfa[i].d_type);
161 lb->lb_type = g->g_dfa[i].d_type;
162 lb->lb_str = NULL;
163 return;
164 }
165 }
166 for (i = 0; i < (int)N_TOKENS; i++) {
167 if (strcmp(lb->lb_str, tok_name[i]) == 0) {
168 if (debugging)
169 printf("Label %s is terminal %d.\n",
170 lb->lb_str, i);
171 lb->lb_type = i;
172 lb->lb_str = NULL;
173 return;
174 }
175 }
176 printf("Can't translate NAME label '%s'\n", lb->lb_str);
177 return;
178 }
179
180 if (lb->lb_type == STRING) {
181 if (isalpha(lb->lb_str[1])) {
182 char *p, *strchr();
183 if (debugging)
184 printf("Label %s is a keyword\n", lb->lb_str);
185 lb->lb_type = NAME;
186 lb->lb_str++;
187 p = strchr(lb->lb_str, '\'');
188 if (p)
189 *p = '\0';
190 }
191 else {
192 if (lb->lb_str[2] == lb->lb_str[0]) {
193 int type = (int) tok_1char(lb->lb_str[1]);
194 if (type != OP) {
195 lb->lb_type = type;
196 lb->lb_str = NULL;
197 }
198 else
199 printf("Unknown OP label %s\n",
200 lb->lb_str);
201 }
202 else
203 printf("Can't translate STRING label %s\n",
204 lb->lb_str);
205 }
206 }
207 else
208 printf("Can't translate label '%s'\n", labelrepr(lb));
209}