blob: 90050272b0aa5793a3c8f69b1259d7ec3b3cde53 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumb9f8d6e1995-01-04 19:08:09 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* Grammar implementation */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "pgenheaders.h"
28
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000029#include <ctype.h>
30
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000031#include "assert.h"
32#include "token.h"
33#include "grammar.h"
34
35extern int debugging;
36
37grammar *
38newgrammar(start)
39 int start;
40{
41 grammar *g;
42
43 g = NEW(grammar, 1);
44 if (g == NULL)
45 fatal("no mem for new grammar");
46 g->g_ndfas = 0;
47 g->g_dfa = NULL;
48 g->g_start = start;
49 g->g_ll.ll_nlabels = 0;
50 g->g_ll.ll_label = NULL;
Guido van Rossum588633d1994-12-30 15:46:02 +000051 g->g_accel = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052 return g;
53}
54
55dfa *
56adddfa(g, type, name)
57 grammar *g;
58 int type;
59 char *name;
60{
61 dfa *d;
62
63 RESIZE(g->g_dfa, dfa, g->g_ndfas + 1);
64 if (g->g_dfa == NULL)
65 fatal("no mem to resize dfa in adddfa");
66 d = &g->g_dfa[g->g_ndfas++];
67 d->d_type = type;
68 d->d_name = name;
69 d->d_nstates = 0;
70 d->d_state = NULL;
71 d->d_initial = -1;
72 d->d_first = NULL;
73 return d; /* Only use while fresh! */
74}
75
76int
77addstate(d)
78 dfa *d;
79{
80 state *s;
81
82 RESIZE(d->d_state, state, d->d_nstates + 1);
83 if (d->d_state == NULL)
84 fatal("no mem to resize state in addstate");
85 s = &d->d_state[d->d_nstates++];
86 s->s_narcs = 0;
87 s->s_arc = NULL;
Guido van Rossum588633d1994-12-30 15:46:02 +000088 s->s_lower = 0;
89 s->s_upper = 0;
90 s->s_accel = NULL;
91 s->s_accept = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000092 return s - d->d_state;
93}
94
95void
96addarc(d, from, to, lbl)
97 dfa *d;
98 int lbl;
99{
100 state *s;
101 arc *a;
102
103 assert(0 <= from && from < d->d_nstates);
104 assert(0 <= to && to < d->d_nstates);
105
106 s = &d->d_state[from];
107 RESIZE(s->s_arc, arc, s->s_narcs + 1);
108 if (s->s_arc == NULL)
109 fatal("no mem to resize arc list in addarc");
110 a = &s->s_arc[s->s_narcs++];
111 a->a_lbl = lbl;
112 a->a_arrow = to;
113}
114
115int
116addlabel(ll, type, str)
117 labellist *ll;
118 int type;
119 char *str;
120{
121 int i;
122 label *lb;
123
124 for (i = 0; i < ll->ll_nlabels; i++) {
125 if (ll->ll_label[i].lb_type == type &&
126 strcmp(ll->ll_label[i].lb_str, str) == 0)
127 return i;
128 }
129 RESIZE(ll->ll_label, label, ll->ll_nlabels + 1);
130 if (ll->ll_label == NULL)
131 fatal("no mem to resize labellist in addlabel");
132 lb = &ll->ll_label[ll->ll_nlabels++];
133 lb->lb_type = type;
134 lb->lb_str = str; /* XXX strdup(str) ??? */
135 return lb - ll->ll_label;
136}
137
138/* Same, but rather dies than adds */
139
140int
141findlabel(ll, type, str)
142 labellist *ll;
143 int type;
144 char *str;
145{
146 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000147
148 for (i = 0; i < ll->ll_nlabels; i++) {
149 if (ll->ll_label[i].lb_type == type /*&&
150 strcmp(ll->ll_label[i].lb_str, str) == 0*/)
151 return i;
152 }
153 fprintf(stderr, "Label %d/'%s' not found\n", type, str);
Guido van Rossum588633d1994-12-30 15:46:02 +0000154 fatal("grammar.c:findlabel()");
155 /*NOTREACHED*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000156}
157
Guido van Rossum3f5da241990-12-20 15:06:42 +0000158/* Forward */
159static void translabel PROTO((grammar *, label *));
160
161void
162translatelabels(g)
163 grammar *g;
164{
165 int i;
Guido van Rossum588633d1994-12-30 15:46:02 +0000166
167#ifdef DEBUG
Guido van Rossum3f5da241990-12-20 15:06:42 +0000168 printf("Translating labels ...\n");
Guido van Rossum588633d1994-12-30 15:46:02 +0000169#endif
Guido van Rossum3f5da241990-12-20 15:06:42 +0000170 /* Don't translate EMPTY */
171 for (i = EMPTY+1; i < g->g_ll.ll_nlabels; i++)
172 translabel(g, &g->g_ll.ll_label[i]);
173}
174
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000175static void
176translabel(g, lb)
177 grammar *g;
178 label *lb;
179{
180 int i;
181
182 if (debugging)
183 printf("Translating label %s ...\n", labelrepr(lb));
184
185 if (lb->lb_type == NAME) {
186 for (i = 0; i < g->g_ndfas; i++) {
187 if (strcmp(lb->lb_str, g->g_dfa[i].d_name) == 0) {
188 if (debugging)
189 printf("Label %s is non-terminal %d.\n",
190 lb->lb_str,
191 g->g_dfa[i].d_type);
192 lb->lb_type = g->g_dfa[i].d_type;
193 lb->lb_str = NULL;
194 return;
195 }
196 }
197 for (i = 0; i < (int)N_TOKENS; i++) {
198 if (strcmp(lb->lb_str, tok_name[i]) == 0) {
199 if (debugging)
200 printf("Label %s is terminal %d.\n",
201 lb->lb_str, i);
202 lb->lb_type = i;
203 lb->lb_str = NULL;
204 return;
205 }
206 }
207 printf("Can't translate NAME label '%s'\n", lb->lb_str);
208 return;
209 }
210
211 if (lb->lb_type == STRING) {
212 if (isalpha(lb->lb_str[1])) {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000213 char *p;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000214 if (debugging)
215 printf("Label %s is a keyword\n", lb->lb_str);
216 lb->lb_type = NAME;
217 lb->lb_str++;
218 p = strchr(lb->lb_str, '\'');
219 if (p)
220 *p = '\0';
221 }
Guido van Rossumc64d04d1991-10-20 20:20:00 +0000222 else if (lb->lb_str[2] == lb->lb_str[0]) {
223 int type = (int) tok_1char(lb->lb_str[1]);
224 if (type != OP) {
225 lb->lb_type = type;
226 lb->lb_str = NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227 }
228 else
Guido van Rossumc64d04d1991-10-20 20:20:00 +0000229 printf("Unknown OP label %s\n",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230 lb->lb_str);
231 }
Guido van Rossumc64d04d1991-10-20 20:20:00 +0000232 else if (lb->lb_str[2] && lb->lb_str[3] == lb->lb_str[0]) {
233 int type = (int) tok_2char(lb->lb_str[1],
234 lb->lb_str[2]);
235 if (type != OP) {
236 lb->lb_type = type;
237 lb->lb_str = NULL;
238 }
239 else
240 printf("Unknown OP label %s\n",
241 lb->lb_str);
242 }
243 else
244 printf("Can't translate STRING label %s\n",
245 lb->lb_str);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000246 }
247 else
248 printf("Can't translate label '%s'\n", labelrepr(lb));
249}