scan.c

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

C
1,127
字号
static char *sccsid ="@(#)scan.c	1.3 (Berkeley) 12/24/82";# include "mfile1"# include <a.out.h># include <stab.h># include <ctype.h>	/* temporarily */int asm_esc = 0; /* asm escaped used in file */	/* lexical actions */# define A_ERR 0		/* illegal character */# define A_LET 1		/* saw a letter */# define A_DIG 2		/* saw a digit */# define A_1C 3			/* return a single character */# define A_STR 4		/* string */# define A_CC 5			/* character constant */# define A_BCD 6		/* GCOS BCD constant */# define A_SL 7			/* saw a / */# define A_DOT 8		/* saw a . */# define A_PL 9		/* + */# define A_MI 10		/* - */# define A_EQ 11		/* = */# define A_NOT 12		/* ! */# define A_LT 13		/* < */# define A_GT 14		/* > */# define A_AND 16		/* & */# define A_OR 17		/* | */# define A_WS 18		/* whitespace (not \n) */# define A_NL 19		/* \n */	/* character classes */# define LEXLET 01# define LEXDIG 02# define LEXOCT 04# define LEXHEX 010# define LEXWS 020# define LEXDOT 040	/* reserved word actions */# define AR_TY 0		/* type word */# define AR_RW 1		/* simple reserved word */# define AR_CL 2		/* storage class word */# define AR_S 3		/* struct */# define AR_U 4		/* union */# define AR_E 5		/* enum */# define AR_A 6		/* asm */	/* text buffer */#ifndef FLEXNAMES# define LXTSZ 100#else#define	LXTSZ	BUFSIZ#endifchar yytext[LXTSZ];char * lxgcp;/* extern int proflg; CXREF *//* extern int gdebug; CXREF */int oldway;		/* allocate storage so lint will compile as well */unsigned caloff();	/* ARGSUSED */mainp1( argc, argv ) int argc; char *argv[]; {  /* control multiple files */	register i;	register char *cp;	extern int idebug, bdebug, tdebug, edebug, ddebug, xdebug;	extern unsigned int offsz;	int fdef = 0;	char *release = "PCC/364r1 vax uts3.0";	offsz = caloff();	for( i=1; i<argc; ++i ){		if( *(cp=argv[i]) == '-' && *++cp == 'X' ){			while( *++cp ){				switch( *cp ){				case 'r':					fprintf( stderr, "Release: %s\n",						release );					break;				case 'd':					++ddebug;					break;				case 'i':					++idebug;					break;				case 'b':					++bdebug;					break;				case 't':					++tdebug;					break;				case 'e':					++edebug;					break;				case 'x':					++xdebug;					break;				case 'P':	/* profiling *//*					++proflg; CXREF */					break;				case 'g':					/* ++gdebug; CXREF */					break;				case 'G':					/* ++gdebug; CXREF */					oldway = 1;					break;					}				}			}		}# ifdef ONEPASS /*	p2init( argc, argv );	CXREF */# endif	for( i=0; i<SYMTSZ; ++i ) stab[i].stype = TNULL;	lxinit();	tinit();	mkdope();	lineno = 1;	/* dimension table initialization */	dimtab[NULL] = 0;	dimtab[CHAR] = SZCHAR;	dimtab[INT] = SZINT;	dimtab[FLOAT] = SZFLOAT;	dimtab[DOUBLE] = SZDOUBLE;	dimtab[LONG] = SZLONG;	dimtab[SHORT] = SZSHORT;	dimtab[UCHAR] = SZCHAR;	dimtab[USHORT] = SZSHORT;	dimtab[UNSIGNED] = SZINT;	dimtab[ULONG] = SZLONG;	/* starts past any of the above */	curdim = 16;	reached = 1;	yyparse();	yyaccpt();	ejobcode( nerrors ? 1 : 0 );	return(nerrors?1:0);	}# ifdef ibm# define CSMASK 0377# define CSSZ 256# else# define CSMASK 0177# define CSSZ 128# endifshort lxmask[CSSZ+1];lxenter( s, m ) register char *s; register short m; {	/* enter a mask into lxmask */	register c;	while( c= *s++ ) lxmask[c+1] |= m;	}# define lxget(c,m) (lxgcp=yytext,lxmore(c,m))lxmore( c, m )  register c, m; {	register char *cp;	*(cp = lxgcp) = c;	while( c=getchar(), lxmask[c+1]&m ){		if( cp < &yytext[LXTSZ-1] ){			*++cp = c;			}		}	ungetc(c,stdin);	*(lxgcp = cp+1) = '\0';	}struct lxdope {	short lxch;	/* the character */	short lxact;	/* the action to be performed */	short lxtok;	/* the token number to be returned */	short lxval;	/* the value to be returned */	} lxdope[] = {	'@',	A_ERR,	0,	0,	/* illegal characters go here... */	'_',	A_LET,	0,	0,	/* letters point here */	'0',	A_DIG,	0,	0,	/* digits point here */	' ',	A_WS,	0,	0,	/* whitespace goes here */	'\n',	A_NL,	0,	0,	'"',	A_STR,	0,	0,	/* character string */	'\'',	A_CC,	0,	0,	/* character constant */	'`',	A_BCD,	0,	0,	/* GCOS BCD constant */	'(',	A_1C,	LP,	0,	')',	A_1C,	RP,	0,	'{',	A_1C,	LC,	0,	'}',	A_1C,	RC,	0,	'[',	A_1C,	LB,	0,	']',	A_1C,	RB,	0,	'*',	A_1C,	MUL,	MUL,	'?',	A_1C,	QUEST,	0,	':',	A_1C,	COLON,	0,	'+',	A_PL,	PLUS,	PLUS,	'-',	A_MI,	MINUS,	MINUS,	'/',	A_SL,	DIVOP,	DIV,	'%',	A_1C,	DIVOP,	MOD,	'&',	A_AND,	AND,	AND,	'|',	A_OR,	OR,	OR,	'^',	A_1C,	ER,	ER,	'!',	A_NOT,	UNOP,	NOT,	'~',	A_1C,	UNOP,	COMPL,	',',	A_1C,	CM,	CM,	';',	A_1C,	SM,	0,	'.',	A_DOT,	STROP,	DOT,	'<',	A_LT,	RELOP,	LT,	'>',	A_GT,	RELOP,	GT,	'=',	A_EQ,	ASSIGN,	ASSIGN,	-1,	A_1C,	0,	0,	};struct lxdope *lxcp[CSSZ+1];lxinit(){	register struct lxdope *p;	register i;	register char *cp;	/* set up character classes */	lxenter( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$", LEXLET );	lxenter( "0123456789", LEXDIG );	lxenter( "0123456789abcdefABCDEF", LEXHEX );		/* \013 should become \v someday; \013 is OK for ASCII and EBCDIC */	lxenter( " \t\r\b\f\013", LEXWS );	lxenter( "01234567", LEXOCT );	lxmask['.'+1] |= LEXDOT;	/* make lxcp point to appropriate lxdope entry for each character */	/* initialize error entries */	for( i= 0; i<=CSSZ; ++i ) lxcp[i] = lxdope;	/* make unique entries */	for( p=lxdope; ; ++p ) {		lxcp[p->lxch+1] = p;		if( p->lxch < 0 ) break;		}	/* handle letters, digits, and whitespace */	/* by convention, first, second, and third places */	cp = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$";	while( *cp ) lxcp[*cp++ + 1] = &lxdope[1];	cp = "123456789";	while( *cp ) lxcp[*cp++ + 1] = &lxdope[2];	cp = "\t\b\r\f\013";	while( *cp ) lxcp[*cp++ + 1] = &lxdope[3];	/* first line might have title */	lxtitle();	}int lxmatch;  /* character to be matched in char or string constant */lxstr(ct){	/* match a string or character constant, up to lxmatch */	register c;	register val;	register i;	i=0;	while( (c=getchar()) != lxmatch ){		switch( c ) {		case EOF:			uerror( "unexpected EOF" );			break;		case '\n':			uerror( "newline in string or char constant" );			++lineno;			break;		case '\\':			switch( c = getchar() ){			case '\n':				++lineno;				continue;			default:				val = c;				goto mkcc;			case 'n':				val = '\n';				goto mkcc;			case 'r':				val = '\r';				goto mkcc;			case 'b':				val = '\b';				goto mkcc;			case 't':				val = '\t';				goto mkcc;			case 'f':				val = '\f';				goto mkcc;			case 'v':				val = '\013';				goto mkcc;			case '0':			case '1':			case '2':			case '3':			case '4':			case '5':			case '6':			case '7':				val = c-'0';				c=getchar();  /* try for 2 */				if( lxmask[c+1] & LEXOCT ){					val = (val<<3) | (c-'0');					c = getchar();  /* try for 3 */					if( lxmask[c+1] & LEXOCT ){						val = (val<<3) | (c-'0');						}					else ungetc( c ,stdin);					}				else ungetc( c ,stdin);				goto mkcc1;				}		default:			val =c;		mkcc:			val = CCTRANS(val);		mkcc1:			if( lxmatch == '\'' ){				val = CHARCAST(val);  /* it is, after all, a "character" constant */				makecc( val, i );				}			else { /* stash the byte into the string */				if( strflg ) {					if( ct==0 || i<ct ) putbyte( val );					else if( i == ct ) werror( "non-null byte ignored in string initializer" );					}				else bycode( val, i );				}			++i;			continue;			}		break;		}	/* end of string or  char constant */	if( lxmatch == '"' ){		if( strflg ){ /* end the string */			if( ct==0 || i<ct ) putbyte( 0 );  /* the null at the end */			}		else {  /* the initializer gets a null byte */			bycode( 0, i++ );			bycode( -1, i );			dimtab[curdim] = i;  /* in case of later sizeof ... */			}		}	else { /* end the character constant */		if( i == 0 ) uerror( "empty character constant" );		if( i>(SZINT/SZCHAR) || ( (pflag||hflag)&&i>1) )			uerror( "too many characters in character constant" );		}	}lxcom(){	register c;	/* saw a /*: process a comment */	for(;;){		switch( c = getchar() ){		case EOF:			uerror( "unexpected EOF" );			return;		case '\n':			++lineno;		default:			continue;		case '*':			if( (c = getchar()) == '/' ) return;			else ungetc( c ,stdin);			continue;# ifdef LINT		case 'V':			lxget( c, LEXLET|LEXDIG );			{				extern int vaflag;				int i;				i = yytext[7]?yytext[7]-'0':0;				yytext[7] = '\0';				if( strcmp( yytext, "VARARGS" ) ) continue;				vaflag = i;				continue;				}		case 'L':			lxget( c, LEXLET );			if( strcmp( yytext, "LINTLIBRARY" ) ) continue;			{				extern int libflag;				libflag = 1;				}			continue;		case 'A':			lxget( c, LEXLET );			if( strcmp( yytext, "ARGSUSED" ) ) continue;			{				extern int argflag, vflag;				argflag = 1;				vflag = 0;				}			continue;		case 'N':			lxget( c, LEXLET );			if( strcmp( yytext, "NOTREACHED" ) ) continue;			reached = 0;			continue;# endif			}		}	}yylex(){	for(;;){		register lxchar;		register struct lxdope *p;		register struct symtab *sp;		int id;		switch( (p=lxcp[(lxchar=getchar())+1])->lxact ){		onechar:			ungetc( lxchar ,stdin);		case A_1C:			/* eat up a single character, and return an opcode */			yylval.intval = p->lxval;			return( p->lxtok );		case A_ERR:			uerror( "illegal character: %03o (octal)", lxchar );			break;		case A_LET:			/* collect an identifier, check for reserved word, and return */			lxget( lxchar, LEXLET|LEXDIG );			if( (lxchar=lxres()) > 0 ) return( lxchar ); /* reserved word */			if( lxchar== 0 ) continue;#ifdef FLEXNAMES			id = lookup( hash(yytext),#else			id = lookup( yytext,#endif				/* tag name for struct/union/enum */				(stwart&TAGNAME)? STAG:				/* member name for struct/union */				(stwart&(INSTRUCT|INUNION|FUNNYNAME))?SMOS:0 );			sp = &stab[id];			if( sp->sclass == TYPEDEF && !stwart ){				ref(id, lineno);	/* CXREF */				stwart = instruct;				yylval.nodep = mkty( sp->stype, sp->dimoff, sp->sizoff );				return( TYPE );				}			stwart = (stwart&SEENAME) ? instruct : 0;			yylval.intval = id;			return( NAME );		case A_DIG:			/* collect a digit string, then look at last one... */			lastcon = 0;			lxget( lxchar, LEXDIG );			switch( lxchar=getchar() ){			case 'x':			case 'X':				if( yytext[0] != '0' && !yytext[1] ) uerror( "illegal hex constant" );				lxmore( lxchar, LEXHEX );				/* convert the value */				{					register char *cp;					for( cp = yytext+2; *cp; ++cp ){						/* this code won't work for all wild character sets,						   but seems ok for ascii and ebcdic */						lastcon <<= 4;						if( isdigit( *cp ) ) lastcon += *cp-'0';						else if( isupper( *cp ) ) lastcon += *cp - 'A'+ 10;						else lastcon += *cp - 'a'+ 10;						}					}			hexlong:				/* criterion for longness for hex and octal constants is that it				   fit within 0177777 */				if( lastcon & ~0177777L ) yylval.intval = 1;				else yylval.intval = 0;				goto islong;			case '.':				lxmore( lxchar, LEXDIG );			getfp:				if( (lxchar=getchar()) == 'e' || lxchar == 'E' ){ /* exponent */			case 'e':			case 'E':					if( (lxchar=getchar()) == '+' || lxchar == '-' ){						*lxgcp++ = 'e';						}					else {						ungetc(lxchar,stdin);						lxchar = 'e';						}					lxmore( lxchar, LEXDIG );					/* now have the whole thing... */					}				else {  /* no exponent */					ungetc( lxchar ,stdin);					}				return( isitfloat( yytext ) );

⌨️ 快捷键说明

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