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

📄 getsym.c

📁 一款拥有一定历史的C语言编译器
💻 C
📖 第 1 页 / 共 4 页
字号:
	, {			/* U and >16 bits, short int */
	Ox00010000UL, S | U, tk_ulconst, "unsigned long"}
	, {			/* L */
	Ox0UL, L, tk_lconst, (const char *) NULL}
	, {			/* >16 bits, short int */
	Ox00010000UL, S, tk_lconst, "long"}
	, {			/* U */
	Ox0UL, S | U, tk_uconst, (const char *) NULL}
	, {			/* >15 bits, hex/octal, short int */
	Ox8000UL, S | H, tk_uconst, "unsigned"}
	, {			/* >15 bits, short int */
	Ox8000UL, S, tk_lconst, "long"}
	, {			/* int */
	Ox0UL, H, tk_iconst, (const char *) NULL}
	, {			/* int */
	Ox0UL, 0, tk_iconst, (const char *) NULL}
    }
    , *typeptr;

    assert (rep <= 1);
    
#ifdef LONGLONG
#ifdef LONGLONG_BOOTSTRAP
    {
	static int init_done = 0;

	
	if (0 == init_done) {
	    UVAL   uval;

	    uval = (UVAL) 1;
	    typetab[1].minval = uval << 63;
	    uval = (UVAL) 1;
	    typetab[2].minval = uval << 63;
	    uval = (UVAL) 1;
	    typetab[3].minval = uval << 32;
	    uval = (UVAL) 1;
	    typetab[4].minval = uval << 63;
	    init_done = 1;
	}
    }
    
#endif	/* LONGLONG_BOOTSTRAP */
#endif	/* LONGLONG */
#ifndef SYNTAX_CORRECT
    if (overflow) {
	message (ERR_REPRESENT, "");
    }
#endif /* SYNTAX_CORRECT */
    if (tp_int->size == tp_short->size) {
	rep |= S;
    }
    /*
     *      first check suffixes.
     *      L, U, LL, and combinations are allowed.
     */
    for (;;) {
	if (*bufcur == (CHAR) 'l' || *bufcur == (CHAR) 'L') {
	    if (rep & L) {
		if ((lang_option >= LANG_C99) && (rep & LL)) {
		    break;
		}
		rep |= LL;
	    }
	    rep |= L;
	} else if (*bufcur == (CHAR) 'u' || *bufcur == (CHAR) 'U') {
	    if (rep & U) {
		break;
	    }
	    rep |= U;
	} else {
	    break;
	}
	nextch ();
    }

    /*
     *      now search table for first match
     */
#ifdef LONGLONG
    if (is_debugging (DEBUG_LONGLONG)) {
	VOIDCAST fprintf (stderr, "test_int: ival = %s\n",
			   longlongStr (ival));
    }
    
#endif	/* LONGLONG */
    for (typeptr = typetab;; typeptr++) {
        if ((rep & typeptr->repmask) != typeptr->repmask) {
	    continue;
	}
#ifndef SYNTAX_CORRECT
#ifdef LONGLONG
	if (is_debugging (DEBUG_LONGLONG)) {
	    VOIDCAST fprintf (stderr, "test_int: min  = %s\n",
			       longlongStr (typeptr->minval));
	}
	
#endif	/* LONGLONG */
	if (ival > typeptr->minval) {
	    if (typeptr->msg) {
		message (WARN_CONSTANT, typeptr->msg);
	    }
	    break;
	}
#endif	/* SYNTAX_CORRECT */
	if (ival == typeptr->minval) {
	    break;
	}
    }
    
#ifdef LONGLONG
    if (is_debugging (DEBUG_LONGLONG)) {
        VOIDCAST fprintf (stderr, "test_int: type = %d\n", typeptr->type);
        VOIDCAST fprintf (stderr, "test_int: mask = 0x%x\n",
			   typeptr->repmask);
        VOIDCAST fprintf (stderr, "test_int: min  = %s\n",
			       longlongStr (typeptr->minval));
    }
#endif /* LONGLONG */
    lastst = typeptr->type;
}

/*
 *	test_int() - Test on float and double constants.
 */
static void test_real P0 (void)
{
    switch (*bufcur) {
    case 'f':
    case 'F':
	lastst = tk_fconst;
	nextch ();
	break;
    case 'l':
    case 'L':
	lastst = tk_lrconst;
	nextch ();
	break;
    default:
	break;
    }
}

/*
 *	getdecimal() - get integers
 *
 *	rval is computed simultaneously - this handles floating point
 *	constants whose integer part is greater than INT_MAX correctly,
 *	e. g. 10000000000000000000000.0
 */
