blob: 3da7d3ff6f01573285330a4f90babe4da5f35561 [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
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032/* Grammar implementation */
33
Guido van Rossum3f5da241990-12-20 15:06:42 +000034#include "pgenheaders.h"
35
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000036#include <ctype.h>
37
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000038#include "assert.h"
39#include "token.h"
40#include "grammar.h"
41
42extern int debugging;
43
44grammar *
45newgrammar(start)
46 int start;
47{
48 grammar *g;
49
50 g = NEW(grammar, 1);
51 if (g == NULL)
52 fatal("no mem for new grammar");
53 g->g_ndfas = 0;
54 g->g_dfa = NULL;
55 g->g_start = start;
56 g->g_ll.ll_nlabels = 0;
57 g->g_ll.ll_label = NULL;
Guido van Rossum588633d1994-12-30 15:46:02 +000058 g->g_accel = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000059 return g;
60}
61
62dfa *
63adddfa(g, type, name)
64 grammar *g;
65 int type;
66 char *name;
67{
68 dfa *d;
69
70 RESIZE(g->g_dfa, dfa, g->g_ndfas + 1);
71 if (g->g_dfa == NULL)
72 fatal("no mem to resize dfa in adddfa");
73 d = &g->g_dfa[g->g_ndfas++];
74 d->d_type = type;
75 d->d_name = name;
76 d->d_nstates = 0;
77 d->d_state = NULL;
78 d->d_initial = -1;
79 d->d_first = NULL;
80 return d; /* Only use while fresh! */
81}
82
83int
84addstate(d)
85 dfa *d;
86{
87 state *s;
88
89 RESIZE(d->d_state, state, d->d_nstates + 1);
90 if (d->d_state == NULL)
91 fatal("no mem to resize state in addstate");
92 s = &d->d_state[d->d_nstates++];
93 s->s_narcs = 0;
94 s->s_arc = NULL;
Guido van Rossum588633d1994-12-30 15:46:02 +000095 s->s_lower = 0;
96 s->s_upper = 0;
97 s->s_accel = NULL;
98 s->s_accept = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000099 return s - d->d_state;
100}
101
102void
103addarc(d, from, to, lbl)
104 dfa *d;
105 int lbl;
106{
107 state *s;
108 arc *a;
109
110 assert(0 <= from && from < d->d_nstates);
111 assert(0 <= to && to < d->d_nstates);
112
113 s = &d->d_state[from];
114 RESIZE(s->s_arc, arc, s->s_narcs + 1);
115 if (s->s_arc == NULL)
116 fatal("no mem to resize arc list in addarc");
117 a = &s->s_arc[s->s_narcs++];
118 a->a_lbl = lbl;
119 a->a_arrow = to;
120}
121
122int
123addlabel(ll, type, str)
124 labellist *ll;
125 int type;
126 char *str;
127{
128 int i;
129 label *lb;
130
131 for (i = 0; i < ll->ll_nlabels; i++) {
132 if (ll->ll_label[i].lb_type == type &&
133 strcmp(ll->ll_label[i].lb_str, str) == 0)
134 return i;
135 }
136 RESIZE(ll->ll_label, label, ll->ll_nlabels + 1);
137 if (ll->ll_label == NULL)
138 fatal("no mem to resize labellist in addlabel");
139 lb = &ll->ll_label[ll->ll_nlabels++];
140 lb->lb_type = type;
141 lb->lb_str = str; /* XXX strdup(str) ??? */
142 return lb - ll->ll_label;
143}
144
145/* Same, but rather dies than adds */
146
147int
148findlabel(ll, type, str)
149 labellist *ll;
150 int type;
151 char *str;
152{
153 int i;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000154
155 for (i = 0; i < ll->ll_nlabels; i++) {
156 if (ll->ll_label[i].lb_type == type /*&&
157 strcmp(ll->ll_label[i].lb_str, str) == 0*/)
158 return i;
159 }
160 fprintf(stderr, "Label %d/'%s' not found\n", type, str);
Guido van Rossum588633d1994-12-30 15:46:02 +0000161 fatal("grammar.c:findlabel()");
162 /*NOTREACHED*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000163}
164
Guido van Rossum3f5da241990-12-20 15:06:42 +0000165/* Forward */
166static void translabel PROTO((grammar *, label *));
167
168void
169translatelabels(g)
170 grammar *g;
171{
172 int i;
Guido van Rossum588633d1994-12-30 15:46:02 +0000173
174#ifdef DEBUG
Guido van Rossum3f5da241990-12-20 15:06:42 +0000175 printf("Translating labels ...\n");
Guido van Rossum588633d1994-12-30 15:46:02 +0000176#endif
Guido van Rossum3f5da241990-12-20 15:06:42 +0000177 /* Don't translate EMPTY */
178 for (i = EMPTY+1; i < g->g_ll.ll_nlabels; i++)
179 translabel(g, &g->g_ll.ll_label[i]);
180}
181
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000182static void
183translabel(g, lb)
184 grammar *g;
185 label *lb;
186{
187 int i;
188
189 if (debugging)
190 printf("Translating label %s ...\n", labelrepr(lb));
191
192 if (lb->lb_type == NAME) {
193 for (i = 0; i < g->g_ndfas; i++) {
194 if (strcmp(lb->lb_str, g->g_dfa[i].d_name) == 0) {
195 if (debugging)
196 printf("Label %s is non-terminal %d.\n",
197 lb->lb_str,
198 g->g_dfa[i].d_type);
199 lb->lb_type = g->g_dfa[i].d_type;
200 lb->lb_str = NULL;
201 return;
202 }
203 }
204 for (i = 0; i < (int)N_TOKENS; i++) {
205 if (strcmp(lb->lb_str, tok_name[i]) == 0) {
206 if (debugging)
207 printf("Label %s is terminal %d.\n",
208 lb->lb_str, i);
209 lb->lb_type = i;
210 lb->lb_str = NULL;
211 return;
212 }
213 }
214 printf("Can't translate NAME label '%s'\n", lb->lb_str);
215 return;
216 }
217
218 if (lb->lb_type == STRING) {
219 if (isalpha(lb->lb_str[1])) {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000220 char *p;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000221 if (debugging)
222 printf("Label %s is a keyword\n", lb->lb_str);
223 lb->lb_type = NAME;
224 lb->lb_str++;
225 p = strchr(lb->lb_str, '\'');
226 if (p)
227 *p = '\0';
228 }
Guido van Rossumc64d04d1991-10-20 20:20:00 +0000229 else if (lb->lb_str[2] == lb->lb_str[0]) {
230 int type = (int) tok_1char(lb->lb_str[1]);
231 if (type != OP) {
232 lb->lb_type = type;
233 lb->lb_str = NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000234 }
235 else
Guido van Rossumc64d04d1991-10-20 20:20:00 +0000236 printf("Unknown OP label %s\n",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237 lb->lb_str);
238 }
Guido van Rossumc64d04d1991-10-20 20:20:00 +0000239 else if (lb->lb_str[2] && lb->lb_str[3] == lb->lb_str[0]) {
240 int type = (int) tok_2char(lb->lb_str[1],
241 lb->lb_str[2]);
242 if (type != OP) {
243 lb->lb_type = type;
244 lb->lb_str = NULL;
245 }
246 else
247 printf("Unknown OP label %s\n",
248 lb->lb_str);
249 }
250 else
251 printf("Can't translate STRING label %s\n",
252 lb->lb_str);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000253 }
254 else
255 printf("Can't translate label '%s'\n", labelrepr(lb));
256}