Line data Source code
1 :
2 : /* Grammar implementation */
3 :
4 : #include "Python.h"
5 : #include "pgenheaders.h"
6 :
7 : #include <ctype.h>
8 :
9 : #include "token.h"
10 : #include "grammar.h"
11 :
12 : extern int Py_DebugFlag;
13 :
14 : grammar *
15 0 : newgrammar(int start)
16 : {
17 : grammar *g;
18 :
19 0 : g = (grammar *)PyObject_MALLOC(sizeof(grammar));
20 0 : if (g == NULL)
21 0 : Py_FatalError("no mem for new grammar");
22 0 : g->g_ndfas = 0;
23 0 : g->g_dfa = NULL;
24 0 : g->g_start = start;
25 0 : g->g_ll.ll_nlabels = 0;
26 0 : g->g_ll.ll_label = NULL;
27 0 : g->g_accel = 0;
28 0 : return g;
29 : }
30 :
31 : dfa *
32 0 : adddfa(grammar *g, int type, char *name)
33 : {
34 : dfa *d;
35 :
36 0 : g->g_dfa = (dfa *)PyObject_REALLOC(g->g_dfa,
37 0 : sizeof(dfa) * (g->g_ndfas + 1));
38 0 : if (g->g_dfa == NULL)
39 0 : Py_FatalError("no mem to resize dfa in adddfa");
40 0 : d = &g->g_dfa[g->g_ndfas++];
41 0 : d->d_type = type;
42 0 : d->d_name = strdup(name);
43 0 : d->d_nstates = 0;
44 0 : d->d_state = NULL;
45 0 : d->d_initial = -1;
46 0 : d->d_first = NULL;
47 0 : return d; /* Only use while fresh! */
48 : }
49 :
50 : int
51 0 : addstate(dfa *d)
52 : {
53 : state *s;
54 :
55 0 : d->d_state = (state *)PyObject_REALLOC(d->d_state,
56 0 : sizeof(state) * (d->d_nstates + 1));
57 0 : if (d->d_state == NULL)
58 0 : Py_FatalError("no mem to resize state in addstate");
59 0 : s = &d->d_state[d->d_nstates++];
60 0 : s->s_narcs = 0;
61 0 : s->s_arc = NULL;
62 0 : s->s_lower = 0;
63 0 : s->s_upper = 0;
64 0 : s->s_accel = NULL;
65 0 : s->s_accept = 0;
66 0 : return s - d->d_state;
67 : }
68 :
69 : void
70 0 : addarc(dfa *d, int from, int to, int lbl)
71 : {
72 : state *s;
73 : arc *a;
74 :
75 : assert(0 <= from && from < d->d_nstates);
76 : assert(0 <= to && to < d->d_nstates);
77 :
78 0 : s = &d->d_state[from];
79 0 : s->s_arc = (arc *)PyObject_REALLOC(s->s_arc, sizeof(arc) * (s->s_narcs + 1));
80 0 : if (s->s_arc == NULL)
81 0 : Py_FatalError("no mem to resize arc list in addarc");
82 0 : a = &s->s_arc[s->s_narcs++];
83 0 : a->a_lbl = lbl;
84 0 : a->a_arrow = to;
85 0 : }
86 :
87 : int
88 0 : addlabel(labellist *ll, int type, char *str)
89 : {
90 : int i;
91 : label *lb;
92 :
93 0 : for (i = 0; i < ll->ll_nlabels; i++) {
94 0 : if (ll->ll_label[i].lb_type == type &&
95 0 : strcmp(ll->ll_label[i].lb_str, str) == 0)
96 0 : return i;
97 : }
98 0 : ll->ll_label = (label *)PyObject_REALLOC(ll->ll_label,
99 0 : sizeof(label) * (ll->ll_nlabels + 1));
100 0 : if (ll->ll_label == NULL)
101 0 : Py_FatalError("no mem to resize labellist in addlabel");
102 0 : lb = &ll->ll_label[ll->ll_nlabels++];
103 0 : lb->lb_type = type;
104 0 : lb->lb_str = strdup(str);
105 0 : if (Py_DebugFlag)
106 0 : printf("Label @ %8p, %d: %s\n", ll, ll->ll_nlabels,
107 : PyGrammar_LabelRepr(lb));
108 0 : return lb - ll->ll_label;
109 : }
110 :
111 : /* Same, but rather dies than adds */
112 :
113 : int
114 0 : findlabel(labellist *ll, int type, char *str)
115 : {
116 : int i;
117 :
118 0 : for (i = 0; i < ll->ll_nlabels; i++) {
119 0 : if (ll->ll_label[i].lb_type == type /*&&
120 : strcmp(ll->ll_label[i].lb_str, str) == 0*/)
121 0 : return i;
122 : }
123 0 : fprintf(stderr, "Label %d/'%s' not found\n", type, str);
124 0 : Py_FatalError("grammar.c:findlabel()");
125 0 : return 0; /* Make gcc -Wall happy */
126 : }
127 :
128 : /* Forward */
129 : static void translabel(grammar *, label *);
130 :
131 : void
132 0 : translatelabels(grammar *g)
133 : {
134 : int i;
135 :
136 : #ifdef Py_DEBUG
137 : printf("Translating labels ...\n");
138 : #endif
139 : /* Don't translate EMPTY */
140 0 : for (i = EMPTY+1; i < g->g_ll.ll_nlabels; i++)
141 0 : translabel(g, &g->g_ll.ll_label[i]);
142 0 : }
143 :
144 : static void
145 0 : translabel(grammar *g, label *lb)
146 : {
147 : int i;
148 :
149 0 : if (Py_DebugFlag)
150 0 : printf("Translating label %s ...\n", PyGrammar_LabelRepr(lb));
151 :
152 0 : if (lb->lb_type == NAME) {
153 0 : for (i = 0; i < g->g_ndfas; i++) {
154 0 : if (strcmp(lb->lb_str, g->g_dfa[i].d_name) == 0) {
155 0 : if (Py_DebugFlag)
156 0 : printf(
157 : "Label %s is non-terminal %d.\n",
158 : lb->lb_str,
159 0 : g->g_dfa[i].d_type);
160 0 : lb->lb_type = g->g_dfa[i].d_type;
161 0 : free(lb->lb_str);
162 0 : lb->lb_str = NULL;
163 0 : return;
164 : }
165 : }
166 0 : for (i = 0; i < (int)N_TOKENS; i++) {
167 0 : if (strcmp(lb->lb_str, _PyParser_TokenNames[i]) == 0) {
168 0 : if (Py_DebugFlag)
169 0 : printf("Label %s is terminal %d.\n",
170 : lb->lb_str, i);
171 0 : lb->lb_type = i;
172 0 : free(lb->lb_str);
173 0 : lb->lb_str = NULL;
174 0 : return;
175 : }
176 : }
177 0 : printf("Can't translate NAME label '%s'\n", lb->lb_str);
178 0 : return;
179 : }
180 :
181 0 : if (lb->lb_type == STRING) {
182 0 : if (isalpha(Py_CHARMASK(lb->lb_str[1])) ||
183 0 : lb->lb_str[1] == '_') {
184 : char *p;
185 : char *src;
186 : char *dest;
187 : size_t name_len;
188 0 : if (Py_DebugFlag)
189 0 : printf("Label %s is a keyword\n", lb->lb_str);
190 0 : lb->lb_type = NAME;
191 0 : src = lb->lb_str + 1;
192 0 : p = strchr(src, '\'');
193 0 : if (p)
194 0 : name_len = p - src;
195 : else
196 0 : name_len = strlen(src);
197 0 : dest = (char *)malloc(name_len + 1);
198 0 : if (!dest) {
199 0 : printf("Can't alloc dest '%s'\n", src);
200 0 : return;
201 : }
202 0 : strncpy(dest, src, name_len);
203 0 : dest[name_len] = '\0';
204 0 : free(lb->lb_str);
205 0 : lb->lb_str = dest;
206 : }
207 0 : else if (lb->lb_str[2] == lb->lb_str[0]) {
208 0 : int type = (int) PyToken_OneChar(lb->lb_str[1]);
209 0 : if (type != OP) {
210 0 : lb->lb_type = type;
211 0 : free(lb->lb_str);
212 0 : lb->lb_str = NULL;
213 : }
214 : else
215 0 : printf("Unknown OP label %s\n",
216 : lb->lb_str);
217 : }
218 0 : else if (lb->lb_str[2] && lb->lb_str[3] == lb->lb_str[0]) {
219 0 : int type = (int) PyToken_TwoChars(lb->lb_str[1],
220 0 : lb->lb_str[2]);
221 0 : if (type != OP) {
222 0 : lb->lb_type = type;
223 0 : free(lb->lb_str);
224 0 : lb->lb_str = NULL;
225 : }
226 : else
227 0 : printf("Unknown OP label %s\n",
228 : lb->lb_str);
229 : }
230 0 : else if (lb->lb_str[2] && lb->lb_str[3] && lb->lb_str[4] == lb->lb_str[0]) {
231 0 : int type = (int) PyToken_ThreeChars(lb->lb_str[1],
232 0 : lb->lb_str[2],
233 0 : lb->lb_str[3]);
234 0 : if (type != OP) {
235 0 : lb->lb_type = type;
236 0 : free(lb->lb_str);
237 0 : lb->lb_str = NULL;
238 : }
239 : else
240 0 : printf("Unknown OP label %s\n",
241 : lb->lb_str);
242 : }
243 : else
244 0 : printf("Can't translate STRING label %s\n",
245 : lb->lb_str);
246 : }
247 : else
248 0 : printf("Can't translate label '%s'\n",
249 : PyGrammar_LabelRepr(lb));
250 : }
|