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