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

📄 cclex.c

📁 KCC , a good c compiler, write by Ken Harrenstien
💻 C
📖 第 1 页 / 共 2 页
字号:
	    else if (toupper(*cp++) == 'U')
		constant.ctype = ulongtype;
	    else
		c = -1;		/* Bad */
	    }
	else if (c == 'U')
	    {
	    if (!*++cp)
		constant.ctype = (ovfl) ? ulongtype : uinttype;
	    else if (toupper(*cp++) == 'L')
		constant.ctype = ulongtype;
	    else
		c = -1;		/* Bad */
	    }
	else if (c == 'F')
	    {
	    error("Invalid floating point constant");
	    constant.cvalue = v;
	    return token = T_FCONST;
	    }
	else
	    c = -1;			/* Bad */

	if (c < 0 || *cp)		/* Bad if flag set or anything left */
	    error("Bad integer constant suffix");
	}

    constant.cvalue = v;		/* Now set value */
    return token = T_ICONST;
}

/* TRFLTCON() - Transform floating-point PP-number constant
*/
static long maxdbl[2] = {MAXPOSLONG, MAXPOSLONG};
#define MAXPOSDOUBLE (*(double *)maxdbl)	/* Gross hack for now */

static int
trfltcon()
{
    register char *cp;
    register int c;
    INT exponent;
    double divisor, value = 0;		/* accumulated value */
    int expsign, ovfl = 0;

    /* Internal checks to verify token is correct */
    if ((cp = curval.cp) == 0 || (!isdigit(c = *cp) && c != '.'))
	{
	int_error("trfltcon: bad str");
	return dzerotok();
	}
	
    /* First do whole-number part.  We use floating arithmetic to avoid
    ** the real possibility of integer overflow.  Slower, but safer.
    */
    for (; isdigit(c); c = *++cp)
	{
	value = (value*10.0) + (c-'0');
	if (value && value < 1.0)	/* If exponent wrapped around, */
	    ovfl++;			/* we overflowed. */
	}

    /* Now do fractional part if one was specified */
    if (c == '.')
	{
	divisor = 1.0;		/* Place-value for post-. digits */
	while (isdigit(*++cp))
	    value += (*cp - '0') / (divisor *= 10.0);
	c = *cp;
	}
    
    /* Now exponent, if any */
    if (c == 'E' || c == 'e')
	{
	expsign = (c = *++cp);	/* Get possible exponent sign */
	if (c == '-' || c == '+')
	    c = *++cp;
	if (!isdigit(c))
	    {
	    error("Bad floating constant exponent");
	    return dzerotok();
	    }
	exponent = c - '0';
	while (isdigit(c = *++cp))
	    {
	    exponent = exponent*10 + (c-'0');
	    if (exponent >= ((MAXPOSLONG-9)/10))
		ovfl++, value = (expsign=='-' ? 0.0 : 1.0);
	    }

	/* EXTREMELY dumb method of scaling value by exponent */
	/* Fix this up later!! */
	if (!ovfl)
	    {
	    double pv;
	    if (expsign == '-')
		while (--exponent >= 0)
		    {
		    pv = value;			/* Remember val so can */
		    if ((value /= 10.0) > pv)	/* check for underflow */
			{
			ovfl++;
			value = 0;
			break;
			}
		    }
	    else
		while (--exponent >= 0)
		    {
		    pv = value;
		    if ((value *= 10.0) < pv)	/* Check for overflow */
			{
			ovfl++;
			value = 1.0;
			break;
			}
		    }
	    }
	}

    /* See whether we overflowed or not, and fix up. */
    if (ovfl)
	{
	if (value)
	    value = MAXPOSDOUBLE;
	error("Floating constant %sflow", (int) value ? "over" : "under");
	}

    /* Now check for suffix type specifier */
    if (c && toupper((char) c) == 'F')	// FW KCC-NT
	{
	constant.ctype = flttype;
	constant.Cfloat = (float) value;	// FW KCC-NT
	c = *++cp;
	}
    else if (c && toupper((char) c) == 'L') // FW KCC-NT
	{
	constant.ctype = lngdbltype;
	constant.Clngdbl = value;
	c = *++cp;
	}
    else if (c)
	{
	error("Bad floating constant suffix");
	return dzerotok();
	}
    else
	{
	constant.ctype = dbltype;	/* Set constant type to double */
	constant.Cdouble = value;	/* and set constant value */
	}
    return token = T_FCONST;
}

