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