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

📄 gram.y

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 Y
字号:
%{#include "defs.h"%}%term NAME SHELLINE START MACRODEF COLON DOUBLECOLON GREATER AMPER AMPERAMPER%union	{	struct shblock *yshblock;	depblkp ydepblock;	nameblkp ynameblock;	}%type <yshblock> SHELLINE, shlist, shellist%type <ynameblock> NAME, namelist%type <ydepblock> deplist, dlist%%%{struct depblock *pp;static struct shblock *prevshp;static struct nameblock *lefts[NLEFTS];struct nameblock *leftp;static int nlefts;struct lineblock *lp, *lpp;static struct depblock *prevdep;static int sepc;static int allnowait;static struct fstack	{	FILE *fin;	char *fname;	int lineno;	} filestack[MAXINCLUDE];static int ninclude = 0;%}file:	| file comline	;comline:  START	| MACRODEF	| START namelist deplist shellist = {	    while( --nlefts >= 0)		{		wildp wp;		leftp = lefts[nlefts];		if(wp = iswild(leftp->namep))			{			leftp->septype = SOMEDEPS;			if(lastwild)				lastwild->next = wp;			else				firstwild = wp;			lastwild = wp;			}		if(leftp->septype == 0)			leftp->septype = sepc;		else if(leftp->septype != sepc)			{			if(! wp)				fprintf(stderr,					"Inconsistent rules lines for `%s'\n",					leftp->namep);			}		else if(sepc==ALLDEPS && leftp->namep[0]!='.' && $4!=0)			{			for(lp=leftp->linep; lp->nxtlineblock; lp=lp->nxtlineblock)			if(lp->shp)				fprintf(stderr,					"Multiple rules lines for `%s'\n",					leftp->namep);			}		lp = ALLOC(lineblock);		lp->nxtlineblock = NULL;		lp->depp = $3;		lp->shp = $4;		if(wp)			wp->linep = lp;		if(equal(leftp->namep, ".SUFFIXES") && $3==0)			leftp->linep = 0;		else if(leftp->linep == 0)			leftp->linep = lp;		else	{			for(lpp = leftp->linep; lpp->nxtlineblock;				lpp = lpp->nxtlineblock) ;				if(sepc==ALLDEPS && leftp->namep[0]=='.')					lpp->shp = 0;			lpp->nxtlineblock = lp;			}		}	}	| error	;namelist: NAME	= { lefts[0] = $1; nlefts = 1; }	| namelist NAME	= { lefts[nlefts++] = $2;	    	if(nlefts>=NLEFTS) fatal("Too many lefts"); }	;deplist:		{		char junk[100];		sprintf(junk, "%s:%d", filestack[ninclude-1].fname, yylineno);		fatal1("Must be a separator on rules line %s", junk);		}	| dlist	;dlist:  sepchar	= { prevdep = 0;  $$ = 0; allnowait = NO; }	| sepchar AMPER	= { prevdep = 0; $$ = 0; allnowait = YES; }	| dlist NAME	= {			  pp = ALLOC(depblock);			  pp->nxtdepblock = NULL;			  pp->depname = $2;			  pp->nowait = allnowait;			  if(prevdep == 0) $$ = pp;			  else  prevdep->nxtdepblock = pp;			  prevdep = pp;			  }	| dlist AMPER	= { if(prevdep) prevdep->nowait = YES; }	| dlist AMPERAMPER	;sepchar:  COLON 	= { sepc = ALLDEPS; }	| DOUBLECOLON	= { sepc = SOMEDEPS; }	;shellist:	= {$$ = 0; }	| shlist = { $$ = $1; }	;shlist:	SHELLINE   = { $$ = $1;  prevshp = $1; }	| shlist SHELLINE = { $$ = $1;			prevshp->nxtshblock = $2;			prevshp = $2;			}	;%%static char *zznextc;	/* null if need another line;			   otherwise points to next char */static int yylineno;static FILE * fin;static int retsh(char *);static int nextlin(void);static int isinclude(char *);int yyparse(void);intparse(char *name){FILE *stream;if(name == CHNULL)	{	stream = NULL;	name = "(builtin-rules)";	}else if(equal(name, "-"))	{	stream = stdin;	name = "(stdin)";	}else if( (stream = fopen(name, "r")) == NULL)	return NO;filestack[0].fname = copys(name);ninclude = 1;fin = stream;yylineno = 0;zznextc = 0;if( yyparse() )	fatal("Description file error");if(fin)	fclose(fin);return YES;}intyylex(void){char *p;char *q;char word[INMAX];if(! zznextc )	return nextlin() ;while( isspace(*zznextc) )	++zznextc;switch(*zznextc)	{	case '\0':		return nextlin() ;	case '|':		if(zznextc[1]==':')			{			zznextc += 2;			return DOUBLECOLON;			}		break;	case ':':		if(*++zznextc == ':')			{			++zznextc;			return DOUBLECOLON;			}		return COLON;	case '>':		++zznextc;		return GREATER;	case '&':		if(*++zznextc == '&')			{			++zznextc;			return AMPERAMPER;			}		return AMPER;	case ';':		return retsh(zznextc) ;	}p = zznextc;q = word;while( ! ( funny[*p] & TERMINAL) )	*q++ = *p++;if(p != zznextc)	{	*q = '\0';	if((yylval.ynameblock=srchname(word))==0)		yylval.ynameblock = makename(word);	zznextc = p;	return NAME;	}else	{	char junk[100];	sprintf(junk, "Bad character %c (octal %o), line %d of file %s",		*zznextc, *zznextc, yylineno, filestack[ninclude-1].fname);	fatal(junk);	}return 0;	/* never executed */}static intretsh(char *q){register char *p;struct shblock *sp;for(p=q+1 ; *p==' '||*p=='\t' ; ++p)  ;sp = ALLOC(shblock);sp->nxtshblock = NULL;sp->shbp = (fin ? copys(p) : p );yylval.yshblock = sp;zznextc = 0;return SHELLINE;}static intnextlin(void){static char yytext[INMAX];static char *yytextl	= yytext+INMAX;char *text, templin[INMAX];char c;char *p, *t;char lastch, *lastchp;extern char **linesptr;int incom;int kc;again:	incom = NO;	zznextc = 0;if(fin == NULL)	{	if( (text = *linesptr++) == 0)		return 0;	++yylineno;	}else	{	for(p = text = yytext ; p<yytextl ; *p++ = kc)		switch(kc = getc(fin))			{			case '\t':				if(p == yytext)					incom = YES;				break;			case ';':				incom = YES;				break;			case '#':				if(! incom)					kc = '\0';				break;			case '\n':				++yylineno;				if(p==yytext || p[-1]!='\\')					{					*p = '\0';					goto endloop;					}				p[-1] = ' ';				while( (kc=getc(fin))=='\t' || kc==' ' || kc=='\n')					if(kc == '\n')						++yylineno;					if(kc != EOF)					break;			case EOF:				*p = '\0';				if(ninclude > 1)					{					register struct fstack *stp;					fclose(fin);					--ninclude;					stp = filestack + ninclude;					fin = stp->fin;					yylineno = stp->lineno;					free(stp->fname);					goto again;					}				return 0;			}	fatal("line too long");	}endloop:	if((c = text[0]) == '\t')		return retsh(text) ;		if(isalpha(c) || isdigit(c) || c==' ' || c=='.'|| c=='_')		for(p=text+1; *p!='\0'; )			if(*p == ':')				break;			else if(*p++ == '=')				{				eqsign(text);				return MACRODEF;				}/* substitute for macros on dependency line up to the semicolon if any */for(t = yytext ; *t!='\0' && *t!=';' ; ++t)	;lastchp = t;lastch = *t;*t = '\0';	/* replace the semi with a null so subst will stop */subst(yytext, templin);		/* Substitute for macros on dependency lines */if(lastch)	/* copy the stuff after the semicolon */	{	*lastchp = lastch;	strcat(templin, lastchp);	}strcpy(yytext, templin);/* process include files after macro substitution */if(strncmp(text, "include", 7) == 0) { 	if (isinclude(text+7))		goto again;}for(p = zznextc = text ; *p ; ++p )	if(*p!=' ' && *p!='\t')		return START;goto again;}static intisinclude(char *s){char *t;struct fstack *p;for(t=s; *t==' ' || *t=='\t' ; ++t)	;if(t == s)	return NO;for(s = t; *s!='\n' && *s!='#' && *s!='\0' ; ++s)	if(*s == ':')		return NO;*s = '\0';if(ninclude >= MAXINCLUDE)	fatal("include depth exceeded");p = filestack + ninclude;p->fin = fin;p->lineno = yylineno;p->fname = copys(t);if( (fin = fopen(t, "r")) == NULL)	fatal1("Cannot open include file %s", t);yylineno = 0;++ninclude;return YES;}intyyerror(char *s, ...){char buf[100];sprintf(buf, "line %d of file %s: %s",		yylineno, filestack[ninclude-1].fname, s);fatal(buf);}

⌨️ 快捷键说明

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