⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mkmake.y

📁 早期freebsd实现
💻 Y
📖 第 1 页 / 共 2 页
字号:
%{/*- * 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 + -