static void getdecimal P0 (void)
{
    register UVAL i = (UVAL) 0;
    register unsigned j;
    UVAL    old = (UVAL) 0;

#ifdef FLOAT_SUPPORT
#ifndef FLOAT_BOOTSTRAP
    register RVAL r = F_zero;

#endif /* FLOAT_BOOTSTRAP */
#endif /* FLOAT_SUPPORT */

    while (is_digit (*bufcur)) {
	j = radix36 (*bufcur);
	i = ((UVAL) 10 * i) + (UVAL) j;
	if (old > i) {
	    /* must have wrapped the constant ... too big */
	    overflow = TRUE;
	}
	old = i;
#ifdef FLOAT_SUPPORT
#ifndef FLOAT_BOOTSTRAP
	r = F_ten * r + (RVAL) j;
#endif /* FLOAT_BOOTSTRAP */
#endif /* FLOAT_SUPPORT */
	nextch ();
    }
    ival = i;
#ifdef FLOAT_SUPPORT
#ifndef FLOAT_BOOTSTRAP
    rval = r;
#endif /* FLOAT_BOOTSTRAP */
#endif /* FLOAT_SUPPORT */
}

/*
 *	getoctal() - get an octal number
 */
static void getoctal P0 (void)
{
    register UVAL i = (UVAL) 0;
    register unsigned j;
    UVAL    old = (UVAL) 0;

    while (is_octal (*bufcur)) {
	j = radix36 (*bufcur);
	i = ((UVAL) 8 * i) + (UVAL) j;
	if (old > i) {
	    /* must have wrapped the constant ... too big */
	    overflow = TRUE;
	}
	old = i;
	nextch ();
    }
    ival = i;
}

/*
 *	gethex() - get a hexadecimal number.
 */
static void gethex P0 (void)
{
    register UVAL i = (UVAL) 0;
    register unsigned j;
    UVAL    old = (UVAL) 0;

#ifdef FLOAT_SUPPORT
#ifndef FLOAT_BOOTSTRAP
    register RVAL r = F_zero;

#endif /* FLOAT_BOOTSTRAP */
#endif /* FLOAT_SUPPORT */


#ifndef SYNTAX_CORRECT
    if (!is_hex (*bufcur)) {
	static CHAR temp[] = { " " };

	temp[0] = *bufcur;
	message (ERR_PUNCT, temp);
    }
#endif /* SYNTAX_CORRECT */
    while (is_hex (*bufcur)) {
	j = radix36 (*bufcur);
	i = ((UVAL) 16 * i) + (UVAL) j;
	if (old > i) {
	    /* must have wrapped the constant ... too big */
	    overflow = TRUE;
	}
	old = i;
#ifdef FLOAT_SUPPORT
#ifndef FLOAT_BOOTSTRAP
	r = F_sixteen * r + (RVAL) j;
#endif /* FLOAT_BOOTSTRAP */
#endif /* FLOAT_SUPPORT */
	nextch ();
    }
    ival = i;
}

/*
 *	getfrac() - get fraction part of a floating number.
 *
 *	Since 0.1 has no exact representation in a binary base,
 *	we divide by 10.0 instead of multiplying by 0.1
 *	(Thanks to Michael Mueller for this comment)
 *	Improved algorithym by doing a single division at the end
 *	- supplied by Tom Watson.
 */
static void getfrac P0 (void)
{
#ifdef FLOAT_SUPPORT
#ifndef FLOAT_BOOTSTRAP
    RVAL    frmul;
    RVAL    fraction;

    frmul = F_one;
    fraction = F_zero;
    while (is_digit (*bufcur)) {
	frmul *= F_ten;
	fraction *= F_ten;
	fraction += (RVAL) radix36 (*bufcur);
	nextch ();
    }
    rval += fraction / frmul;
    lastst = tk_rconst;
#endif /* FLOAT_BOOTSTRAP */
#endif /* FLOAT_SUPPORT */
}

static void gethexfrac P0 (void)
{
#ifdef FLOAT_SUPPORT
#ifndef FLOAT_BOOTSTRAP
    RVAL    frmul;
    RVAL    fraction;

    frmul = F_one;
    fraction = F_zero;
    while (is_hex (*bufcur)) {
	frmul *= F_sixteen;
	fraction *= F_sixteen;
	fraction += (RVAL) radix36 (*bufcur);
	nextch ();
    }
    rval += fraction / frmul;
    lastst = tk_rconst;
#endif /* FLOAT_BOOTSTRAP */
#endif /* FLOAT_SUPPORT */
}

/*
 *	getexp() - get exponent part of floating number.
 *
 *	This algorithm is primitive but useful.
 *	We have to limit the exponent range somehow since 'endless'
 *	loops can occur if 1E123456789 is to be converted.
 *	The biggest exponent range I am aware of (CRAY Y-MP) is
 *	2^4096, say 10^1200, so I limit the exponent range to 1500.
 *	Is it better to flag an error or to generate +/- inf or
 *	zero here?
 *
 *	The reason we divide by exmul, and not multiply by 1/exmul is that
 *	0.1 can NOT be represented as an exact quantity in a binary base.
 *	Thus, when you increase sizeof(double), you get into trouble.
 */
