Changeset 388 for python/vendor/current/Parser/parser.c
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Parser/parser.c
r2 r388 30 30 s_reset(stack *s) 31 31 { 32 32 s->s_top = &s->s_base[MAXSTACK]; 33 33 } 34 34 … … 38 38 s_push(register stack *s, dfa *d, node *parent) 39 39 { 40 41 42 43 44 45 46 47 48 49 40 register stackentry *top; 41 if (s->s_top == s->s_base) { 42 fprintf(stderr, "s_push: parser stack overflow\n"); 43 return E_NOMEM; 44 } 45 top = --s->s_top; 46 top->s_dfa = d; 47 top->s_parent = parent; 48 top->s_state = 0; 49 return 0; 50 50 } 51 51 … … 55 55 s_pop(register stack *s) 56 56 { 57 58 59 57 if (s_empty(s)) 58 Py_FatalError("s_pop: parser stack underflow -- FATAL"); 59 s->s_top++; 60 60 } 61 61 … … 72 72 PyParser_New(grammar *g, int start) 73 73 { 74 75 76 77 78 79 80 81 74 parser_state *ps; 75 76 if (!g->g_accel) 77 PyGrammar_AddAccelerators(g); 78 ps = (parser_state *)PyMem_MALLOC(sizeof(parser_state)); 79 if (ps == NULL) 80 return NULL; 81 ps->p_grammar = g; 82 82 #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD 83 84 #endif 85 86 87 88 89 90 91 92 83 ps->p_flags = 0; 84 #endif 85 ps->p_tree = PyNode_New(start); 86 if (ps->p_tree == NULL) { 87 PyMem_FREE(ps); 88 return NULL; 89 } 90 s_reset(&ps->p_stack); 91 (void) s_push(&ps->p_stack, PyGrammar_FindDFA(g, start), ps->p_tree); 92 return ps; 93 93 } 94 94 … … 96 96 PyParser_Delete(parser_state *ps) 97 97 { 98 99 100 101 98 /* NB If you want to save the parse tree, 99 you must set p_tree to NULL before calling delparser! */ 100 PyNode_Free(ps->p_tree); 101 PyMem_FREE(ps); 102 102 } 103 103 … … 108 108 shift(register stack *s, int type, char *str, int newstate, int lineno, int col_offset) 109 109 { 110 111 112 113 114 115 116 110 int err; 111 assert(!s_empty(s)); 112 err = PyNode_AddChild(s->s_top->s_parent, type, str, lineno, col_offset); 113 if (err) 114 return err; 115 s->s_top->s_state = newstate; 116 return 0; 117 117 } 118 118 … … 120 120 push(register stack *s, int type, dfa *d, int newstate, int lineno, int col_offset) 121 121 { 122 123 124 125 126 127 128 129 130 122 int err; 123 register node *n; 124 n = s->s_top->s_parent; 125 assert(!s_empty(s)); 126 err = PyNode_AddChild(n, type, (char *)NULL, lineno, col_offset); 127 if (err) 128 return err; 129 s->s_top->s_state = newstate; 130 return s_push(s, d, CHILD(n, NCH(n)-1)); 131 131 } 132 132 … … 137 137 classify(parser_state *ps, int type, char *str) 138 138 { 139 140 141 142 143 144 145 146 147 148 149 150 139 grammar *g = ps->p_grammar; 140 register int n = g->g_ll.ll_nlabels; 141 142 if (type == NAME) { 143 register char *s = str; 144 register label *l = g->g_ll.ll_label; 145 register int i; 146 for (i = n; i > 0; i--, l++) { 147 if (l->lb_type != NAME || l->lb_str == NULL || 148 l->lb_str[0] != s[0] || 149 strcmp(l->lb_str, s) != 0) 150 continue; 151 151 #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD 152 153 s[0] == 'p' && strcmp(s, "print") == 0) {154 155 156 #endif 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 152 if (ps->p_flags & CO_FUTURE_PRINT_FUNCTION && 153 s[0] == 'p' && strcmp(s, "print") == 0) { 154 break; /* no longer a keyword */ 155 } 156 #endif 157 D(printf("It's a keyword\n")); 158 return n - i; 159 } 160 } 161 162 { 163 register label *l = g->g_ll.ll_label; 164 register int i; 165 for (i = n; i > 0; i--, l++) { 166 if (l->lb_type == type && l->lb_str == NULL) { 167 D(printf("It's a token we know\n")); 168 return n - i; 169 } 170 } 171 } 172 173 D(printf("Illegal token\n")); 174 return -1; 175 175 } 176 176 … … 179 179 future_hack(parser_state *ps) 180 180 { 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 181 node *n = ps->p_stack.s_top->s_parent; 182 node *ch, *cch; 183 int i; 184 185 /* from __future__ import ..., must have at least 4 children */ 186 n = CHILD(n, 0); 187 if (NCH(n) < 4) 188 return; 189 ch = CHILD(n, 0); 190 if (STR(ch) == NULL || strcmp(STR(ch), "from") != 0) 191 return; 192 ch = CHILD(n, 1); 193 if (NCH(ch) == 1 && STR(CHILD(ch, 0)) && 194 strcmp(STR(CHILD(ch, 0)), "__future__") != 0) 195 return; 196 ch = CHILD(n, 3); 197 /* ch can be a star, a parenthesis or import_as_names */ 198 if (TYPE(ch) == STAR) 199 return; 200 if (TYPE(ch) == LPAR) 201 ch = CHILD(n, 4); 202 203 for (i = 0; i < NCH(ch); i += 2) { 204 cch = CHILD(ch, i); 205 if (NCH(cch) >= 1 && TYPE(CHILD(cch, 0)) == NAME) { 206 char *str_ch = STR(CHILD(cch, 0)); 207 if (strcmp(str_ch, FUTURE_WITH_STATEMENT) == 0) { 208 ps->p_flags |= CO_FUTURE_WITH_STATEMENT; 209 } else if (strcmp(str_ch, FUTURE_PRINT_FUNCTION) == 0) { 210 ps->p_flags |= CO_FUTURE_PRINT_FUNCTION; 211 } else if (strcmp(str_ch, FUTURE_UNICODE_LITERALS) == 0) { 212 ps->p_flags |= CO_FUTURE_UNICODE_LITERALS; 213 } 214 } 215 } 216 216 } 217 217 #endif /* future keyword */ … … 219 219 int 220 220 PyParser_AddToken(register parser_state *ps, register int type, char *str, 221 222 { 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 221 int lineno, int col_offset, int *expected_ret) 222 { 223 register int ilabel; 224 int err; 225 226 D(printf("Token %s/'%s' ... ", _PyParser_TokenNames[type], str)); 227 228 /* Find out which label this token is */ 229 ilabel = classify(ps, type, str); 230 if (ilabel < 0) 231 return E_SYNTAX; 232 233 /* Loop until the token is shifted or an error occurred */ 234 for (;;) { 235 /* Fetch the current dfa and state */ 236 register dfa *d = ps->p_stack.s_top->s_dfa; 237 register state *s = &d->d_state[ps->p_stack.s_top->s_state]; 238 239 D(printf(" DFA '%s', state %d:", 240 d->d_name, ps->p_stack.s_top->s_state)); 241 242 /* Check accelerator */ 243 if (s->s_lower <= ilabel && ilabel < s->s_upper) { 244 register int x = s->s_accel[ilabel - s->s_lower]; 245 if (x != -1) { 246 if (x & (1<<7)) { 247 /* Push non-terminal */ 248 int nt = (x >> 8) + NT_OFFSET; 249 int arrow = x & ((1<<7)-1); 250 dfa *d1 = PyGrammar_FindDFA( 251 ps->p_grammar, nt); 252 if ((err = push(&ps->p_stack, nt, d1, 253 arrow, lineno, col_offset)) > 0) { 254 D(printf(" MemError: push\n")); 255 return err; 256 } 257 D(printf(" Push ...\n")); 258 continue; 259 } 260 261 /* Shift the token */ 262 if ((err = shift(&ps->p_stack, type, str, 263 x, lineno, col_offset)) > 0) { 264 D(printf(" MemError: shift.\n")); 265 return err; 266 } 267 D(printf(" Shift.\n")); 268 /* Pop while we are in an accept-only state */ 269 while (s = &d->d_state 270 [ps->p_stack.s_top->s_state], 271 s->s_accept && s->s_narcs == 1) { 272 D(printf(" DFA '%s', state %d: " 273 "Direct pop.\n", 274 d->d_name, 275 ps->p_stack.s_top->s_state)); 276 276 #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD 277 278 279 280 281 #endif 282 283 284 285 286 287 288 289 290 291 292 293 277 if (d->d_name[0] == 'i' && 278 strcmp(d->d_name, 279 "import_stmt") == 0) 280 future_hack(ps); 281 #endif 282 s_pop(&ps->p_stack); 283 if (s_empty(&ps->p_stack)) { 284 D(printf(" ACCEPT.\n")); 285 return E_DONE; 286 } 287 d = ps->p_stack.s_top->s_dfa; 288 } 289 return E_OK; 290 } 291 } 292 293 if (s->s_accept) { 294 294 #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD 295 296 297 298 #endif 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 else 318 319 320 321 295 if (d->d_name[0] == 'i' && 296 strcmp(d->d_name, "import_stmt") == 0) 297 future_hack(ps); 298 #endif 299 /* Pop this dfa and try again */ 300 s_pop(&ps->p_stack); 301 D(printf(" Pop ...\n")); 302 if (s_empty(&ps->p_stack)) { 303 D(printf(" Error: bottom of stack.\n")); 304 return E_SYNTAX; 305 } 306 continue; 307 } 308 309 /* Stuck, report syntax error */ 310 D(printf(" Error.\n")); 311 if (expected_ret) { 312 if (s->s_lower == s->s_upper - 1) { 313 /* Only one possible expected token */ 314 *expected_ret = ps->p_grammar-> 315 g_ll.ll_label[s->s_lower].lb_type; 316 } 317 else 318 *expected_ret = -1; 319 } 320 return E_SYNTAX; 321 } 322 322 } 323 323 … … 330 330 dumptree(grammar *g, node *n) 331 331 { 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 332 int i; 333 334 if (n == NULL) 335 printf("NIL"); 336 else { 337 label l; 338 l.lb_type = TYPE(n); 339 l.lb_str = STR(n); 340 printf("%s", PyGrammar_LabelRepr(&l)); 341 if (ISNONTERMINAL(TYPE(n))) { 342 printf("("); 343 for (i = 0; i < NCH(n); i++) { 344 if (i > 0) 345 printf(","); 346 dumptree(g, CHILD(n, i)); 347 } 348 printf(")"); 349 } 350 } 351 351 } 352 352 … … 354 354 showtree(grammar *g, node *n) 355 355 { 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 356 int i; 357 358 if (n == NULL) 359 return; 360 if (ISNONTERMINAL(TYPE(n))) { 361 for (i = 0; i < NCH(n); i++) 362 showtree(g, CHILD(n, i)); 363 } 364 else if (ISTERMINAL(TYPE(n))) { 365 printf("%s", _PyParser_TokenNames[TYPE(n)]); 366 if (TYPE(n) == NUMBER || TYPE(n) == NAME) 367 printf("(%s)", STR(n)); 368 printf(" "); 369 } 370 else 371 printf("? "); 372 372 } 373 373 … … 375 375 printtree(parser_state *ps) 376 376 { 377 378 379 380 381 382 383 384 385 386 387 377 if (Py_DebugFlag) { 378 printf("Parse tree:\n"); 379 dumptree(ps->p_grammar, ps->p_tree); 380 printf("\n"); 381 printf("Tokens:\n"); 382 showtree(ps->p_grammar, ps->p_tree); 383 printf("\n"); 384 } 385 printf("Listing:\n"); 386 PyNode_ListTree(ps->p_tree); 387 printf("\n"); 388 388 } 389 389 … … 420 420 As an example, consider this grammar: 421 421 422 expr: 423 term: 422 expr: term (OP term)* 423 term: CONSTANT | '(' expr ')' 424 424 425 425 The DFA corresponding to the rule for expr is: 426 426 427 427 ------->.---term-->.-------> 428 429 430 428 ^ | 429 | | 430 \----OP----/ 431 431 432 432 The parse tree generated for the input a+b is:
Note:
See TracChangeset
for help on using the changeset viewer.