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

📄 parse.y

📁 早期freebsd实现
💻 Y
字号:
%{/* pathalias -- by steve bellovin, as told to peter honeyman */#ifndef lintstatic char	*sccsid = "@(#)parse.y	9.11 91/06/01";#endif /* lint */#include "def.h"/* scanner states (yylex, parse) */#define OTHER		0#define COSTING		1#define NEWLINE		2#define FILENAME	3/* exports */long Tcount;extern void yyerror();/* imports */extern node *addnode(), *addprivate();extern void fixprivate(), alias(), deadlink(), deletelink();extern link *addlink();extern int strcmp();extern char *strsave();extern int optind;extern char *Cfile, *Netchars, **Argv;extern int Lineno, Argc;extern node *Home;/* privates */STATIC void fixnet(), adjust();STATIC int yylex(), yywrap(), getword();static int Scanstate = NEWLINE;	/* scanner (yylex) state *//* flags for ys_flags */#define TERMINAL 1%}%union {	node	*y_node;	Cost	y_cost;	char	y_net;	char	*y_name;	struct {		node *ys_node;		Cost ys_cost;		short ys_flag;		char ys_net;		char ys_dir;	} y_s;}%type <y_s>	site asite%type <y_node>	links aliases plist network nlist host nhost%type <y_node>	usite delem dlist%type <y_cost>	cost cexpr%token <y_name>	SITE HOST STRING%token <y_cost>	COST%token <y_net>	NET%token EOL PRIVATE DEAD DELETE FILETOK ADJUST%left	'+' '-'%left	'*' '/'%%map	:	/* empty */	|	map		EOL	|	map links	EOL	|	map aliases	EOL	|	map network	EOL	|	map private	EOL	|	map dead	EOL	|	map delete	EOL	|	map file	EOL	|	map adjust	EOL	|	error		EOL	;links	: host site cost {		struct link *l;		l = addlink($1, $2.ys_node, $3, $2.ys_net, $2.ys_dir);		if (GATEWAYED($2.ys_node))			l->l_flag |= LGATEWAY;		if ($2.ys_flag & TERMINAL)			l->l_flag |= LTERMINAL;	  }				| links ',' site cost {		struct link *l;		l = addlink($1, $3.ys_node, $4, $3.ys_net, $3.ys_dir);		if (GATEWAYED($3.ys_node))			l->l_flag |= LGATEWAY;		if ($3.ys_flag & TERMINAL)			l->l_flag |= LTERMINAL;	  }	| links ','	/* benign error */	;host	: HOST		{$$ = addnode($1);}	| PRIVATE	{$$ = addnode("private");}	| DEAD		{$$ = addnode("dead");}	| DELETE	{$$ = addnode("delete");}	| FILETOK	{$$ = addnode("file");}	| ADJUST	{$$ = addnode("adjust");}	;site	: asite {		$$ = $1;		$$.ys_net = DEFNET;		$$.ys_dir = DEFDIR;	  }	| NET asite {		$$ = $2;		$$.ys_net = $1;		$$.ys_dir = LRIGHT;	  }	| asite NET {		$$ = $1;		$$.ys_net = $2;		$$.ys_dir = LLEFT;	  }	;asite	: SITE {		$$.ys_node = addnode($1);		$$.ys_flag = 0;	  }	| '<' SITE '>' {		Tcount++;		$$.ys_node = addnode($2);		$$.ys_flag = TERMINAL;	  }	;aliases	: host '=' SITE	{alias($1, addnode($3));}	| aliases ',' SITE	{alias($1, addnode($3));}	| aliases ','	/* benign error */	;network	: nhost '{' nlist '}' cost	{fixnet($1, $3, $5, DEFNET, DEFDIR);}	| nhost NET '{' nlist '}' cost	{fixnet($1, $4, $6, $2, LRIGHT);}	| nhost '{' nlist '}' NET cost	{fixnet($1, $3, $6, $5, LLEFT);}	;nhost	: '='		{$$ = 0;	/* anonymous net */}	| host '='	{$$ = $1;	/* named net */}	;nlist	: SITE		{$$ = addnode($1);}	| nlist ',' SITE {		node *n;		n = addnode($3);		if (n->n_net == 0) {			n->n_net = $1;			$$ = n;		}	  }	| nlist ','	/* benign error */	;		private	: PRIVATE '{' plist '}'			/* list of privates */	| PRIVATE '{' '}'	{fixprivate();}	/* end scope of privates */	;plist	: SITE			{addprivate($1)->n_flag |= ISPRIVATE;}	| plist ',' SITE	{addprivate($3)->n_flag |= ISPRIVATE;}	| plist ','		/* benign error */	;dead	: DEAD '{' dlist '}';dlist	: delem	| dlist ',' delem	| dlist ','		/* benign error */	;delem	: SITE			{deadlink(addnode($1), (node *) 0);}	| usite NET usite	{deadlink($1, $3);}	;usite	: SITE	{$$ = addnode($1);} ;	/* necessary unit production */delete	: DELETE '{' dellist '}';dellist	: delelem	| dellist ',' delelem	| dellist ','		/* benign error */	;delelem	: SITE {		node *n;		n = addnode($1);		deletelink(n, (node *) 0);		n->n_flag |= ISPRIVATE;		/* reset Home if it's deleted */		if (n == Home)			Home = addnode(Home->n_name);	  }	| usite NET usite	{deletelink($1, $3);}	;file	: FILETOK '{' {Scanstate = FILENAME;} STRING {Scanstate = OTHER;} '}' {		Lineno = 0;		Cfile = strsave($4);	}adjust	: ADJUST '{' adjlist '}' ;adjlist	: adjelem	| adjlist ',' adjelem	| adjlist ','		/* benign error */	;adjelem	: usite cost	{adjust($1, $2);} ;cost	: {$$ = DEFCOST;	/* empty -- cost is always optional */}	| '(' {Scanstate = COSTING;} cexpr {Scanstate = OTHER;} ')'		{$$ = $3;}	;cexpr	: COST	| '-' cexpr	  {$$ = -$2;}	| '(' cexpr ')'   {$$ = $2;}	| cexpr '+' cexpr {$$ = $1 + $3;}	| cexpr '-' cexpr {$$ = $1 - $3;}	| cexpr '*' cexpr {$$ = $1 * $3;}	| cexpr '/' cexpr {		if ($3 == 0)			yyerror("zero divisor\n");		else			$$ = $1 / $3;	  }	;%%void#ifdef YYDEBUG/*VARARGS1*/yyerror(fmt, arg)	char *fmt, *arg;#elseyyerror(s)	char *s;#endif{	/* a concession to bsd error(1) */	fprintf(stderr, "\"%s\", ", Cfile);#ifdef YYDEBUG	fprintf(stderr, "line %d: ", Lineno);	fprintf(stderr, fmt, arg);	putc('\n', stderr);#else	fprintf(stderr, "line %d: %s\n", Lineno, s);#endif}/* * patch in the costs of getting on/off the network. * * for each network member on netlist, add links: *	network -> member	cost = 0; *	member -> network	cost = parameter. * * if network and member both require gateways, assume network * is a gateway to member (but not v.v., to avoid such travesties * as topaz!seismo.css.gov.edu.rutgers). * * note that members can have varying costs to a network, by suitable * multiple declarations.  this is a feechur, albeit a useless one. */STATIC voidfixnet(network, nlist, cost, netchar, netdir)	register node *network;	node *nlist;	Cost cost;	char netchar, netdir;{	register node *member, *nextnet;	link *l;	static int netanon = 0;	char anon[25];	if (network == 0) {		sprintf(anon, "[unnamed net %d]", netanon++);		network = addnode(anon);	}	network->n_flag |= NNET;	/* insert the links */	for (member = nlist ; member; member = nextnet) {		/* network -> member, cost is 0 */		l = addlink(network, member, (Cost) 0, netchar, netdir);		if (GATEWAYED(network) && GATEWAYED(member))			l->l_flag |= LGATEWAY;		/* member -> network, cost is parameter */		/* never ever ever crawl up from a domain*/		if (!ISADOMAIN(network))			(void) addlink(member, network, cost, netchar, netdir);		nextnet = member->n_net;		member->n_net = 0;	/* clear for later use */	}}/* scanner */#define QUOTE '"'#define STR_EQ(s1, s2) (s1[2] == s2[2] && strcmp(s1, s2) == 0)#define NLRETURN() {Scanstate = NEWLINE; return EOL;}static struct ctable {	char *cname;	Cost cval;} ctable[] = {	/* ordered by frequency of appearance in a "typical" dataset */	{"DIRECT", 200},	{"DEMAND", 300},	{"DAILY", 5000},	{"HOURLY", 500},	{"DEDICATED", 100},	{"EVENING", 2000},	{"LOCAL", 25},	{"LOW", 5},	/* baud rate, quality penalty */	{"DEAD", MILLION},	{"POLLED", 5000},	{"WEEKLY", 30000},	{"HIGH", -5},	/* baud rate, quality bonus */	{"FAST", -80},	/* high speed (>= 9.6 kbps) modem */	/* deprecated */	{"ARPA", 100},	{"DIALED", 300},	{0, 0}};STATIC intyylex(){	static char retbuf[128];	/* for return to yacc part */	register int c;	register char *buf = retbuf;	register struct ctable *ct;	register Cost cost;	char errbuf[128];	if (feof(stdin) && yywrap())		return EOF;	/* count lines, skip over space and comments */	if ((c = getchar()) == EOF)		NLRETURN();    continuation:	while (c == ' ' || c == '\t')		if ((c = getchar()) == EOF)			NLRETURN();	if (c == '#')		while ((c = getchar()) != '\n')			if (c == EOF)				NLRETURN();	/* scan token */	if (c == '\n') {		Lineno++;		if ((c = getchar()) != EOF) {			if (c == ' ' || c == '\t')				goto continuation;			ungetc(c, stdin);		}		NLRETURN();	}	switch(Scanstate) {	case COSTING:		if (isdigit(c)) {			cost = c - '0';			for (c = getchar(); isdigit(c); c = getchar())				cost = (cost * 10) + c - '0';			ungetc(c, stdin);			yylval.y_cost = cost;			return COST;		}		if (getword(buf, c) == 0) {			for (ct = ctable; ct->cname; ct++)				if (STR_EQ(buf, ct->cname)) {					yylval.y_cost = ct->cval;					return COST;				}			sprintf(errbuf, "unknown cost (%s), using default", buf);			yyerror(errbuf);			yylval.y_cost = DEFCOST;			return COST;		}		return c;	/* pass the buck */	case NEWLINE:		Scanstate = OTHER;		if (getword(buf, c) != 0)			return c;		/*		 * special purpose tokens.		 *		 * the "switch" serves the dual-purpose of recognizing		 * unquoted tokens only.		 */		switch(c) {		case 'p':			if (STR_EQ(buf, "private"))				return PRIVATE;			break;		case 'd':			if (STR_EQ(buf, "dead"))				return DEAD;			if (STR_EQ(buf, "delete"))				return DELETE;			break;		case 'f':			if (STR_EQ(buf, "file"))				return FILETOK;			break;		case 'a':			if (STR_EQ(buf, "adjust"))				return ADJUST;			break;		}		yylval.y_name = buf;		return HOST;	case FILENAME:		while (c != EOF && isprint(c)) {			if (c == ' ' || c == '\t' || c == '\n' || c == '}')				break;			*buf++ = c;			c = getchar();		}		if (c != EOF)			ungetc(c, stdin);		*buf = 0;		yylval.y_name = retbuf;		return STRING;	}	if (getword(buf, c) == 0) {		yylval.y_name = buf;		return SITE;	}	if (index(Netchars, c)) {		yylval.y_net = c;		return NET;	}	return c;}/* * fill str with the next word in [0-9A-Za-z][-._0-9A-Za-z]+ or a quoted * string that contains no newline.  return -1 on failure or EOF, 0 o.w. */ STATIC intgetword(str, c)	register char *str;	register int c;{	if (c == QUOTE) {		while ((c = getchar()) != QUOTE) {			if (c == '\n') {				yyerror("newline in quoted string\n");				ungetc(c, stdin);				return -1;			}			if (c == EOF) {				yyerror("EOF in quoted string\n");				return -1;			}			*str++ = c;		}		*str = 0;		return 0;	}	/* host name must start with alphanumeric or `.' */	if (!isalnum(c) && c != '.')		return -1;yymore:	do {		*str++ = c;		c = getchar();	} while (isalnum(c) || c == '.' || c == '_');	if (c == '-' && Scanstate != COSTING)		goto yymore;	ungetc(c, stdin);	*str = 0;	return 0;}STATIC intyywrap(){	char errbuf[100];	fixprivate();	/* munge private host definitions */	Lineno = 1;	while (optind < Argc) {		if (freopen((Cfile = Argv[optind++]), "r", stdin) != 0)			return 0;		sprintf(errbuf, "%s: %s", Argv[0], Cfile);		perror(errbuf);	}	freopen("/dev/null", "r", stdin);	return -1;}STATIC voidadjust(n, cost)	node *n;	Cost cost;{	link *l;	n->n_cost += cost;	/* cumulative */	/* hit existing links */	for (l = n->n_link; l; l = l->l_next) {		if ((l->l_cost += cost) < 0) {			char buf[100];			l->l_flag |= LDEAD;			sprintf(buf, "link to %s deleted with negative cost",							l->l_to->n_name);			yyerror(buf);		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -