📄 mkmake.y
字号:
%{/*- * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)mkmake.y 8.1 (Berkeley) 6/6/93";#endif /* not lint */typedef struct string { int hashval, length; char *string; struct string *next;} string_t;/* * The deal with these is that they exist on various lists. * * First off, they are on a temporary list during the time they * are in the active focus of the parser. * * Secondly, they live on one of three queues: * 1. Variables * 2. Targets * 3. Actions * (and, we restrict any given one to live on one and only one such list) * * Also, they may live on the list of values for someone else's variable, * or as someone's dependancy. */typedef struct same { string_t *string; /* My name */ struct same *nexttoken, /* Next pointer */ *lasttoken, /* Back pointer */ *depend_list, /* If target, dependancies */ *action_list, /* If target, actions */ *value_list, /* If variable, value list */ *shell_item; /* If a shell variable, current value */} same_t;%}%union { string_t *string; same_t *same; int intval; }%start makefile%token <string> TOKEN QUOTED_STRING%token <intval> FOR IN DO DONE%token <intval> MACRO_CHAR NL WHITE_SPACE%token <intval> ':' '=' '$' '{' '}' ';' '-' '@' '(' ')' ' ' '\t'%type <same> target target1 assignment assign1 actions action%type <same> command_list list list_element%type <same> for_statement maybe_at_minus tokens token%type <same> maybe_white_space%type <intval> white_space macro_char%%makefile : lines;lines : line | lines line ;line : NL | assignment | target_action ;assignment : assign1 tokens NL { assign($1, $2); } | assign1 NL { assign($1, same_copy(null)); } ;assign1: token maybe_white_space '=' maybe_white_space ;target_action: target actions { add_targets_actions($1, $2); } | target { add_targets_actions($1, 0); } ;target : target1 tokens NL { $$ = add_depends($1, $2); } | target1 NL { $$ = add_depends($1, same_copy(null)); } ;target1: tokens maybe_white_space ':' maybe_white_space { $$ = ws_merge($1); } ;actions: action | actions action { $$ = same_cat(same_cat($1, same_copy(newline)), $2); } ;action: white_space command_list NL { $$ = $2; } | white_space for_statement do command_list semi_colon done NL { $$ = do_command($2, $4); } ;for_statement: maybe_at_minus FOR white_space token in tokens semi_colon { $$ = for_statement($1, $4, ws_merge(expand_variables($6, 0))); } ;in: white_space IN white_spacedo: white_space DO white_space ;done: white_space DONE ;semi_colon: ';' ;command_list: list | '(' list maybe_white_space ')' { $$ = same_cat($2, same_copy(cwd_line)); } ;list: token | list list_element { $$ = same_cat($1, $2); } | list white_space list_element { $$ = same_cat($1, same_cat(same_copy(blank), $3)); } ;list_element: token | semi_colon { $$ = same_copy(newline); } ;maybe_at_minus: /* empty */ { $$ = same_copy(null); } | '@' { char buffer[2]; buffer[0] = $1; buffer[1] = 0; $$ = same_item(string_lookup(buffer)); } | '-' { char buffer[2]; buffer[0] = $1; buffer[1] = 0; $$ = same_item(string_lookup(buffer)); } ;tokens : token | tokens maybe_white_space token { $$ = same_cat($1, same_cat($2, $3)); } ;token: TOKEN { $$ = same_item($1); } | QUOTED_STRING { $$ = same_item($1); } | '$' macro_char { char buffer[3]; buffer[0] = '$'; buffer[1] = $2; buffer[2] = 0; $$ = same_item(string_lookup(buffer)); } | '$' '$' TOKEN { $$ = shell_variable(same_item($3)); } | MACRO_CHAR { $$ = same_char($1); } | '$' '{' TOKEN '}' { $$ = variable(same_item($3)); } | '$' '(' TOKEN ')' { $$ = variable(same_item($3)); } | '$' TOKEN { $$ = variable(same_item($2)); } | '-' { $$ = same_char('-'); } | '@' { $$ = same_char('@'); } ;macro_char: MACRO_CHAR | '@' ;maybe_white_space: { $$ = same_copy(null); } | white_space { $$ = same_char($1); } ;white_space : WHITE_SPACE | white_space WHITE_SPACE ;%%#include <stdio.h>#include <ctype.h>static int last_char, last_saved = 0;static int column = 0, lineno = 1;static string_t *strings = 0;static same_t *shell_variables = 0, *shell_special = 0, *variables = 0, *targets = 0, *actions = 0;static same_t *null, *blank, *cwd_line, *newline;extern char *malloc();static unsigned int clock = -1;struct { same_t *first; int next;} visit_stack[20]; /* 20 maximum */#define visit(what,via) \ (visit_stack[++clock].next = 0, visit_stack[clock].first = via = what)#define visited(via) (visitcheck(via) || ((via) == 0) \ || (visit_stack[clock].next && (via == visit_stack[clock].first)))#define visit_next(via) (visit_stack[clock].next = 1, (via) = (via)->nexttoken)#define visit_end() (clock--)yyerror(s)char *s;{ fprintf(stderr, "line %d, character %d: %s\n", lineno, column, s); do_dump();}intvisitcheck(same)same_t *same;{ if (same->string == 0) { yyerror("BUG - freed 'same' in use..."); exit(1); } return 0;}intstring_hashof(string, length)char *string;int length;{ register int i = 0; while (length--) { i = (i<<3) + *string ^ ((i>>28)&0x7); } return i;}intstring_same(s1, s2)string_t *s1, *s2;{ if ((s1->hashval == s2->hashval) && (s1->length == s2->length) && (memcmp(s1->string, s2->string, s1->length) == 0)) { return 1; } else { return 0; }}string_t *string_lookup(string)char *string;{ string_t ours; string_t *ptr; ours.length = strlen(string); ours.hashval = string_hashof(string, ours.length); ours.string = string; for (ptr = strings; ptr; ptr = ptr->next) { if (string_same(&ours, ptr)) { return ptr; } } if ((ptr = (string_t *)malloc(sizeof *ptr)) == 0) { fprintf(stderr, "No space to add string *%s*!\n", string); exit(1); } ptr->hashval = ours.hashval; ptr->length = ours.length; if ((ptr->string = malloc(ours.length+1)) == 0) { fprintf(stderr, "No space to add literal *%s*!\n", string); exit(1); } memcpy(ptr->string, string, ours.length+1); ptr->next = strings; strings = ptr; return ptr;}#define same_singleton(s) ((s)->nexttoken == (s))same_t *same_search(list, token)same_t *list, *token;{ same_t *ptr; ptr = list; for (visit(list, ptr); !visited(ptr); visit_next(ptr)) { string_t *string; string = ptr->string; if (string_same(string, token->string)) { visit_end(); return ptr; } } visit_end(); return 0;}same_t *same_cat(list, tokens)same_t *list, *tokens;{ same_t *last; if (tokens == 0) { return list; } if (list) { last = tokens->lasttoken; tokens->lasttoken = list->lasttoken; list->lasttoken = last; tokens->lasttoken->nexttoken = tokens; last->nexttoken = list; return list; } else { return tokens; }}same_t *same_item(string)string_t *string;{ same_t *ptr; if ((ptr = (same_t *)malloc(sizeof *ptr)) == 0) { fprintf(stderr, "No more space for tokens!\n"); exit(1); } memset((char *)ptr, 0, sizeof *ptr); ptr->nexttoken = ptr->lasttoken = ptr; ptr->string = string; return ptr;}same_t *same_copy(same)same_t *same;{ same_t *head, *copy; head = 0; for (visit(same, copy); !visited(copy); visit_next(copy)) { same_t *ptr; ptr = same_item(copy->string); head = same_cat(head, ptr); } visit_end(); return head;}same_t *same_merge(t1, t2)same_t *t1, *t2;{ if (same_singleton(t1) && same_singleton(t2)) { int length = strlen(t1->string->string)+strlen(t2->string->string); char *buffer = malloc(length+1); same_t *value; if (buffer == 0) { yyerror("No space to merge strings in same_merge!"); exit(1); } strcpy(buffer, t1->string->string); strcat(buffer, t2->string->string); value = same_item(string_lookup(buffer)); free(buffer); return value; } else { yyerror("Internal error - same_merge with non-singletons"); exit(1); }}voidsame_free(list)same_t *list;{ same_t *token, *ptr; if (list == 0) { return; } token = list; do { ptr = token->nexttoken; token->string = 0; (void) free((char *)token); token = ptr; } while (token != list);}same_t *same_unlink(token)same_t *token;{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -