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