/* TRSTRCON() - Transform string constant
**	The only chars not allowed in a string constant are
**	newline, double-quote, and backslash.  They must be
**	entered as a character escape code.
**
**	If using ANSI parsing, two successive string constants are
**	merged into one!
*/

static
int
trstrcon (void)
    {
    char*	cp;
    int		wideflg, escval;


    if (savelits++ == 0)	/* Can char pool be reset? */
	slcreset();		/* Yes, do so */

    constant.ctype = strcontype;  /* Set constant type to string const */
    constant.csptr = slcbeg ();		/* Set constant string ptr */
			    
    /* Internal checks to verify token is correct */

    if ((cp = curval.cp) == 0)
	{
	int_error("trstrcon: no str");
	return szerotok ();
	}

    if ((wideflg = *cp) == 'L')
	++cp;	/* Get wchar_t indicator if any */

    if (*cp != '"')
	{
	int_error ("trstrcon: no \"");
	return szerotok ();
	}

    for ( ; ; )
	{
	switch (*++cp)
	    {
	    case '\\':			/* Escape char */
		slcput (escval = cchar (&cp));	/* Handle and map it */
		--cp;			/* Need to ensure ++ gets next */
		if (escval & ~tgcmask)	/* Did we truncate any bits? */
		    {
		    printf ("escval = %o, tgcmask = %o\n", escval, tgcmask);
		    error ("Escape-seq value too large for char");
		    }
		continue;

	    case '"':			/* End of string? */
		if (*++cp)
		    int_error("trstrcon: trailing junk");
		if (clevel < CLEV_ANSI)	/* Check for string concatenation? */
		    break;			/* Nope, just return what we got */

	    /* Hairy stuff... must look at next token! */
		for (;;)		/* Dumb loop to flush wsp */
		    {
		    switch (nextpp())
			{
			case T_WSP:
			case T_EOL:
			    continue;
			case T_SCONST:
			    if ((cp = curval.cp) != 0	/* Paranoia token check */
				&& (*cp == wideflg)	/* Wideness must match */
				&& (*cp == '"'		/* Paranoia format check */
				 || (*cp == 'L' && *++cp == '"')))
				break;	/* Hurray, resume main loop! */
				/* Everything's been set up... */
		    /* Can't concatenate next literal, drop thru */
			default:
			    pushpp();		/* Push current token back */
			    cp = NULL;		/* Say we're done */
			    break;		/* Quit loop and return */
			}
		    break;		/* Stop inner loop */
		    }
		if (cp)
		    continue;	/* Resume outer loop if concating */
		break;		/* else just leave switch */

	    case '\0':
		int_error("trstrcon: no delim");
		break;
	    default:
#if SYS_CSI	/* 5/91 KCC size */
		(void) slcput(*cp);
#else
		slcput(*cp);
#endif
		continue;

	    }
	break;			/* Break from main switch is break from loop */
	}

    /* OK, now finalize string literal in pool. */
#if 0	/* 5/91 Dynamic tables */
    {
	constant.cslen = slcend();	/* slcend() flags error in slcresize() */
	constant.csptr = (char *) ((ptrdiff_t) slcptr - constant.cslen);
	printf("%d:%s\t", (int) (constant.csptr), constant.csptr);
	}
#else
    if ((constant.cslen = slcend()) < 0)
	{
	error("Too many string literal chars, internal overflow");
	return szerotok();
	}
#endif
    return token = T_SCONST;
}

#if 0	/* 5/91 Dynamic tables */
static void
slcresize()
{
    ptrdiff_t offset = slcptr - slcpool;

    ++slcsize;
    slcpool = (char *) realloc (slcpool, slcsize * DYN_SIZE * sizeof(char));
    if (slcpool == NULL)
	jerr("Out of memory for string literal pool\n");
    slcleft += DYN_SIZE * sizeof(char);
    slcocnt += DYN_SIZE * sizeof(char);
    slcptr = (char *) ((ptrdiff_t) slcpool + offset);
    if (slcpool == NULL)
	error("Too many string literal chars, internal overflow");
}
#endif

