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

📄 scan.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
			case 'e':			case 'E':					if( (lxchar=getchar()) == '+' || lxchar == '-' ){						*lxgcp++ = 'e';						}					else {						ungetc(lxchar,stdin);						lxchar = 'e';						}					lxmore( lxchar, LEXDIG );					/* now have the whole thing... */					if ((lxchar=getchar()) == 'f' ||					    lxchar=='F') {					    	goto flt; 						}					else {						ungetc(lxchar,stdin);						goto flt; 						}					    						}				else {  /* no exponent */					ungetc( lxchar ,stdin);					goto flt; 					}			/* vdp004  recongize floating constants by those 			 * that end with an 'f' or a 'F' 			 */ 			case 'f':			case 'F': 				/* Would get here only if we hadn't already			 	 * run into a '.' or an 'e'. vdp004 				 */				uerror ("Illegal floating point constant.");				continue; 			flt:				if (lxchar == 'f' || lxchar == 'F') {					return ( cvtfloat( yytext) ); 				}					else {					return ( cvtdouble( yytext)); 				}			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,	"const",	AR_TA,	CONST,	"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 */	"volatile",	AR_TA,	VOLATILE,	"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=7; break;	case 'e':		c=10; break;	case 'f':		c=13; break;	case 'g':		c=16; break;	case 'i':		c=17; break;	case 'l':		c=19; break;	case 'r':		c=20; break;	case 's':		c=22; break;	case 't':		c=27; break;	case 'u':		c=28; break;	case 'v':		c=30; break;	case 'w':		c=32; 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:			case AR_TA:				/* type word or type attribute */				stwart = instruct;				yylval.nodep = mkty( (TWORD)p->lxrval, 0, p->lxrval );				if (p->lxract == AR_TA)				    return (p->lxrval);   /* CONST/VOLATILE */				else				    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 */				/*RAP001					Let the parser handle it.				*/				return (ASM);			default:				cerror( "bad AR_?? action" );				}			}		}	return( -1 );	}/*RAP001	Action routine to read the asm tail. The text between the "'s is	stored in a buffer which will be put out later in match.c. It will	be put out immediately if the asm was at the function definition	level.	The only real change to the code that used to handle asm's is to	replace the putchar with code to save the information in a buffer.*/procasm(){	int c, cnt;	char *tasmptr;	cnt = 0;	asm_esc = 1; /* warn the world! */	lxget( ' ', LEXWS );	if( getchar() != '(' ) goto badasm;	lxget( ' ', LEXWS );	if( getchar() != '"' ) goto badasm;	asmptr  = tasmptr = (char *)malloc(40);	*asmptr = '\0';	/* In case LINT is defined or theres an error */	while( (c=getchar()) != '"' ){		if( c=='\n' || c==EOF ) goto badasm;# ifndef LINT							/* Increase the buffer if its about to overflow.       */		/* "+2" is used because of the CR and NIL to be added. */		/* The buffer is always a multiple of 40 characters.   */		if ( ( (cnt+2) % 40) == 0 ){			asmptr = (char *)realloc( asmptr, cnt + 42 );			tasmptr = asmptr + cnt;			}		*tasmptr++ = c;		cnt++;# endif		}	lxget( ' ', LEXWS );	if( getchar() != ')' ) goto badasm;# ifndef LINT	/*		Now terminate with CR and NIL	*/	*tasmptr++ = '\n';	*tasmptr   = '\0';# endif	return( 0 );badasm:	uerror( "bad asm construction");	free(asmptr);		/* Free the buffer */	asmptr = (char *)NIL;	/* Ignore any partial information */	return( 0 );		}/*RAP001	Put out the asm information. This routine is called immediately	for asm's at the function declaration level or in match.c for	asm's in a function context in procedural code.	All this  is done to force the code out at a time that will make	the asm look semantically like a function call.*/outasm(cptr)char *cptr;{	char *tptr=cptr;	if ( tptr != (char *)NIL){# ifndef ONEPASS# ifndef LINT		putchar(')');# endif# endif		while(*tptr) putchar(*tptr++);		free(cptr);		}}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			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';#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			}		}	}#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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -