grammar.c revision 588633daa2fe7276ae4b0c99723094add0d965ff
1/***********************************************************
2Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
3Amsterdam, The Netherlands.
4
5                        All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* Grammar implementation */
26
27#include "pgenheaders.h"
28
29#include <ctype.h>
30
31#include "assert.h"
32#include "token.h"
33#include "grammar.h"
34
35extern int debugging;
36
37grammar *
38newgrammar(start)
39	int start;
40{
41	grammar *g;
42
43	g = NEW(grammar, 1);
44	if (g == NULL)
45		fatal("no mem for new grammar");
46	g->g_ndfas = 0;
47	g->g_dfa = NULL;
48	g->g_start = start;
49	g->g_ll.ll_nlabels = 0;
50	g->g_ll.ll_label = NULL;
51	g->g_accel = 0;
52	return g;
53}
54
55dfa *
56adddfa(g, type, name)
57	grammar *g;
58	int type;
59	char *name;
60{
61	dfa *d;
62
63	RESIZE(g->g_dfa, dfa, g->g_ndfas + 1);
64	if (g->g_dfa == NULL)
65		fatal("no mem to resize dfa in adddfa");
66	d = &g->g_dfa[g->g_ndfas++];
67	d->d_type = type;
68	d->d_name = name;
69	d->d_nstates = 0;
70	d->d_state = NULL;
71	d->d_initial = -1;
72	d->d_first = NULL;
73	return d; /* Only use while fresh! */
74}
75
76int
77addstate(d)
78	dfa *d;
79{
80	state *s;
81
82	RESIZE(d->d_state, state, d->d_nstates + 1);
83	if (d->d_state == NULL)
84		fatal("no mem to resize state in addstate");
85	s = &d->d_state[d->d_nstates++];
86	s->s_narcs = 0;
87	s->s_arc = NULL;
88	s->s_lower = 0;
89	s->s_upper = 0;
90	s->s_accel = NULL;
91	s->s_accept = 0;
92	return s - d->d_state;
93}
94
95void
96addarc(d, from, to, lbl)
97	dfa *d;
98	int lbl;
99{
100	state *s;
101	arc *a;
102
103	assert(0 <= from && from < d->d_nstates);
104	assert(0 <= to && to < d->d_nstates);
105
106	s = &d->d_state[from];
107	RESIZE(s->s_arc, arc, s->s_narcs + 1);
108	if (s->s_arc == NULL)
109		fatal("no mem to resize arc list in addarc");
110	a = &s->s_arc[s->s_narcs++];
111	a->a_lbl = lbl;
112	a->a_arrow = to;
113}
114
115int
116addlabel(ll, type, str)
117	labellist *ll;
118	int type;
119	char *str;
120{
121	int i;
122	label *lb;
123
124	for (i = 0; i < ll->ll_nlabels; i++) {
125		if (ll->ll_label[i].lb_type == type &&
126			strcmp(ll->ll_label[i].lb_str, str) == 0)
127			return i;
128	}
129	RESIZE(ll->ll_label, label, ll->ll_nlabels + 1);
130	if (ll->ll_label == NULL)
131		fatal("no mem to resize labellist in addlabel");
132	lb = &ll->ll_label[ll->ll_nlabels++];
133	lb->lb_type = type;
134	lb->lb_str = str; /* XXX strdup(str) ??? */
135	return lb - ll->ll_label;
136}
137
138/* Same, but rather dies than adds */
139
140int
141findlabel(ll, type, str)
142	labellist *ll;
143	int type;
144	char *str;
145{
146	int i;
147
148	for (i = 0; i < ll->ll_nlabels; i++) {
149		if (ll->ll_label[i].lb_type == type /*&&
150			strcmp(ll->ll_label[i].lb_str, str) == 0*/)
151			return i;
152	}
153	fprintf(stderr, "Label %d/'%s' not found\n", type, str);
154	fatal("grammar.c:findlabel()");
155	/*NOTREACHED*/
156}
157
158/* Forward */
159static void translabel PROTO((grammar *, label *));
160
161void
162translatelabels(g)
163	grammar *g;
164{
165	int i;
166
167#ifdef DEBUG
168	printf("Translating labels ...\n");
169#endif
170	/* Don't translate EMPTY */
171	for (i = EMPTY+1; i < g->g_ll.ll_nlabels; i++)
172		translabel(g, &g->g_ll.ll_label[i]);
173}
174
175static void
176translabel(g, lb)
177	grammar *g;
178	label *lb;
179{
180	int i;
181
182	if (debugging)
183		printf("Translating label %s ...\n", labelrepr(lb));
184
185	if (lb->lb_type == NAME) {
186		for (i = 0; i < g->g_ndfas; i++) {
187			if (strcmp(lb->lb_str, g->g_dfa[i].d_name) == 0) {
188				if (debugging)
189					printf("Label %s is non-terminal %d.\n",
190						lb->lb_str,
191						g->g_dfa[i].d_type);
192				lb->lb_type = g->g_dfa[i].d_type;
193				lb->lb_str = NULL;
194				return;
195			}
196		}
197		for (i = 0; i < (int)N_TOKENS; i++) {
198			if (strcmp(lb->lb_str, tok_name[i]) == 0) {
199				if (debugging)
200					printf("Label %s is terminal %d.\n",
201						lb->lb_str, i);
202				lb->lb_type = i;
203				lb->lb_str = NULL;
204				return;
205			}
206		}
207		printf("Can't translate NAME label '%s'\n", lb->lb_str);
208		return;
209	}
210
211	if (lb->lb_type == STRING) {
212		if (isalpha(lb->lb_str[1])) {
213			char *p;
214			if (debugging)
215				printf("Label %s is a keyword\n", lb->lb_str);
216			lb->lb_type = NAME;
217			lb->lb_str++;
218			p = strchr(lb->lb_str, '\'');
219			if (p)
220				*p = '\0';
221		}
222		else if (lb->lb_str[2] == lb->lb_str[0]) {
223			int type = (int) tok_1char(lb->lb_str[1]);
224			if (type != OP) {
225				lb->lb_type = type;
226				lb->lb_str = NULL;
227			}
228			else
229				printf("Unknown OP label %s\n",
230					lb->lb_str);
231		}
232		else if (lb->lb_str[2] && lb->lb_str[3] == lb->lb_str[0]) {
233			int type = (int) tok_2char(lb->lb_str[1],
234						   lb->lb_str[2]);
235			if (type != OP) {
236				lb->lb_type = type;
237				lb->lb_str = NULL;
238			}
239			else
240				printf("Unknown OP label %s\n",
241					lb->lb_str);
242		}
243		else
244			printf("Can't translate STRING label %s\n",
245				lb->lb_str);
246	}
247	else
248		printf("Can't translate label '%s'\n", labelrepr(lb));
249}
250