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

📄 y2.c

📁 整理 unix v7 的 ya
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "dextern.h"#define IDENTIFIER 257#define MARK 258#define TERM 259#define LEFT 260#define RIGHT 261#define BINARY 262#define PREC 263#define LCURLY 264#define C_IDENTIFIER 265  /* name followed by colon */#define NUMBER 266#define START 267#define TYPEDEF 268#define TYPENAME 269#define UNION 270#define ENDFILE 0/* * communication variables between various I/O routines */char *infile;	/* input file name */union {	int number;	/* value of an input number */	char* tokname; /* input token name */} yylval;char tokname[NAMESIZE];	/* storage for input token name *//* * storage of names */char cnames[CNAMSZ];	/* place where token and nonterminal names are stored */int cnamsz = CNAMSZ;	/* size of cnames */char * cnamp = cnames;	/* place where next name is to be put in */int ndefout = 3;  /* number of defined symbols output *//* * storage of types */int ntypes;	/* number of types defined */char * typeset[NTYPES];	/* pointers to type tags *//* * symbol tables for tokens and nonterminals */int ntokens = 0;struct toksymb tokset[NTERMS];int toklev[NTERMS];int nnonter = -1;struct ntsymb nontrst[NNONTERM];int start;	/* start symbol *//* * assigned token type values */int extval = 0;/* * input and output file descriptors */FILE * finput;		/* yacc input file */FILE * faction;		/* file for saving actions */FILE * fdefine;		/* file for #defines */FILE * ftable;		/* y.tab.c file */FILE * ftemp;		/* tempfile to pass 2 */FILE * foutput;		/* y.output file *//* * storage for grammar rules */int mem0[MEMSIZE] ; /* production storage */int *mem = mem0;int nprod= 1;	/* number of productions */int *prdptr[NPROD];	/* pointers to descriptions of productions */int levprd[NPROD] ;	/* precedence levels for the productions */void setup(int argc,char *argv[]);int  yyparse(void);void finact(void);int  defin(int t, register char  *s);void defout(void);char *cstash(register char * s);int  yylex(void);int  fdtype(int t);int  chfind(int t, register char *s);void cpyunion(void);void cpycode(void);int  skipcom(void);void cpyact(int offset);void setup(int argc,char *argv[]){	foutput = NULL;	fdefine = NULL;	while(argc >= 2  && argv[1][0] == '-') {		while(*++(argv[1])){			switch(*argv[1]){			case 'v':			case 'V':				foutput = fopen(FILEU, "w");				if(foutput == NULL)					error("cannot open y.output");				continue;			case 'D':			case 'd':				fdefine = fopen(FILED, "w");				continue;			case 'o':			case 'O':				fprintf(stderr, "`o' flag now default in yacc\n");				continue;			case 'r':			case 'R':				error("Ratfor Yacc is dead: sorry...\n");			default:				error("illegal option: %c", *argv[1]);			}		}		argv++;		argc--;	}	ftable = fopen(OFILE, "w");	if(ftable == NULL)		error("cannot open table file");	ftemp = fopen(TEMPNAME, "w");	faction = fopen(ACTNAME, "w");	if(ftemp==NULL || faction==NULL)		error("cannot open temp file");	if(argc < 2 || ((finput=fopen(infile=argv[1], "r")) == NULL)){		error("cannot open input file");	}}int yyparse(void){	int i,j,lev,t, ty;	int c;	int *p;	char actname[8];	cnamp = cnames;	defin(0,"$end");	extval = 0400;	defin(0,"error");	defin(1,"$accept");	mem=mem0;	lev = 0;	ty = 0;	i=0;	/* sorry -- no yacc parser here.....		we must bootstrap somehow... */	for(t=yylex();  t!=MARK && t!= ENDFILE;){		switch(t){		case ';':			t = yylex();			break;		case START:			if((t=yylex()) != IDENTIFIER){				error("bad %%start construction");			}			start = chfind(1,yylval.tokname);			t = yylex();			continue;		case TYPEDEF:			if((t=yylex()) != TYPENAME)				error("bad syntax in %%type");			ty = yylval.number;			for(;;){				t = yylex();				switch(t){				case IDENTIFIER:					if((t=chfind(1, yylval.tokname)) < NTBASE) {						j = TYPE(toklev[t]);						if(j!= 0 && j != ty){							error("type redeclaration of token %s",								tokset[t].name);						}						else							SETTYPE(toklev[t],ty);					} else {						j = nontrst[t-NTBASE].tvalue;						if(j != 0 && j != ty){							error("type redeclaration of nonterminal %s",								nontrst[t-NTBASE].name);						}						else							nontrst[t-NTBASE].tvalue = ty;					}				case ',':					continue;				case ';':					t = yylex();					break;				default:					break;				}				break;			}			continue;		case UNION:			/* copy the union declaration to the output */			cpyunion();			t = yylex();			continue;		case LEFT:		case BINARY:		case RIGHT:			++i;		case TERM:			lev = t-TERM;  /* nonzero means new prec. and assoc. */			ty = 0;			/* get identifiers so defined */			t = yylex();			if(t == TYPENAME){ /* there is a type defined */				ty = yylval.number;				t = yylex();			}			for(;;) {				switch(t){				case ',':					t = yylex();					continue;				case ';':					break;				case IDENTIFIER:					j = chfind(0,yylval.tokname);					if(lev){						if(ASSOC(toklev[j]))							error("redeclaration of precedence of %s", yylval.tokname);						SETASC(toklev[j],lev);						SETPLEV(toklev[j],i);					}					if(ty){						if(TYPE(toklev[j]))							error("redeclaration of type of %s", yylval.tokname);						SETTYPE(toklev[j],ty);					}					if((t=yylex()) == NUMBER){						tokset[j].value = yylval.number;						if(j < ndefout && j>2){							error("please define type number of %s earlier",								tokset[j].name);						}						t=yylex();					}					continue;				}				break;			}			continue;		case LCURLY:			defout();			cpycode();			t = yylex();			continue;		default:			error("syntax error");		}	}	if(t == ENDFILE){		error("unexpected EOF before %%");	}	/* t is MARK */	defout();	fprintf(ftable,  "#define yyclearin yychar = -1\n");	fprintf(ftable,  "#define yyerrok yyerrflag = 0\n");	fprintf(ftable,  "extern int yychar;\nextern short yyerrflag;\n");	fprintf(ftable,  "#ifndef YYMAXDEPTH\n#define YYMAXDEPTH 150\n#endif\n");	if(!ntypes)		fprintf(ftable,  "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n");	fprintf(ftable,  "YYSTYPE yylval, yyval;\n");	prdptr[0]=mem;	/* added production */	*mem++ = NTBASE;	*mem++ = start;  /* if start is 0, we will overwrite with the lhs of the first rule */	*mem++ = 1;	*mem++ = 0;	prdptr[1]=mem;	while((t=yylex()) == LCURLY)		cpycode();	if(t != C_IDENTIFIER)		error("bad syntax on first rule");	if(!start)		prdptr[0][1] = chfind(1,yylval.tokname);	/* read rules */	while(t!=MARK && t!=ENDFILE){		/* process a rule */		if(t == '|'){			*mem++ = *prdptr[nprod-1];		}		else if(t == C_IDENTIFIER){			*mem = chfind(1,yylval.tokname);			if(*mem < NTBASE)				error("token illegal on LHS of grammar rule");			++mem;		}		else error("illegal rule: missing semicolon or | ?");		/* read rule body */		t = yylex();		for (;;) {			while(t == IDENTIFIER) {				*mem = chfind(1,yylval.tokname);				if(*mem<NTBASE)					levprd[nprod] = toklev[*mem];				++mem;				t = yylex();			}			if(t == PREC){				if(yylex()!=IDENTIFIER)					error("illegal %%prec syntax");				j = chfind(2,yylval.tokname);				if(j>=NTBASE)					error("nonterminal %s illegal after %%prec", nontrst[j-NTBASE].name);				levprd[nprod]=toklev[j];				t = yylex();				if (t == IDENTIFIER)					continue;			}			if(t == '='){				levprd[nprod] |= ACTFLAG;				fprintf(faction, "\ncase %d:", nprod);				cpyact(mem-prdptr[nprod]-1);				fprintf(faction, " break;");				if((t=yylex()) == IDENTIFIER){					/* action within rule... */					sprintf(actname, "$$%d", nprod);					j = chfind(1,actname);  /* make it a nonterminal */					/* the current rule will become rule number nprod+1 */					/* move the contents down, and make room for the null */					for(p=mem; p>=prdptr[nprod]; --p)						p[2] = *p;					mem += 2;					/* enter null production for action */					p = prdptr[nprod];					*p++ = j;					*p++ = -nprod;					/* update the production information */					levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;					levprd[nprod] = ACTFLAG;					if(++nprod >= NPROD)						error("more than %d rules", NPROD);					prdptr[nprod] = p;					/* make the action appear in the original rule */					*mem++ = j;					/* get some more of the rule */					continue;				}			}			break;		}		while(t == ';')			t = yylex();		*mem++ = -nprod;		/* check that default action is reasonable */		if(ntypes && !(levprd[nprod]&ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].tvalue){			/* no explicit action, LHS has value */			register int tempty;			tempty = prdptr[nprod][1];			if(tempty < 0)				error("must return a value, since LHS has a type");			else if(tempty >= NTBASE)				tempty = nontrst[tempty-NTBASE].tvalue;			else				tempty = TYPE(toklev[tempty]);			if(tempty != nontrst[*prdptr[nprod]-NTBASE].tvalue){				error("default action causes potential type clash");			}		}		if(++nprod >= NPROD)			error("more than %d rules", NPROD);		prdptr[nprod] = mem;		levprd[nprod]=0;	}	/* end of all rules */	finact();	if(t == MARK){		fprintf(ftable, "\n#line %d \"%s\"\n", lineno, infile);		while((c=getc(finput)) != EOF)			putc(c, ftable);	}	fclose(finput);	return 0;}/* * finish action routine */void finact(void){	fclose(faction);	fprintf(ftable, "#define YYERRCODE %d\n", tokset[2].value);}/* * define s to be a terminal if t=0 * or a nonterminal if t=1 */int defin(int t, register char  *s){	register int val=0;	if (t) {		if(++nnonter >= NNONTERM)			error("too many nonterminals, limit %d",NNONTERM);		nontrst[nnonter].name = cstash(s);		return(NTBASE + nnonter);	}	/* must be a token */	if(++ntokens >= NTERMS)		error("too many terminals, limit %d",NTERMS);	tokset[ntokens].name = cstash(s);	/* establish value for token */	if(s[0]==' ' && s[2]=='\0') /* single character literal */		val = s[1];	else if (s[0]==' ' && s[1]=='\\') { /* escape sequence */		if(s[3] == '\0'){ /* single character escape sequence */			switch (s[2]){					 /* character which is escaped */			case 'n':				val = '\n';				break;			case 'r':				val = '\r';				break;			case 'b':				val = '\b';				break;			case 't':				val = '\t';				break;			case 'f':				val = '\f';				break;			case '\'':				val = '\'';				break;			case '"':				val = '"';				break;			case '\\':				val = '\\';				break;			default:				error("invalid escape");			}		}

⌨️ 快捷键说明

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