blob: 07e3f623bf581ed7327b2721344ca654aa05977f [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
Guido van Rossum86bea461997-04-29 21:03:06 +000042extern int Py_DebugFlag;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000043
44grammar *
45newgrammar(start)
46 int start;
47{
48 grammar *g;
49
Guido van Rossum86bea461997-04-29 21:03:06 +000050 g = PyMem_NEW(grammar, 1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000051 if (g == NULL)
Guido van Rossum86bea461997-04-29 21:03:06 +000052 Py_FatalError("no mem for new grammar");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000053 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
Guido van Rossum86bea461997-04-29 21:03:06 +000070 PyMem_RESIZE(g->g_dfa, dfa, g->g_ndfas + 1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000071 if (g->g_dfa == NULL)
Guido van Rossum86bea461997-04-29 21:03:06 +000072 Py_FatalError("no mem to resize dfa in adddfa");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073 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
Guido van Rossum86bea461997-04-29 21:03:06 +000089 PyMem_RESIZE(d->d_state, state, d->d_nstates + 1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000090 if (d->d_state == NULL)
Guido van Rossum86bea461997-04-29 21:03:06 +000091 Py_FatalError("no mem to resize state in addstate");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000092 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];
Guido van Rossum86bea461997-04-29 21:03:06 +0000114 PyMem_RESIZE(s->s_arc, arc, s->s_narcs + 1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000115 if (s->s_arc == NULL)
Guido van Rossum86bea461997-04-29 21:03:06 +0000116 Py_FatalError("no mem to resize arc list in addarc");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117 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 }
Guido van Rossum86bea461997-04-29 21:03:06 +0000136 PyMem_RESIZE(ll->ll_label, label, ll->ll_nlabels + 1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000137 if (ll->ll_label == NULL)
Guido van Rossum86bea461997-04-29 21:03:06 +0000138 Py_FatalError("no mem to resize labellist in addlabel");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000139 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 Rossum86bea461997-04-29 21:03:06 +0000161 Py_FatalError("grammar.c:findlabel()");
Guido van Rossumfd8a3931996-12-02 18:27:33 +0000162 return 0; /* Make gcc -Wall happy */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000163}
164
Guido van Rossum3f5da241990-12-20 15:06:42 +0000165/* Forward */
Guido van Rossum86bea461997-04-29 21:03:06 +0000166static void translabel Py_PROTO((grammar *, label *));
Guido van Rossum3f5da241990-12-20 15:06:42 +0000167
168void
169translatelabels(g)
170 grammar *g;
171{
172 int i;
Guido van Rossum588633d1994-12-30 15:46:02 +0000173
Guido van Rossum408027e1996-12-30 16:17:54 +0000174#ifdef Py_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
Guido van Rossum86bea461997-04-29 21:03:06 +0000189 if (Py_DebugFlag)
190 printf("Translating label %s ...\n", PyGrammar_LabelRepr(lb));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191
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) {
Guido van Rossum86bea461997-04-29 21:03:06 +0000195 if (Py_DebugFlag)
196 printf(
197 "Label %s is non-terminal %d.\n",
198 lb->lb_str,
199 g->g_dfa[i].d_type);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000200 lb->lb_type = g->g_dfa[i].d_type;
201 lb->lb_str = NULL;
202 return;
203 }
204 }
205 for (i = 0; i < (int)N_TOKENS; i++) {
Guido van Rossum86bea461997-04-29 21:03:06 +0000206 if (strcmp(lb->lb_str, _PyParser_TokenNames[i]) == 0) {
207 if (Py_DebugFlag)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000208 printf("Label %s is terminal %d.\n",
209 lb->lb_str, i);
210 lb->lb_type = i;
211 lb->lb_str = NULL;
212 return;
213 }
214 }
215 printf("Can't translate NAME label '%s'\n", lb->lb_str);
216 return;
217 }
218
219 if (lb->lb_type == STRING) {
Guido van Rossum6dacd901997-04-02 05:23:46 +0000220 if (isalpha(lb->lb_str[1]) || lb->lb_str[1] == '_') {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000221 char *p;
Guido van Rossum86bea461997-04-29 21:03:06 +0000222 if (Py_DebugFlag)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000223 printf("Label %s is a keyword\n", lb->lb_str);
224 lb->lb_type = NAME;
225 lb->lb_str++;
226 p = strchr(lb->lb_str, '\'');
227 if (p)
228 *p = '\0';
229 }
Guido van Rossumc64d04d1991-10-20 20:20:00 +0000230 else if (lb->lb_str[2] == lb->lb_str[0]) {
Guido van Rossum86bea461997-04-29 21:03:06 +0000231 int type = (int) PyToken_OneChar(lb->lb_str[1]);
Guido van Rossumc64d04d1991-10-20 20:20:00 +0000232 if (type != OP) {
233 lb->lb_type = type;
234 lb->lb_str = NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000235 }
236 else
Guido van Rossumc64d04d1991-10-20 20:20:00 +0000237 printf("Unknown OP label %s\n",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000238 lb->lb_str);
239 }
Guido van Rossumc64d04d1991-10-20 20:20:00 +0000240 else if (lb->lb_str[2] && lb->lb_str[3] == lb->lb_str[0]) {
Guido van Rossum86bea461997-04-29 21:03:06 +0000241 int type = (int) PyToken_TwoChars(lb->lb_str[1],
Guido van Rossumc64d04d1991-10-20 20:20:00 +0000242 lb->lb_str[2]);
243 if (type != OP) {
244 lb->lb_type = type;
245 lb->lb_str = NULL;
246 }
247 else
248 printf("Unknown OP label %s\n",
249 lb->lb_str);
250 }
251 else
252 printf("Can't translate STRING label %s\n",
253 lb->lb_str);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000254 }
255 else
Guido van Rossum86bea461997-04-29 21:03:06 +0000256 printf("Can't translate label '%s'\n",
257 PyGrammar_LabelRepr(lb));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000258}