static int
szerotok()
{
#if 0	/* 5/91 Dynamic tables */
    constant.csptr = 0;		/* Set constant string ptr */
#else
    constant.csptr = "";		/* Set constant string ptr */
#endif
    constant.cslen = 1;
    return token = T_SCONST;
}

/* TRCHRCON() - Transform character constant.
*/

static int
trchrcon (void)
{
    char *cp;
    int wideflg;
    unsigned long val;

    /* Internal checks to verify token is correct */
    if ((cp = curval.cp) == 0)
	{
	int_error("trchrcon: No str");
	return zerotok();
	}
    if ((wideflg = *cp) == 'L')
	++cp;	/* Get wchar_t indicator if any */
    if (*cp != '\'' || !*++cp || *cp == '\'')
	{
	int_error("trchrcon: Bad fmt");
	return zerotok();
	}

    val = 0;
    for (;;)
	{
	if (val & (-1<<(TGSIZ_INT-TGSIZ_CHAR)))
	    error("Character constant overflow");
	val <<= TGSIZ_CHAR;
	val |= cchar(&cp) & ((1<<TGSIZ_CHAR)-1);	/* Put into word */
	if (*cp == '\'')		/* Most common case, just one char */
	    break;
	if (!*cp)
	    {
	    int_error("trchrcon: Bad fmt");
	    return zerotok();
	    }
	}

    constant.ctype = (wideflg == 'L')
			? chartype	/* Wide char const is special type */
			: inttype;	/* Normal char const is type int */

    constant.cvalue = val;
    return T_CCONST;
}

/* CCHAR(&cp) - parse a character from a string literal, char constant,
**	or quoted identifier.
**	Handles escape sequences, and converts values into target char set.
**	Input starts at 1st char of pointer, leaves pointer at first char
**	not translated into resulting value.
*/

static
int
cchar (char **acp)
    {
    char*	cp = *acp;
    int		c = *cp;


    if (c == '\\')
	{
	switch (*++cp)	/* If escape char, handle it */
	    {
	    case 'a':
		c = 07;
		break;	/* ANSI alert - map into BEL */

	    case 'b':
		c = '\b';
		break;

	    case 'f':
		c = '\f';
		break;

	    case 'n':
		c = '\n';
		break;

	    case 'r':
		c = '\r';
		break;

	    case 't':
		c = '\t';
		break;

	    case 'v':
		c = '\v';
		break;

	    case '\'':
		c = '\'';
		break;

	    case '"':
		c = '\"';
		break;

	    case '\\':
		c = '\\';
		break;

	    case '?':
		c = '?';
		break;	/* To avoid trigraphs */

	    case 'x':	/* Hexadecimal escape sequence */

		if (isxdigit(*++cp))
		    {
		    int		ovfl = 0;


		    c = toint (*cp);

		    while (isxdigit (*++cp))
			{
			if (c & (017 << (TGSIZ_INT - 4)))
			    ovfl++;

			c = ((unsigned) c << 4) + toint (*cp);
			}

		    if (ovfl)
			error ("Hex constant overflow");
		    }
		else
		    error ("Need hex digit after \\x");

		*acp = cp;
		return c;		/* Specific hex value */

	    case '0':
	    case '1':
	    case '2':
	    case '3':		/* octal escape */
	    case '4':
	    case '5':
	    case '6':
	    case '7':
		c = *cp - '0';

		if (isodigit (*++cp))
		    {
		    c = ((unsigned) c << 3) + *cp - '0';

		    if (isodigit (*++cp))
			{
			c = ((unsigned) c << 3) + *cp - '0';
			++cp;
			}
		    }

		*acp = cp;

		if (c > 255)
		    {
		    if (!clevkcc)
			error ("Char const exceeds 8 bits");
		    else
			warn ("Non-portable: char const exceeds 8 bits");
		    }

		return c;		/* Specific octal value */

	    case '`':
		if (clevkcc)
		    {
		    c = '`';
		    break;
		    }

		/* Else not doing KCC extensions, drop through to complain. */

	    default:
		error ("Unknown escape char (ignoring backslash): '\\%c'",*cp);
	    }
	}

    *acp = ++cp;
    return c;
    }

⌨️ 快捷键说明

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