scan.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,127 行 · 第 1/2 页

C
1,127
字号
			default:				ungetc( lxchar ,stdin);				if( yytext[0] == '0' ){					/* convert in octal */					register char *cp;					for( cp = yytext+1; *cp; ++cp ){						lastcon <<= 3;						lastcon += *cp - '0';						}					goto hexlong;					}				else {					/* convert in decimal */					register char *cp;					for( cp = yytext; *cp; ++cp ){						lastcon = lastcon * 10 + *cp - '0';						}					}				/* decide if it is long or not (decimal case) */				/* if it is positive and fits in 15 bits, or negative and				   and fits in 15 bits plus an extended sign, it is int; otherwise long */				/* if there is an l or L following, all bets are off... */				{	CONSZ v;					v = lastcon & ~077777L;					if( v == 0 || v == ~077777L ) yylval.intval = 0;					else yylval.intval = 1;					}			islong:				/* finally, look for trailing L or l */				if( (lxchar = getchar()) == 'L' || lxchar == 'l' ) yylval.intval = 1;				else ungetc( lxchar ,stdin);				return( ICON );				}		case A_DOT:			/* look for a dot: if followed by a digit, floating point */			lxchar = getchar();			if( lxmask[lxchar+1] & LEXDIG ){				ungetc(lxchar,stdin);				lxget( '.', LEXDIG );				goto getfp;				}			stwart = FUNNYNAME;			goto onechar;		case A_STR:			/* string constant */			lxmatch = '"';			return( STRING );		case A_CC:			/* character constant */			lxmatch = '\'';			lastcon = 0;			lxstr(0);			yylval.intval = 0;			return( ICON );		case A_BCD:			{				register i;				int j;				for( i=0; i<LXTSZ; ++i ){					if( ( j = getchar() ) == '`' ) break;					if( j == '\n' ){						uerror( "newline in BCD constant" );						break;						}					yytext[i] = j;					}				yytext[i] = '\0';				if( i>6 ) uerror( "BCD constant exceeds 6 characters" );# ifdef gcos				else strtob( yytext, &lastcon, i );				lastcon >>= 6*(6-i);# else				uerror( "gcos BCD constant illegal" );# endif				yylval.intval = 0;  /* not long */				return( ICON );				}		case A_SL:			/* / */			if( (lxchar=getchar()) != '*' ) goto onechar;			lxcom();		case A_WS:			continue;		case A_NL:			++lineno;			lxtitle();			continue;		case A_NOT:			/* ! */			if( (lxchar=getchar()) != '=' ) goto onechar;			yylval.intval = NE;			return( EQUOP );		case A_MI:			/* - */			if( (lxchar=getchar()) == '-' ){				yylval.intval = DECR;				return( INCOP );				}			if( lxchar != '>' ) goto onechar;			stwart = FUNNYNAME;			yylval.intval=STREF;			return( STROP );		case A_PL:			/* + */			if( (lxchar=getchar()) != '+' ) goto onechar;			yylval.intval = INCR;			return( INCOP );		case A_AND:			/* & */			if( (lxchar=getchar()) != '&' ) goto onechar;			return( yylval.intval = ANDAND );		case A_OR:			/* | */			if( (lxchar=getchar()) != '|' ) goto onechar;			return( yylval.intval = OROR );		case A_LT:			/* < */			if( (lxchar=getchar()) == '<' ){				yylval.intval = LS;				return( SHIFTOP );				}			if( lxchar != '=' ) goto onechar;			yylval.intval = LE;			return( RELOP );		case A_GT:			/* > */			if( (lxchar=getchar()) == '>' ){				yylval.intval = RS;				return(SHIFTOP );				}			if( lxchar != '=' ) goto onechar;			yylval.intval = GE;			return( RELOP );		case A_EQ:			/* = */			switch( lxchar = getchar() ){			case '=':				yylval.intval = EQ;				return( EQUOP );			case '+':				yylval.intval = ASG PLUS;				break;			case '-':				yylval.intval = ASG MINUS;			warn:				if( lxmask[ (lxchar=getchar())+1] & (LEXLET|LEXDIG|LEXDOT) ){					werror( "ambiguous assignment: assignment op taken" );					}				ungetc( lxchar ,stdin);				break;			case '*':				yylval.intval = ASG MUL;				goto warn;			case '/':				yylval.intval = ASG DIV;				break;			case '%':				yylval.intval = ASG MOD;				break;			case '&':				yylval.intval = ASG AND;				break;			case '|':				yylval.intval = ASG OR;				break;			case '^':				yylval.intval = ASG ER;				break;			case '<':				if( (lxchar=getchar()) != '<' ){					uerror( "=<%c illegal", lxchar );					}				yylval.intval = ASG LS;				break;			case '>':				if( (lxchar=getchar()) != '>' ){					uerror( "=>%c illegal", lxchar );					}				yylval.intval = ASG RS;				break;			default:				goto onechar;				}			return( ASOP );		default:			cerror( "yylex error, character %03o (octal)", lxchar );			}		/* ordinarily, repeat here... */		cerror( "out of switch in yylex" );		}	}struct lxrdope {	/* dope for reserved, in alphabetical order */	char *lxrch;	/* name of reserved word */	short lxract;	/* reserved word action */	short lxrval;	/* value to be returned */	} lxrdope[] = {	"asm",		AR_A,	0,	"auto",		AR_CL,	AUTO,	"break",	AR_RW,	BREAK,	"char",		AR_TY,	CHAR,	"case",		AR_RW,	CASE,	"continue",	AR_RW,	CONTINUE,	"double",	AR_TY,	DOUBLE,	"default",	AR_RW,	DEFAULT,	"do",		AR_RW,	DO,	"extern",	AR_CL,	EXTERN,	"else",		AR_RW,	ELSE,	"enum",		AR_E,	ENUM,	"for",		AR_RW,	FOR,	"float",	AR_TY,	FLOAT,	"fortran",	AR_CL,	FORTRAN,	"goto",		AR_RW,	GOTO,	"if",		AR_RW,	IF,	"int",		AR_TY,	INT,	"long",		AR_TY,	LONG,	"return",	AR_RW,	RETURN,	"register",	AR_CL,	REGISTER,	"switch",	AR_RW,	SWITCH,	"struct",	AR_S,	0,	"sizeof",	AR_RW,	SIZEOF,	"short",	AR_TY,	SHORT,	"static",	AR_CL,	STATIC,	"typedef",	AR_CL,	TYPEDEF,	"unsigned",	AR_TY,	UNSIGNED,	"union",	AR_U,	0,	"void",		AR_TY,	UNDEF, /* tymerge adds FTN */	"while",	AR_RW,	WHILE,	"",		0,	0,	/* to stop the search */	};lxres() {	/* check to see of yytext is reserved; if so,	/* do the appropriate action and return */	/* otherwise, return -1 */	register c, ch;	register struct lxrdope *p;	ch = yytext[0];	if( !islower(ch) ) return( -1 );	switch( ch ){	case 'a':		c=0; break;	case 'b':		c=2; break;	case 'c':		c=3; break;	case 'd':		c=6; break;	case 'e':		c=9; break;	case 'f':		c=12; break;	case 'g':		c=15; break;	case 'i':		c=16; break;	case 'l':		c=18; break;	case 'r':		c=19; break;	case 's':		c=21; break;	case 't':		c=26; break;	case 'u':		c=27; break;	case 'v':		c=29; break;	case 'w':		c=30; break;	default:		return( -1 );		}	for( p= lxrdope+c; p->lxrch[0] == ch; ++p ){		if( !strcmp( yytext, p->lxrch ) ){ /* match */			switch( p->lxract ){			case AR_TY:				/* type word */				stwart = instruct;				yylval.nodep = mkty( (TWORD)p->lxrval, 0, p->lxrval );				return( TYPE );			case AR_RW:				/* ordinary reserved word */				return( yylval.intval = p->lxrval );			case AR_CL:				/* class word */				yylval.intval = p->lxrval;				return( CLASS );			case AR_S:				/* struct */				stwart = INSTRUCT|SEENAME|TAGNAME;				yylval.intval = INSTRUCT;				return( STRUCT );			case AR_U:				/* union */				stwart = INUNION|SEENAME|TAGNAME;				yylval.intval = INUNION;				return( STRUCT );			case AR_E:				/* enums */				stwart = SEENAME|TAGNAME;				return( yylval.intval = ENUM );			case AR_A:				/* asm */				asm_esc = 1; /* warn the world! */				lxget( ' ', LEXWS );				if( getchar() != '(' ) goto badasm;				lxget( ' ', LEXWS );				if( getchar() != '"' ) goto badasm;# ifndef ONEPASS# ifndef LINT				putchar(')');# endif# endif				while( (c=getchar()) != '"' ){					if( c=='\n' || c==EOF ) goto badasm;# ifndef LINT					putchar(c);# endif					}				lxget( ' ', LEXWS );				if( getchar() != ')' ) goto badasm;# ifndef LINT				putchar('\n');# endif				return( 0 );			badasm:				uerror( "bad asm construction" );				return( 0 );			default:				cerror( "bad AR_?? action" );				}			}		}	return( -1 );	}extern int	labelno;lxtitle(){	/* called after a newline; set linenumber and file name */	register c, val;	register char *cp, *cq;	for(;;){  /* might be several such lines in a row */		if( (c=getchar()) != '#' ){			if( c != EOF ) ungetc(c,stdin);/*#ifndef LINT			if ( lastloc != PROG) return;			cp = ftitle;			cq = ititle;			while ( *cp ) if (*cp++ != *cq++) return;			if ( *cq ) return;			psline();#endif	CXREF */			return;			}		lxget( ' ', LEXWS );		val = 0;		for( c=getchar(); isdigit(c); c=getchar() ){			val = val*10+ c - '0';			}		ungetc( c, stdin );		lineno = val;		lxget( ' ', LEXWS );		if( (c=getchar()) != '\n' ){			for( cp=ftitle; c!='\n'; c=getchar(),++cp ){				*cp = c;				}			*cp = '\0';			fprintf(outfp,"%s\n",ftitle);	/* CXREF *//*#ifndef LINT			if (ititle[0] == '\0') {				cp = ftitle;				cq = ititle;				while ( *cp )  					*cq++ = *cp++;				*cq = '\0';				*--cq = '\0';#ifndef FLEXNAMES				for ( cp = ititle+1; *(cp-1); cp += 8 ) {					pstab(cp, N_SO);					if (gdebug) printf("0,0,LL%d\n", labelno);					}#else				pstab(ititle+1, N_SO);				if (gdebug) printf("0,0,LL%d\n", labelno); #endif				*cq = '"';			printf("LL%d:\n", labelno++);				}#endif		CXREF */			}		}	}#ifdef FLEXNAMES#define	NSAVETAB	4096char	*savetab;int	saveleft;char *savestr(cp)	register char *cp;{	register int len;	len = strlen(cp) + 1;	if (len > saveleft) {		saveleft = NSAVETAB;		if (len > saveleft)			saveleft = len;		savetab = (char *)malloc(saveleft);		if (savetab == 0)			cerror("Ran out of memory (savestr)");	}	strncpy(savetab, cp, len);	cp = savetab;	savetab += len;	saveleft -= len;	return (cp);}/* * The definition for the segmented hash tables. */#define	MAXHASH	20#define	HASHINC	1013struct ht {	char	**ht_low;	char	**ht_high;	int	ht_used;} htab[MAXHASH];char *hash(s)	char *s;{	register char **h;	register i;	register char *cp;	struct ht *htp;	int sh;	/*	 * The hash function is a modular hash of	 * the sum of the characters with the sum	 * doubled before each successive character	 * is added.	 */	cp = s;	i = 0;	while (*cp)		i = i*2 + *cp++;	sh = (i&077777) % HASHINC;	cp = s;	/*	 * There are as many as MAXHASH active	 * hash tables at any given point in time.	 * The search starts with the first table	 * and continues through the active tables	 * as necessary.	 */	for (htp = htab; htp < &htab[MAXHASH]; htp++) {		if (htp->ht_low == 0) {			register char **hp =			    (char **) calloc(sizeof (char **), HASHINC);			if (hp == 0)				cerror("ran out of memory (hash)");			htp->ht_low = hp;			htp->ht_high = htp->ht_low + HASHINC;		}		h = htp->ht_low + sh;		/*		 * quadratic rehash increment		 * starts at 1 and incremented		 * by two each rehash.		 */		i = 1;		do {			if (*h == 0) {				if (htp->ht_used > (HASHINC * 3)/4)					break;				htp->ht_used++;				*h = savestr(cp);				return (*h);			}			if (**h == *cp && strcmp(*h, cp) == 0)				return (*h);			h += i;			i += 2;			if (h >= htp->ht_high)				h -= HASHINC;		} while (i < HASHINC);	}	cerror("ran out of hash tables");}#endif

⌨️ 快捷键说明

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