All but end of file.
[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
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
55makefile : lines END_OF_FILE;
56
57lines : line
58 | lines line
59 ;
60
9b9748d9
GM
61line : maybe_white_space NL
62 | assignment
63 | target_action
aebba157
GM
64 ;
65
9b9748d9
GM
66assignment :
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
77target_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
87target :
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
98actions: action
99 | actions action
100 {
9b9748d9 101 $$ = same_cat($1, $2);
aebba157
GM
102 }
103 ;
104
9b9748d9 105action: white_space tokens NL
aebba157
GM
106 {
107 $$ = $2;
108 }
109 ;
110
111tokens : token
112 | tokens token
113 {
9b9748d9 114 $$ = same_cat($1, $2);
aebba157
GM
115 }
116 ;
9b9748d9 117
aebba157
GM
118token: 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
151macro_char: MACRO_CHAR
152 | '$'
153 ;
154
155special_chars : BREAK_CHAR
156 | MACRO_CHAR
157 | white_space
158 ;
159
160maybe_white_space:
161 | white_space;
162
163white_space : WHITE_SPACE
164 | white_space WHITE_SPACE
165 ;
166
aebba157
GM
167%%
168#include <stdio.h>
169
170static int last_char, last_saved = 0;
171static int column = 0, lineno = 1;
172
173
9b9748d9
GM
174static string_t
175 *strings = 0;
176static same_t
1d1968a6
GM
177 *variables = 0,
178 *targets = 0,
179 *actions = 0;
9b9748d9 180
aebba157 181static same_t
0859be39
GM
182 *null,
183 *blank,
184 *newline;
aebba157
GM
185
186extern char *malloc();
187
0859be39
GM
188static unsigned int
189 clock = -1;
190
191struct {
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
203yyerror(s)
204char *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
210int
211visitcheck(same)
212same_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
221int
222string_hashof(string, length)
223char *string;
224int 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
234int
235string_same(s1, s2)
236string_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
247string_t *
248string_lookup(string)
249char *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
279same_t *
9b9748d9 280same_search(list, token)
aebba157 281same_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
301same_t *
9b9748d9 302same_cat(list, tokens)
aebba157 303same_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
321same_t *
9b9748d9 322same_item(string)
aebba157
GM
323string_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
337same_t *
338same_copy(same)
339same_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
354void
0859be39
GM
355same_free(list)
356same_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
369void
0859be39 370same_unlink(token)
9b9748d9 371same_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
382same_t *
383add_target(target)
384same_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
399same_t *
400add_targets_actions(target, actions)
401same_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
425same_t *
426add_depends(target, depends)
427same_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
449void
450assign(variable, value)
451same_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
466same_t *
467value_of(variable)
468same_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
480int
481Getchar()
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
502yylex()
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
609main()
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
622dump_same(same)
623same_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
633do_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 */