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

📄 lex.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
				continue;			if(cp == symb+2)				yyerror("malformed hex constant");			goto ncu;		}	if(c < '0' || c > '7')		goto dc;	for(;;) {		if(c >= '0' && c <= '7') {			*cp++ = c;			c = GETC();			continue;		}		goto ncu;	}dc:	if(c == '.')		goto casedot;	if(c == 'e' || c == 'E')		goto casee;ncu:	if((c == 'U' || c == 'u') && !(c1 & Numuns)) {		c = GETC();		c1 |= Numuns;		goto ncu;	}	if((c == 'L' || c == 'l') && !(c1 & Numvlong)) {		c = GETC();		if(c1 & Numlong)			c1 |= Numvlong;		c1 |= Numlong;		goto ncu;	}	*cp = 0;	peekc = c;	if(mpatov(symb, &yylval.vval))		yyerror("overflow in constant");	vv = yylval.vval;	if(c1 & Numvlong) {		if((c1 & Numuns) || convvtox(vv, TVLONG) < 0) {			c = LUVLCONST;			t = TUVLONG;			goto nret;		}		c = LVLCONST;		t = TVLONG;		goto nret;	}	if(c1 & Numlong) {		if((c1 & Numuns) || convvtox(vv, TLONG) < 0) {			c = LULCONST;			t = TULONG;			goto nret;		}		c = LLCONST;		t = TLONG;		goto nret;	}	if((c1 & Numuns) || convvtox(vv, TINT) < 0) {		c = LUCONST;		t = TUINT;		goto nret;	}	c = LCONST;	t = TINT;	goto nret;nret:	yylval.vval = convvtox(vv, t);	if(yylval.vval != vv){		nearln = lineno;		warn(Z, "truncated constant: %T %s", types[t], symb);	}	return c;casedot:	for(;;) {		*cp++ = c;		c = GETC();		if(!isdigit(c))			break;	}	if(c != 'e' && c != 'E')		goto caseout;casee:	*cp++ = 'e';	c = GETC();	if(c == '+' || c == '-') {		*cp++ = c;		c = GETC();	}	if(!isdigit(c))		yyerror("malformed fp constant exponent");	while(isdigit(c)) {		*cp++ = c;		c = GETC();	}caseout:	if(c == 'L' || c == 'l') {		c = GETC();		c1 |= Numlong;	} else	if(c == 'F' || c == 'f') {		c = GETC();		c1 |= Numflt;	}	*cp = 0;	peekc = c;	yylval.dval = strtod(symb, nil);	if(isInf(yylval.dval, 1) || isInf(yylval.dval, -1)) {		yyerror("overflow in float constant");		yylval.dval = 0;	}	if(c1 & Numflt)		return LFCONST;	return LDCONST;}/* * convert a string, s, to vlong in *v * return conversion overflow. * required syntax is [0[x]]d* */intmpatov(char *s, vlong *v){	vlong n, nn;	int c;	n = 0;	c = *s;	if(c == '0')		goto oct;	while(c = *s++) {		if(c >= '0' && c <= '9')			nn = n*10 + c-'0';		else			goto bad;		if(n < 0 && nn >= 0)			goto bad;		n = nn;	}	goto out;oct:	s++;	c = *s;	if(c == 'x' || c == 'X')		goto hex;	while(c = *s++) {		if(c >= '0' || c <= '7')			nn = n*8 + c-'0';		else			goto bad;		if(n < 0 && nn >= 0)			goto bad;		n = nn;	}	goto out;hex:	s++;	while(c = *s++) {		if(c >= '0' && c <= '9')			c += 0-'0';		else		if(c >= 'a' && c <= 'f')			c += 10-'a';		else		if(c >= 'A' && c <= 'F')			c += 10-'A';		else			goto bad;		nn = n*16 + c;		if(n < 0 && nn >= 0)			goto bad;		n = nn;	}out:	*v = n;	return 0;bad:	*v = ~0;	return 1;}intgetc(void){	int c;	if(peekc != IGN) {		c = peekc;		peekc = IGN;	} else		c = GETC();	if(c == '\n')		lineno++;	if(c == EOF) {		yyerror("End of file");		errorexit();	}	return c;}longgetr(void){	int c, i;	char str[UTFmax+1];	Rune rune;	c = getc();	if(c < Runeself)		return c;	i = 0;	str[i++] = c;loop:	c = getc();	str[i++] = c;	if(!fullrune(str, i))		goto loop;	c = chartorune(&rune, str);	if(rune == Runeerror && c == 1) {		nearln = lineno;		diag(Z, "illegal rune in string");		for(c=0; c<i; c++)			print(" %.2x", *(uchar*)(str+c));		print("\n");	}	return rune;}intgetnsc(void){	int c;	if(peekc != IGN) {		c = peekc;		peekc = IGN;	} else		c = GETC();	for(;;) {		if(!isspace(c))			return c;		if(c == '\n') {			lineno++;			return c;		}		c = GETC();	}}voidunget(int c){	peekc = c;	if(c == '\n')		lineno--;}longescchar(long e, int longflg, int escflg){	long c, l;	int i;loop:	c = getr();	if(c == '\n') {		yyerror("newline in string");		return EOF;	}	if(c != '\\') {		if(c == e)			c = EOF;		return c;	}	c = getr();	if(c == 'x') {		/*		 * note this is not ansi,		 * supposed to only accept 2 hex		 */		i = 2;		if(longflg)			i = 4;		l = 0;		for(; i>0; i--) {			c = getc();			if(c >= '0' && c <= '9') {				l = l*16 + c-'0';				continue;			}			if(c >= 'a' && c <= 'f') {				l = l*16 + c-'a' + 10;				continue;			}			if(c >= 'A' && c <= 'F') {				l = l*16 + c-'A' + 10;				continue;			}			unget(c);			break;		}		if(escflg)			l |= ESC;		return l;	}	if(c >= '0' && c <= '7') {		/*		 * note this is not ansi,		 * supposed to only accept 3 oct		 */		i = 2;		if(longflg)			i = 5;		l = c - '0';		for(; i>0; i--) {			c = getc();			if(c >= '0' && c <= '7') {				l = l*8 + c-'0';				continue;			}			unget(c);		}		if(escflg)			l |= ESC;		return l;	}	switch(c)	{	case '\n':	goto loop;	case 'n':	return '\n';	case 't':	return '\t';	case 'b':	return '\b';	case 'r':	return '\r';	case 'f':	return '\f';	case 'a':	return '\a';	case 'v':	return '\v';	}	return c;}struct{	char	*name;	ushort	lexical;	ushort	type;} itab[] ={	"auto",		LAUTO,		0,	"break",	LBREAK,		0,	"case",		LCASE,		0,	"char",		LCHAR,		TCHAR,	"const",	LCONSTNT,	0,	"continue",	LCONTINUE,	0,	"default",	LDEFAULT,	0,	"do",		LDO,		0,	"double",	LDOUBLE,	TDOUBLE,	"else",		LELSE,		0,	"enum",		LENUM,		0,	"extern",	LEXTERN,	0,	"float",	LFLOAT,		TFLOAT,	"for",		LFOR,		0,	"goto",		LGOTO,		0,	"if",		LIF,		0,	"inline",	LINLINE,	0,	"int",		LINT,		TINT,	"long",		LLONG,		TLONG,	"register",	LREGISTER,	0,	"restrict",	LRESTRICT,	0,	"return",	LRETURN,	0,	"SET",		LSET,		0,	"short",	LSHORT,		TSHORT,	"signed",	LSIGNED,	0,	"signof",	LSIGNOF,	0,	"sizeof",	LSIZEOF,	0,	"static",	LSTATIC,	0,	"struct",	LSTRUCT,	0,	"switch",	LSWITCH,	0,	"typedef",	LTYPEDEF,	0,	"typestr",	LTYPESTR,	0,	"union",	LUNION,		0,	"unsigned",	LUNSIGNED,	0,	"USED",		LUSED,		0,	"void",		LVOID,		TVOID,	"volatile",	LVOLATILE,	0,	"while",	LWHILE,		0,	0};voidcinit(void){	Sym *s;	int i;	Type *t;	nerrors = 0;	lineno = 1;	iostack = I;	iofree = I;	peekc = IGN;	nhunk = 0;	types[TXXX] = T;	types[TCHAR] = typ(TCHAR, T);	types[TUCHAR] = typ(TUCHAR, T);	types[TSHORT] = typ(TSHORT, T);	types[TUSHORT] = typ(TUSHORT, T);	types[TINT] = typ(TINT, T);	types[TUINT] = typ(TUINT, T);	types[TLONG] = typ(TLONG, T);	types[TULONG] = typ(TULONG, T);	types[TVLONG] = typ(TVLONG, T);	types[TUVLONG] = typ(TUVLONG, T);	types[TFLOAT] = typ(TFLOAT, T);	types[TDOUBLE] = typ(TDOUBLE, T);	types[TVOID] = typ(TVOID, T);	types[TENUM] = typ(TENUM, T);	types[TFUNC] = typ(TFUNC, types[TINT]);	types[TIND] = typ(TIND, types[TVOID]);	for(i=0; i<NHASH; i++)		hash[i] = S;	for(i=0; itab[i].name; i++) {		s = slookup(itab[i].name);		s->lexical = itab[i].lexical;		if(itab[i].type != 0)			s->type = types[itab[i].type];	}	blockno = 0;	autobn = 0;	autoffset = 0;	t = typ(TARRAY, types[TCHAR]);	t->width = 0;	symstring = slookup(".string");	symstring->class = CSTATIC;	symstring->type = t;	t = typ(TARRAY, types[TCHAR]);	t->width = 0;	nodproto = new(OPROTO, Z, Z);	dclstack = D;	pathname = allocn(pathname, 0, 100);	if(mygetwd(pathname, 99) == 0) {		pathname = allocn(pathname, 100, 900);		if(mygetwd(pathname, 999) == 0)			strcpy(pathname, "/???");	}	fmtinstall('O', Oconv);	fmtinstall('T', Tconv);	fmtinstall('F', FNconv);	fmtinstall('L', Lconv);	fmtinstall('Q', Qconv);	fmtinstall('|', VBconv);}intfilbuf(void){	Io *i;loop:	i = iostack;	if(i == I)		return EOF;	if(i->f < 0)		goto pop;	fi.c = read(i->f, i->b, BUFSIZ) - 1;	if(fi.c < 0) {		close(i->f);		linehist(0, 0);		goto pop;	}	fi.p = i->b + 1;	return i->b[0] & 0xff;pop:	iostack = i->link;	i->link = iofree;	iofree = i;	i = iostack;	if(i == I)		return EOF;	fi.p = i->p;	fi.c = i->c;	if(--fi.c < 0)		goto loop;	return *fi.p++ & 0xff;}intOconv(Fmt *fp){	int a;	a = va_arg(fp->args, int);	if(a < OXXX || a > OEND)		return fmtprint(fp, "***badO %d***", a);	return fmtstrcpy(fp, onames[a]);}intLconv(Fmt *fp){	char str[STRINGSZ], s[STRINGSZ];	Hist *h;	struct	{		Hist*	incl;	/* start of this include file */		long	idel;	/* delta line number to apply to include */		Hist*	line;	/* start of this #line directive */		long	ldel;	/* delta line number to apply to #line */	} a[HISTSZ];	long l, d;	int i, n;	l = va_arg(fp->args, long);	n = 0;	for(h = hist; h != H; h = h->link) {		if(l < h->line)			break;		if(h->name) {			if(h->offset != 0) {		/* #line directive, not #pragma */				if(n > 0 && n < HISTSZ && h->offset >= 0) {					a[n-1].line = h;					a[n-1].ldel = h->line - h->offset + 1;				}			} else {				if(n < HISTSZ) {	/* beginning of file */					a[n].incl = h;					a[n].idel = h->line;					a[n].line = 0;				}				n++;			}			continue;		}		n--;		if(n > 0 && n < HISTSZ) {			d = h->line - a[n].incl->line;			a[n-1].ldel += d;			a[n-1].idel += d;		}	}	if(n > HISTSZ)		n = HISTSZ;	str[0] = 0;	for(i=n-1; i>=0; i--) {		if(i != n-1) {			if(fp->flags & ~(FmtWidth|FmtPrec))	/* BUG ROB - was f3 */				break;			strcat(str, " ");		}		if(a[i].line)			snprint(s, STRINGSZ, "%s:%ld[%s:%ld]",				a[i].line->name, l-a[i].ldel+1,				a[i].incl->name, l-a[i].idel+1);		else			snprint(s, STRINGSZ, "%s:%ld",				a[i].incl->name, l-a[i].idel+1);		if(strlen(s)+strlen(str) >= STRINGSZ-10)			break;		strcat(str, s);		l = a[i].incl->line - 1;	/* now print out start of this file */	}	if(n == 0)		strcat(str, "<eof>");	return fmtstrcpy(fp, str);}intTconv(Fmt *fp){	char str[STRINGSZ+20], s[STRINGSZ+20];	Type *t, *t1;	int et;	long n;	str[0] = 0;	for(t = va_arg(fp->args, Type*); t != T; t = t->link) {		et = t->etype;		if(str[0])			strcat(str, " ");		if(t->garb&~GINCOMPLETE) {			sprint(s, "%s ", gnames[t->garb&~GINCOMPLETE]);			if(strlen(str) + strlen(s) < STRINGSZ)				strcat(str, s);		}		sprint(s, "%s", tnames[et]);		if(strlen(str) + strlen(s) < STRINGSZ)			strcat(str, s);		if(et == TFUNC && (t1 = t->down)) {			sprint(s, "(%T", t1);			if(strlen(str) + strlen(s) < STRINGSZ)				strcat(str, s);			while(t1 = t1->down) {				sprint(s, ", %T", t1);				if(strlen(str) + strlen(s) < STRINGSZ)					strcat(str, s);			}			if(strlen(str) + strlen(s) < STRINGSZ)				strcat(str, ")");		}		if(et == TARRAY) {			n = t->width;			if(t->link && t->link->width)				n /= t->link->width;			sprint(s, "[%ld]", n);			if(strlen(str) + strlen(s) < STRINGSZ)				strcat(str, s);		}		if(t->nbits) {			sprint(s, " %d:%d", t->shift, t->nbits);			if(strlen(str) + strlen(s) < STRINGSZ)				strcat(str, s);		}		if(typesu[et]) {			if(t->tag) {				strcat(str, " ");				if(strlen(str) + strlen(t->tag->name) < STRINGSZ)					strcat(str, t->tag->name);			} else				strcat(str, " {}");			break;		}	}	return fmtstrcpy(fp, str);}intFNconv(Fmt *fp){	char *str;	Node *n;	n = va_arg(fp->args, Node*);	str = "<indirect>";	if(n != Z && (n->op == ONAME || n->op == ODOT || n->op == OELEM))		str = n->sym->name;	return fmtstrcpy(fp, str);}intQconv(Fmt *fp){	char str[STRINGSZ+20], *s;	long b;	int i;	str[0] = 0;	for(b = va_arg(fp->args, long); b;) {		i = bitno(b);		if(str[0])			strcat(str, " ");		s = qnames[i];		if(strlen(str) + strlen(s) >= STRINGSZ)			break;		strcat(str, s);		b &= ~(1L << i);	}	return fmtstrcpy(fp, str);}intVBconv(Fmt *fp){	char str[STRINGSZ];	int i, n, t, pc;	n = va_arg(fp->args, int);	pc = 0;	/* BUG: was printcol */	i = 0;	while(pc < n) {		t = (pc+4) & ~3;		if(t <= n) {			str[i++] = '\t';			pc = t;			continue;		}		str[i++] = ' ';		pc++;	}	str[i] = 0;	return fmtstrcpy(fp, str);}/* * real allocs */void*alloc(long n){	void *p;	while((uintptr)hunk & MAXALIGN) {		hunk++;		nhunk--;	}	while(nhunk < n)		gethunk();	p = hunk;	nhunk -= n;	hunk += n;	return p;}void*allocn(void *p, long on, long n){	void *q;	q = (uchar*)p + on;	if(q != hunk || nhunk < n) {		while(nhunk < on+n)			gethunk();		memmove(hunk, p, on);		p = hunk;		hunk += on;		nhunk -= on;	}	hunk += n;	nhunk -= n;	return p;}voidsetinclude(char *p){	int i;	char *e;	while(*p != 0) {		e = strchr(p, ' ');		if(e != 0)			*e = '\0';		for(i=1; i < ninclude; i++)			if(strcmp(p, include[i]) == 0)				break;		if(i >= ninclude)			include[ninclude++] = p;		if(ninclude > nelem(include)) {			diag(Z, "ninclude too small %d", nelem(include));			exits("ninclude");		}		if(e == 0)			break;		p = e+1;	}}

⌨️ 快捷键说明

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