static void getexp P0 (void)
{
#ifdef FLOAT_SUPPORT
#ifndef FLOAT_BOOTSTRAP
    RVAL    expo;
    RVAL    multiplier;
    int     flag = FALSE;

    expo = rval;
    multiplier = F_ten;
    switch (*bufcur) {
    case '-':
	flag = TRUE;
	/*lint -fallthrough */
    case '+':
	nextch ();
	break;
    default:
	break;
    }
#ifndef SYNTAX_CORRECT
    if (!is_digit (*bufcur)) {
	static CHAR temp[] = " ";

	temp[0] = *bufcur;
	message (ERR_PUNCT, temp);
    }
#endif /* SYNTAX_CORRECT */
    getdecimal ();
    if (ival < (IVAL) TARGET_LDBL_MAX_EXP) {
	while (ival-- != (UVAL) 0) {
	    if (flag) {
		expo /= multiplier;
	    } else {
		expo *= multiplier;
	    }
	}
#ifndef SYNTAX_CORRECT
    } else {
	message (ERR_CONSTFLOAT);
#endif /* SYNTAX_CORRECT */
    }
    rval = expo;
    lastst = tk_rconst;
#endif /* FLOAT_BOOTSTRAP */
#endif /* FLOAT_SUPPORT */
}

static void gethexexp P0 (void)
{
#ifdef FLOAT_SUPPORT
#ifndef FLOAT_BOOTSTRAP
    RVAL    expo;
    RVAL    multiplier;
    int     flag = FALSE;

    expo = rval;
    multiplier = F_two;
    switch (*bufcur) {
    case '-':
	flag = TRUE;
	/*lint -fallthrough */
    case '+':
	nextch ();
	break;
    default:
	break;
    }
#ifndef SYNTAX_CORRECT
    if (!is_hex (*bufcur)) {
	static CHAR temp[] = " ";

	temp[0] = *bufcur;
	message (ERR_PUNCT, temp);
    }
#endif /* SYNTAX_CORRECT */
    gethex ();
    if (ival < (UVAL) 1500) {
	while (ival-- != (UVAL) 0) {
	    if (flag) {
		expo /= multiplier;
	    } else {
		expo *= multiplier;
	    }
	}
#ifndef SYNTAX_CORRECT
    } else {
	message (ERR_CONSTFLOAT);
#endif /* SYNTAX_CORRECT */
    }
    rval = expo;
    lastst = tk_rconst;
#endif /* FLOAT_BOOTSTRAP */
#endif /* FLOAT_SUPPORT */
}


/*
 *	getnum() - get a number from input.
 *
 *	getnum handles all of the numeric input. it accepts decimal, octal,
 *	hexidecimal, and floating point numbers.
 */
static void getnum P0 (void)
{
    overflow = FALSE;
    lastst = tk_iconst;
    switch (*bufcur) {
    case '0':
	nextch ();
	switch (*bufcur) {
	case 'x':
	case 'X':
	    nextch ();
	    switch (*bufcur) {
	    case '.':
		if (lang_option >= LANG_C99) {
		    break;
		}
		/*lint -fallthrough */
	    default:
		gethex ();
		break;
	    }
	    if (lang_option >= LANG_C99) {
		switch (*bufcur) {
		case '.':
		    /* rval already set */
		    nextch ();
		    gethexfrac ();	/* add the fractional part */
		 /*lint -fallthrough*/ case 'p':
		case 'P':
		    switch (*bufcur) {
		    case 'p':
		    case 'P':
			nextch ();
			gethexexp ();	/* get the exponent */
			test_real ();
			break;
		    default:
#ifndef SYNTAX_CORRECT
			message (ERR_BINARYEXP);
#endif /* SYNTAX_CORRECT */
			break;
		    }
		    break;
		default:
		    test_int (H);
		    break;
		}
	    } else {
		test_int (H);
	    }
	    return;
	default:
	    getoctal ();
	    test_int (H);
	    return;
	case '.':
	case 'e':
	case 'E':
	    break;
	}
	/*lint -fallthrough */
    default:
	getdecimal ();
	switch (*bufcur) {
	case '.':
	    /* rval already set */
	    nextch ();
	    getfrac ();		/* add the fractional part */
	    /*lint -fallthrough */
	default:
	    switch (*bufcur) {
	    case 'e':
	    case 'E':
		nextch ();
		getexp ();	/* get the exponent */
		break;
	    default:
		break;
	    }
	    if (lastst == tk_rconst) {
		test_real ();
	    } else {
		/*
		 * look for l and u qualifiers
		 */
		test_int (0U);
	    }
	    break;
	}
    }
}

/*
 *	getsym() - get next symbol from input stream.
 *
 *	getsym is the basic lexical analyser.
 *	It builds basic tokens out of the characters on the input stream
 *	and sets the following global variables:
 *
 *	lastst: 		type of last symbol read.
 *	lastsym:		last identifier/string read.
 *	ival:			last integer constant read.
 *	rval:			last real constant read.
 *
 *	getsym should be called for all your input needs...
 */
void getsym P0 (void)
{
    register SIZE i;

    for (;;) {
      restart:
	symstart = bufcur;
	switch (*bufcur) {
	case '\n':
	    new_line ();
	    continue;
	case '\f':
	case '\r':
	case '\t':
	case '\v':
	case ' ':
	    bufcur++;
	    continue;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
	    getnum ();

⌨️ 快捷键说明

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