blob: ad9c2b010aa3af844405714195c87a425292eb19 [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* Grammar implementation */
2
3#include <stdio.h>
4#include <ctype.h>
5
6#include "PROTO.h"
7#include "malloc.h"
8#include "assert.h"
9#include "token.h"
10#include "grammar.h"
11
12extern int debugging;
13
14grammar *
15newgrammar(start)
16 int start;
17{
18 grammar *g;
19
20 g = NEW(grammar, 1);
21 if (g == NULL)
22 fatal("no mem for new grammar");
23 g->g_ndfas = 0;
24 g->g_dfa = NULL;
25 g->g_start = start;
26 g->g_ll.ll_nlabels = 0;
27 g->g_ll.ll_label = NULL;
28 return g;
29}
30
31dfa *
32adddfa(g, type, name)
33 grammar *g;
34 int type;
35 char *name;
36{
37 dfa *d;
38
39 RESIZE(g->g_dfa, dfa, g->g_ndfas + 1);
40 if (g->g_dfa == NULL)
41 fatal("no mem to resize dfa in adddfa");
42 d = &g->g_dfa[g->g_ndfas++];
43 d->d_type = type;
44 d->d_name = name;
45 d->d_nstates = 0;
46 d->d_state = NULL;
47 d->d_initial = -1;
48 d->d_first = NULL;
49 return d; /* Only use while fresh! */
50}
51
52int
53addstate(d)
54 dfa *d;
55{
56 state *s;
57
58 RESIZE(d->d_state, state, d->d_nstates + 1);
59 if (d->d_state == NULL)
60 fatal("no mem to resize state in addstate");
61 s = &d->d_state[d->d_nstates++];
62 s->s_narcs = 0;
63 s->s_arc = NULL;
64 return s - d->d_state;
65}
66
67void
68addarc(d, from, to, lbl)
69 dfa *d;
70 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 s = &d->d_state[from];
79 RESIZE(s->s_arc, arc, s->s_narcs + 1);
80 if (s->s_arc == NULL)
81 fatal("no mem to resize arc list in addarc");
82 a = &s->s_arc[s->s_narcs++];
83 a->a_lbl = lbl;
84 a->a_arrow = to;
85}
86
87int
88addlabel(ll, type, str)
89 labellist *ll;
90 int type;
91 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 RESIZE(ll->ll_label, label, ll->ll_nlabels + 1);
102 if (ll->ll_label == NULL)
103 fatal("no mem to resize labellist in addlabel");
104 lb = &ll->ll_label[ll->ll_nlabels++];
105 lb->lb_type = type;
106 lb->lb_str = str; /* XXX strdup(str) ??? */
107 return lb - ll->ll_label;
108}
109
110/* Same, but rather dies than adds */
111
112int
113findlabel(ll, type, str)
114 labellist *ll;
115 int type;
116 char *str;
117{
118 int i;
119 label *lb;
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 abort();
128}
129
130static void
131translabel(g, lb)
132 grammar *g;
133 label *lb;
134{
135 int i;
136
137 if (debugging)
138 printf("Translating label %s ...\n", labelrepr(lb));
139
140 if (lb->lb_type == NAME) {
141 for (i = 0; i < g->g_ndfas; i++) {
142 if (strcmp(lb->lb_str, g->g_dfa[i].d_name) == 0) {
143 if (debugging)
144 printf("Label %s is non-terminal %d.\n",
145 lb->lb_str,
146 g->g_dfa[i].d_type);
147 lb->lb_type = g->g_dfa[i].d_type;
148 lb->lb_str = NULL;
149 return;
150 }
151 }
152 for (i = 0; i < (int)N_TOKENS; i++) {
153 if (strcmp(lb->lb_str, tok_name[i]) == 0) {
154 if (debugging)
155 printf("Label %s is terminal %d.\n",
156 lb->lb_str, i);
157 lb->lb_type = i;
158 lb->lb_str = NULL;
159 return;
160 }
161 }
162 printf("Can't translate NAME label '%s'\n", lb->lb_str);
163 return;
164 }
165
166 if (lb->lb_type == STRING) {
167 if (isalpha(lb->lb_str[1])) {
168 char *p, *strchr();
169 if (debugging)
170 printf("Label %s is a keyword\n", lb->lb_str);
171 lb->lb_type = NAME;
172 lb->lb_str++;
173 p = strchr(lb->lb_str, '\'');
174 if (p)
175 *p = '\0';
176 }
177 else {
178 if (lb->lb_str[2] == lb->lb_str[0]) {
179 int type = (int) tok_1char(lb->lb_str[1]);
180 if (type != OP) {
181 lb->lb_type = type;
182 lb->lb_str = NULL;
183 }
184 else
185 printf("Unknown OP label %s\n",
186 lb->lb_str);
187 }
188 else
189 printf("Can't translate STRING label %s\n",
190 lb->lb_str);
191 }
192 }
193 else
194 printf("Can't translate label '%s'\n", labelrepr(lb));
195}
196
197void
198translatelabels(g)
199 grammar *g;
200{
201 int i;
202
203 printf("Translating labels ...\n");
204 /* Don't translate EMPTY */
205 for (i = EMPTY+1; i < g->g_ll.ll_nlabels; i++)
206 translabel(g, &g->g_ll.ll_label[i]);
207}