Commit | Line | Data |
---|---|---|
aebba157 GM |
1 | %{ |
2 | typedef struct string { | |
3 | int | |
4 | hashval, | |
5 | length; | |
6 | char | |
7 | *string; | |
8 | struct string | |
9 | *next; | |
10 | } string_t; | |
11 | ||
9b9748d9 GM |
12 | /* |
13 | * The deal with these is that they exist on various lists. | |
14 | * | |
15 | * First off, they are on a temporary list during the time they | |
16 | * are in the active focus of the parser. | |
17 | * | |
18 | * Secondly, they live on one of three queues: | |
19 | * 1. Variables | |
20 | * 2. Targets | |
21 | * 3. Actions | |
22 | * (and, we restrict any given one to live on one and only one such list) | |
23 | * | |
24 | * Also, they may live on the list of values for someone else's variable, | |
25 | * or as someone's dependancy. | |
26 | */ | |
27 | ||
aebba157 | 28 | typedef struct same { |
aebba157 | 29 | string_t |
9b9748d9 GM |
30 | *string; /* My name */ |
31 | struct same | |
32 | *nexttoken, /* Next pointer */ | |
33 | *lasttoken, /* Back pointer */ | |
34 | *depend_list, /* If target, dependancies */ | |
35 | *action_list, /* If target, actions */ | |
36 | *value_list; /* If variable, value list */ | |
aebba157 GM |
37 | } same_t; |
38 | ||
aebba157 GM |
39 | %} |
40 | ||
41 | %union { | |
42 | string_t *string; | |
43 | same_t *same; | |
9b9748d9 | 44 | int intval; |
aebba157 GM |
45 | } |
46 | ||
b430ae6a | 47 | %start makefile |
9b9748d9 GM |
48 | %token <string> TOKEN QUOTED_STRING |
49 | %token <intval> MACRO_CHAR BREAK_CHAR WHITE_SPACE NL END_OF_FILE | |
50 | %token <intval> ':' '=' '$' '{' '}' | |
aebba157 | 51 | %type <same> target assignment actions action tokens token |
9b9748d9 | 52 | %type <intval> special_chars white_space macro_char |
aebba157 | 53 | %% |
9b9748d9 | 54 | |
aebba157 GM |
55 | makefile : lines END_OF_FILE; |
56 | ||
57 | lines : line | |
58 | | lines line | |
59 | ; | |
60 | ||
9b9748d9 GM |
61 | line : maybe_white_space NL |
62 | | assignment | |
63 | | target_action | |
aebba157 GM |
64 | ; |
65 | ||
9b9748d9 GM |
66 | assignment : |
67 | token maybe_white_space '=' maybe_white_space tokens maybe_white_space NL | |
aebba157 | 68 | { |
9b9748d9 GM |
69 | assign($1, $5); |
70 | } | |
71 | | token maybe_white_space '=' maybe_white_space NL | |
72 | { | |
0859be39 | 73 | assign($1, same_copy(null)); |
aebba157 GM |
74 | } |
75 | ; | |
76 | ||
9b9748d9 GM |
77 | target_action: target actions |
78 | { | |
79 | add_targets_actions($1, $2); | |
80 | } | |
81 | | target | |
aebba157 | 82 | { |
0859be39 | 83 | add_targets_actions($1, same_copy(null)); |
9b9748d9 GM |
84 | } |
85 | ; | |
86 | ||
87 | target : | |
88 | tokens maybe_white_space ':' maybe_white_space tokens maybe_white_space NL | |
89 | { | |
90 | $$ = add_depends($1, $5); | |
91 | } | |
92 | | tokens maybe_white_space ':' maybe_white_space NL | |
93 | { | |
0859be39 | 94 | $$ = add_depends($1, same_copy(null)); |
aebba157 GM |
95 | } |
96 | ; | |
97 | ||
98 | actions: action | |
99 | | actions action | |
100 | { | |
9b9748d9 | 101 | $$ = same_cat($1, $2); |
aebba157 GM |
102 | } |
103 | ; | |
104 | ||
9b9748d9 | 105 | action: white_space tokens NL |
aebba157 GM |
106 | { |
107 | $$ = $2; | |
108 | } | |
109 | ; | |
110 | ||
111 | tokens : token | |
112 | | tokens token | |
113 | { | |
9b9748d9 | 114 | $$ = same_cat($1, $2); |
aebba157 GM |
115 | } |
116 | ; | |
9b9748d9 | 117 | |
aebba157 GM |
118 | token: TOKEN |
119 | { | |
9b9748d9 GM |
120 | $$ = same_item($1); |
121 | } | |
122 | | QUOTED_STRING | |
123 | { | |
124 | $$ = same_item($1); | |
125 | } | |
126 | | '$' macro_char | |
127 | { | |
128 | char buffer[3]; | |
129 | ||
130 | buffer[0] = '$'; | |
131 | buffer[1] = $2; | |
132 | buffer[2] = 0; | |
133 | ||
134 | $$ = same_item(string_lookup(buffer)); | |
135 | } | |
136 | | special_chars | |
137 | { | |
138 | char buffer[2]; | |
139 | ||
140 | buffer[0] = $1; | |
141 | buffer[1] = 0; | |
142 | ||
143 | $$ = same_item(string_lookup(buffer)); | |
144 | } | |
145 | | '$' '{' token '}' | |
146 | { | |
b430ae6a | 147 | $$ = value_of($3); |
aebba157 GM |
148 | } |
149 | ; | |
9b9748d9 GM |
150 | |
151 | macro_char: MACRO_CHAR | |
152 | | '$' | |
153 | ; | |
154 | ||
155 | special_chars : BREAK_CHAR | |
156 | | MACRO_CHAR | |
157 | | white_space | |
158 | ; | |
159 | ||
160 | maybe_white_space: | |
161 | | white_space; | |
162 | ||
163 | white_space : WHITE_SPACE | |
164 | | white_space WHITE_SPACE | |
165 | ; | |
166 | ||
aebba157 GM |
167 | %% |
168 | #include <stdio.h> | |
169 | ||
170 | static int last_char, last_saved = 0; | |
171 | static int column = 0, lineno = 1; | |
172 | ||
173 | ||
9b9748d9 GM |
174 | static string_t |
175 | *strings = 0; | |
176 | static same_t | |
1d1968a6 GM |
177 | *variables = 0, |
178 | *targets = 0, | |
179 | *actions = 0; | |
9b9748d9 | 180 | |
aebba157 | 181 | static same_t |
0859be39 GM |
182 | *null, |
183 | *blank, | |
184 | *newline; | |
aebba157 GM |
185 | |
186 | extern char *malloc(); | |
187 | ||
0859be39 GM |
188 | static unsigned int |
189 | clock = -1; | |
190 | ||
191 | struct { | |
192 | same_t *first; | |
193 | int next; | |
194 | } visit_stack[20]; /* 20 maximum */ | |
195 | ||
196 | #define visit(what,via) \ | |
197 | (visit_stack[++clock].next = 0, visit_stack[clock].first = via = what) | |
b430ae6a | 198 | #define visited(via) (visitcheck(via) || ((via) == 0) \ |
1d1968a6 | 199 | || (visit_stack[clock].next && (via == visit_stack[clock].first))) |
0859be39 GM |
200 | #define visit_next(via) (visit_stack[clock].next = 1, (via) = (via)->nexttoken) |
201 | #define visit_end() (clock--) | |
202 | ||
9b9748d9 GM |
203 | yyerror(s) |
204 | char *s; | |
aebba157 | 205 | { |
9b9748d9 GM |
206 | fprintf(stderr, "line %d, character %d: %s\n", lineno, column, s); |
207 | do_dump(); | |
208 | } | |
aebba157 | 209 | |
b430ae6a GM |
210 | int |
211 | visitcheck(same) | |
212 | same_t *same; | |
213 | { | |
214 | if (same->string == 0) { | |
215 | yyerror("BUG - freed 'same' in use..."); | |
216 | exit(1); | |
217 | } | |
218 | return 0; | |
219 | } | |
220 | ||
9b9748d9 GM |
221 | int |
222 | string_hashof(string, length) | |
223 | char *string; | |
224 | int length; | |
225 | { | |
226 | register int i = 0; | |
227 | ||
228 | while (length--) { | |
229 | i = (i<<3) + *string ^ ((i>>28)&0x7); | |
230 | } | |
231 | return i; | |
aebba157 GM |
232 | } |
233 | ||
9b9748d9 GM |
234 | int |
235 | string_same(s1, s2) | |
236 | string_t | |
237 | *s1, *s2; | |
aebba157 | 238 | { |
9b9748d9 GM |
239 | if ((s1->hashval == s2->hashval) && (s1->length == s2->length) |
240 | && (memcmp(s1->string, s2->string, s1->length) == 0)) { | |
241 | return 1; | |
242 | } else { | |
243 | return 0; | |
244 | } | |
aebba157 GM |
245 | } |
246 | ||
9b9748d9 GM |
247 | string_t * |
248 | string_lookup(string) | |
249 | char *string; | |
aebba157 | 250 | { |
9b9748d9 GM |
251 | string_t ours; |
252 | string_t *ptr; | |
253 | ||
254 | ours.length = strlen(string); | |
255 | ours.hashval = string_hashof(string, ours.length); | |
256 | ours.string = string; | |
257 | ||
258 | for (ptr = strings; ptr; ptr = ptr->next) { | |
259 | if (string_same(&ours, ptr)) { | |
260 | return ptr; | |
261 | } | |
262 | } | |
263 | if ((ptr = (string_t *)malloc(sizeof *ptr)) == 0) { | |
264 | fprintf(stderr, "No space to add string *%s*!\n", string); | |
265 | exit(1); | |
266 | } | |
267 | ptr->hashval = ours.hashval; | |
268 | ptr->length = ours.length; | |
269 | if ((ptr->string = malloc(ours.length+1)) == 0) { | |
270 | fprintf(stderr, "No space to add literal *%s*!\n", string); | |
271 | exit(1); | |
272 | } | |
273 | memcpy(ptr->string, string, ours.length+1); | |
274 | ptr->next = strings; | |
275 | strings = ptr; | |
276 | return ptr; | |
aebba157 GM |
277 | } |
278 | ||
279 | same_t * | |
9b9748d9 | 280 | same_search(list, token) |
aebba157 | 281 | same_t |
9b9748d9 GM |
282 | *list, |
283 | *token; | |
aebba157 | 284 | { |
9b9748d9 GM |
285 | same_t *ptr; |
286 | ||
0859be39 GM |
287 | ptr = list; |
288 | for (visit(list, ptr); !visited(ptr); visit_next(ptr)) { | |
9b9748d9 | 289 | string_t *string; |
aebba157 | 290 | |
9b9748d9 GM |
291 | string = ptr->string; |
292 | if (string_same(string, token->string)) { | |
0859be39 | 293 | visit_end(); |
9b9748d9 GM |
294 | return ptr; |
295 | } | |
296 | } | |
0859be39 | 297 | visit_end(); |
9b9748d9 GM |
298 | return 0; |
299 | } | |
aebba157 GM |
300 | |
301 | same_t * | |
9b9748d9 | 302 | same_cat(list, tokens) |
aebba157 | 303 | same_t |
9b9748d9 GM |
304 | *list, |
305 | *tokens; | |
aebba157 | 306 | { |
9b9748d9 | 307 | same_t *last; |
aebba157 | 308 | |
1d1968a6 GM |
309 | if (list) { |
310 | last = tokens->lasttoken; | |
311 | tokens->lasttoken = list->lasttoken; | |
312 | list->lasttoken = last; | |
313 | tokens->lasttoken->nexttoken = tokens; | |
314 | last->nexttoken = list; | |
315 | return list; | |
316 | } else { | |
317 | return tokens; | |
318 | } | |
aebba157 GM |
319 | } |
320 | ||
321 | same_t * | |
9b9748d9 | 322 | same_item(string) |
aebba157 GM |
323 | string_t *string; |
324 | { | |
325 | same_t *ptr; | |
326 | ||
327 | if ((ptr = (same_t *)malloc(sizeof *ptr)) == 0) { | |
328 | fprintf(stderr, "No more space for tokens!\n"); | |
329 | exit(1); | |
330 | } | |
9b9748d9 | 331 | memset((char *)ptr, 0, sizeof *ptr); |
0859be39 | 332 | ptr->nexttoken = ptr->lasttoken = ptr; |
aebba157 | 333 | ptr->string = string; |
aebba157 GM |
334 | return ptr; |
335 | } | |
336 | ||
9b9748d9 GM |
337 | same_t * |
338 | same_copy(same) | |
339 | same_t *same; | |
340 | { | |
0859be39 | 341 | same_t *head, *copy; |
9b9748d9 | 342 | |
1d1968a6 GM |
343 | head = 0; |
344 | for (visit(same, copy); !visited(copy); visit_next(copy)) { | |
9b9748d9 GM |
345 | same_t *ptr; |
346 | ||
0859be39 | 347 | ptr = same_item(copy->string); |
1d1968a6 | 348 | head = same_cat(head, ptr); |
9b9748d9 | 349 | } |
1d1968a6 | 350 | visit_end(); |
9b9748d9 GM |
351 | return head; |
352 | } | |
353 | ||
354 | void | |
0859be39 GM |
355 | same_free(list) |
356 | same_t *list; | |
9b9748d9 | 357 | { |
0859be39 | 358 | same_t *token, *ptr; |
9b9748d9 | 359 | |
0859be39 GM |
360 | token = list; |
361 | do { | |
9b9748d9 | 362 | ptr = token->nexttoken; |
b430ae6a | 363 | token->string = 0; |
9b9748d9 GM |
364 | (void) free((char *)token); |
365 | token = ptr; | |
0859be39 | 366 | } while (token != list); |
9b9748d9 GM |
367 | } |
368 | ||
369 | void | |
0859be39 | 370 | same_unlink(token) |
9b9748d9 | 371 | same_t |
0859be39 | 372 | *token; |
9b9748d9 | 373 | { |
1d1968a6 GM |
374 | if (token == 0) { |
375 | return; | |
376 | } | |
0859be39 GM |
377 | token->lasttoken->nexttoken = token->nexttoken; |
378 | token->nexttoken->lasttoken = token->lasttoken; | |
1d1968a6 | 379 | token->nexttoken = token->lasttoken = token; |
9b9748d9 GM |
380 | } |
381 | ||
382 | same_t * | |
383 | add_target(target) | |
384 | same_t | |
385 | *target; | |
386 | { | |
387 | same_t *ptr; | |
388 | ||
0859be39 | 389 | if ((ptr = same_search(targets, target)) == 0) { |
1d1968a6 GM |
390 | targets = same_cat(targets, target); |
391 | return target; | |
9b9748d9 | 392 | } else { |
1d1968a6 GM |
393 | ptr->action_list = same_cat(ptr->action_list, target->action_list); |
394 | ptr->depend_list = same_cat(ptr->depend_list, target->depend_list); | |
395 | return ptr; | |
9b9748d9 | 396 | } |
9b9748d9 GM |
397 | } |
398 | ||
399 | same_t * | |
400 | add_targets_actions(target, actions) | |
401 | same_t | |
402 | *target, | |
403 | *actions; | |
404 | { | |
b430ae6a | 405 | same_t *ptr; |
9b9748d9 | 406 | |
1d1968a6 GM |
407 | if (target == 0) { |
408 | return 0; | |
9b9748d9 | 409 | } |
1d1968a6 GM |
410 | do { |
411 | target->action_list = same_cat(target->action_list, | |
412 | same_copy(actions)); | |
b430ae6a GM |
413 | if ((ptr = target->nexttoken) == target) { |
414 | ptr = 0; | |
415 | } | |
1d1968a6 GM |
416 | same_unlink(target); |
417 | add_target(target); | |
418 | target = ptr; | |
b430ae6a | 419 | } while (target); |
1d1968a6 GM |
420 | |
421 | same_free(actions); | |
9b9748d9 GM |
422 | return 0; |
423 | } | |
424 | ||
425 | same_t * | |
426 | add_depends(target, depends) | |
427 | same_t | |
428 | *target, | |
429 | *depends; | |
430 | { | |
431 | same_t *original = target; | |
432 | ||
1d1968a6 | 433 | depends = same_cat(depends, same_copy(blank)); /* Separator */ |
9b9748d9 | 434 | |
0859be39 | 435 | for (visit(original, target); !visited(target); visit_next(target)) { |
1d1968a6 | 436 | target->depend_list = same_cat(target->depend_list, same_copy(depends)); |
9b9748d9 | 437 | } |
0859be39 | 438 | visit_end(); |
1d1968a6 | 439 | same_free(depends); |
0859be39 | 440 | |
9b9748d9 GM |
441 | return original; |
442 | } | |
443 | ||
444 | ||
445 | /* | |
446 | * We know that variable is a singleton | |
447 | */ | |
448 | ||
449 | void | |
450 | assign(variable, value) | |
451 | same_t | |
452 | *variable, | |
453 | *value; | |
454 | { | |
455 | same_t *ptr; | |
456 | ||
0859be39 | 457 | if ((ptr = same_search(variables, variable)) != 0) { |
9b9748d9 | 458 | same_free(ptr->value_list); |
0859be39 | 459 | same_unlink(ptr); |
1d1968a6 | 460 | same_free(ptr); |
9b9748d9 GM |
461 | } |
462 | variable->value_list = value; | |
1d1968a6 | 463 | variables = same_cat(variables, variable); |
9b9748d9 GM |
464 | } |
465 | ||
466 | same_t * | |
467 | value_of(variable) | |
468 | same_t *variable; | |
469 | { | |
0859be39 | 470 | same_t *ptr = same_search(variables, variable); |
9b9748d9 GM |
471 | |
472 | if (ptr == 0) { | |
1d1968a6 | 473 | return same_copy(null); |
9b9748d9 | 474 | } else { |
1d1968a6 | 475 | return same_copy(ptr->value_list); |
9b9748d9 GM |
476 | } |
477 | } | |
478 | ||
479 | ||
aebba157 GM |
480 | int |
481 | Getchar() | |
482 | { | |
483 | if (last_saved) { | |
484 | last_saved = 0; | |
485 | return last_char; | |
486 | } else { | |
487 | int c; | |
488 | c = getchar(); | |
489 | switch (c) { | |
490 | case '\n': | |
491 | lineno++; | |
492 | column = 0; | |
493 | break; | |
494 | default: | |
495 | column++; | |
496 | } | |
497 | return c; | |
498 | } | |
499 | } | |
500 | ||
aebba157 GM |
501 | |
502 | yylex() | |
503 | { | |
504 | #define ret_token(c) if (bufptr != buffer) { \ | |
505 | save(c); \ | |
506 | *bufptr = 0; \ | |
507 | bufptr = buffer; \ | |
9b9748d9 | 508 | yylval.string = string_lookup(buffer); \ |
aebba157 GM |
509 | return TOKEN; \ |
510 | } | |
511 | #define save(c) { last_char = c; last_saved = 1; } | |
9b9748d9 | 512 | #if defined(YYDEBUG) |
aebba157 GM |
513 | #define Return(c) if (yydebug) { \ |
514 | printf("[%d]", c); \ | |
515 | fflush(stdout); \ | |
516 | } \ | |
9b9748d9 | 517 | yyval.intval = c; \ |
aebba157 | 518 | return c; |
9b9748d9 GM |
519 | #else /* defined(YYDEBUG) */ |
520 | #define Return(y,c) { yylval.intval = c; return y; } | |
521 | #endif /* defined(YYDEBUG) */ | |
aebba157 | 522 | |
9b9748d9 GM |
523 | |
524 | static char buffer[500], *bufptr = buffer; | |
aebba157 GM |
525 | static int eof_found = 0; |
526 | int c; | |
527 | ||
528 | if (eof_found != 0) { | |
529 | eof_found++; | |
530 | if (eof_found > 2) { | |
531 | fprintf(stderr, "End of file ignored.\n"); | |
532 | exit(1); | |
533 | } | |
9b9748d9 | 534 | Return(END_OF_FILE,0); |
aebba157 GM |
535 | } |
536 | while ((c = Getchar()) != EOF) { | |
537 | switch (c) { | |
538 | case '#': | |
539 | ret_token(c); | |
540 | while (((c = Getchar()) != EOF) && (c != '\n')) { | |
541 | ; | |
542 | } | |
543 | save(c); | |
544 | break; | |
9b9748d9 GM |
545 | case '@': |
546 | case '<': | |
547 | case '?': | |
548 | ret_token(c); | |
549 | Return(MACRO_CHAR, c); | |
550 | case '-': | |
551 | case '(': | |
552 | case ')': | |
553 | case ';': | |
554 | ret_token(c); | |
555 | Return(BREAK_CHAR, c); | |
aebba157 | 556 | case '\t': |
9b9748d9 | 557 | case ' ': |
aebba157 | 558 | ret_token(c); |
9b9748d9 | 559 | Return(WHITE_SPACE, c); |
aebba157 GM |
560 | case ':': |
561 | case '=': | |
9b9748d9 GM |
562 | case '$': |
563 | case '{': | |
564 | case '}': | |
aebba157 | 565 | ret_token(c); |
9b9748d9 GM |
566 | Return(c,c); |
567 | case '\'': | |
568 | case '"': | |
569 | { | |
570 | int newc; | |
571 | ||
572 | ret_token(c); | |
573 | *bufptr++ = c; | |
574 | while (((newc = Getchar()) != EOF) && (newc != c)) { | |
575 | *bufptr++ = newc; | |
576 | } | |
577 | *bufptr++ = c; | |
578 | *bufptr = 0; | |
579 | bufptr = buffer; | |
580 | yylval.string = string_lookup(buffer); | |
581 | return QUOTED_STRING; | |
582 | } | |
aebba157 GM |
583 | case '\n': |
584 | if (bufptr != buffer) { | |
585 | if (bufptr[-1] == '\\') { | |
586 | bufptr--; | |
9b9748d9 GM |
587 | if ((c = Getchar()) != '\t') { |
588 | yyerror("continuation line doesn't begin with a tab"); | |
589 | save(c); | |
590 | } | |
591 | ret_token(c); | |
592 | Return(WHITE_SPACE, c); | |
aebba157 GM |
593 | } |
594 | } | |
595 | ret_token(c); | |
9b9748d9 | 596 | Return(NL, 0); |
aebba157 GM |
597 | default: |
598 | *bufptr++ = c; | |
599 | break; | |
600 | } | |
601 | } | |
602 | ||
603 | eof_found = 1; | |
604 | ||
605 | ret_token(' '); | |
9b9748d9 GM |
606 | Return(END_OF_FILE, 0); |
607 | } | |
608 | ||
609 | main() | |
610 | { | |
611 | #define YYDEBUG | |
612 | extern int yydebug; | |
613 | ||
0859be39 GM |
614 | null = same_item(string_lookup("")); |
615 | newline = same_item(string_lookup("\n")); | |
616 | blank = same_item(string_lookup(" ")); | |
9b9748d9 | 617 | |
9b9748d9 GM |
618 | return yyparse(); |
619 | } | |
620 | ||
621 | #if defined(YYDEBUG) | |
b430ae6a GM |
622 | dump_same(same) |
623 | same_t *same; | |
624 | { | |
625 | same_t *same2; | |
626 | ||
627 | for (visit(same, same2); !visited(same2); visit_next(same2)) { | |
628 | printf(same2->string->string); | |
629 | } | |
630 | visit_end(); | |
631 | } | |
632 | ||
9b9748d9 GM |
633 | do_dump() |
634 | { | |
635 | string_t *string; | |
636 | same_t *same, *same2; | |
637 | ||
638 | if (yydebug > 1) { | |
639 | printf("strings...\n"); | |
640 | for (string = strings; string; string = string->next) { | |
641 | printf("\t%s\n", string->string); | |
642 | } | |
643 | } | |
644 | ||
645 | printf("variables...\n"); | |
1d1968a6 | 646 | for (visit(variables, same); !visited(same); visit_next(same)) { |
9b9748d9 | 647 | printf("\t%s =\t", same->string->string); |
0859be39 GM |
648 | for (visit(same->value_list, same2); !visited(same2); |
649 | visit_next(same2)) { | |
9b9748d9 GM |
650 | printf(same2->string->string); |
651 | } | |
0859be39 | 652 | visit_end(); |
9b9748d9 GM |
653 | printf("\n"); |
654 | } | |
1d1968a6 | 655 | visit_end(); |
9b9748d9 GM |
656 | |
657 | printf("targets...\n"); | |
1d1968a6 | 658 | for (visit(targets, same); !visited(same); visit_next(same)) { |
9b9748d9 | 659 | printf("\t%s :\t", same->string->string); |
0859be39 GM |
660 | for (visit(same->depend_list, same2); !visited(same2); |
661 | visit_next(same2)) { | |
9b9748d9 GM |
662 | printf(same2->string->string); |
663 | } | |
0859be39 | 664 | visit_end(); |
1d1968a6 GM |
665 | printf("\n\t\t"); |
666 | for (visit(same->action_list, same2); !visited(same2); | |
667 | visit_next(same2)) { | |
668 | printf(same2->string->string); | |
669 | if (same2->string->string[0] == '\n') { | |
670 | printf("\t\t"); | |
9b9748d9 | 671 | } |
9b9748d9 | 672 | } |
1d1968a6 GM |
673 | visit_end(); |
674 | printf("\n"); | |
9b9748d9 | 675 | } |
1d1968a6 | 676 | visit_end(); |
aebba157 | 677 | } |
9b9748d9 | 678 | #endif /* YYDEBUG */ |