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