ยปCore Development>Code coverage>Parser/grammar.c

Python code coverage for Parser/grammar.c

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