📄 cclex.c
字号:
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 + -