📄 getsym.c
字号:
ival = getsch(2);
lastst = iconst;
while (lastch != '\'' && lastch != '\n')
getsch(2);
if (lastch != '\'')
generror(ERR_NEEDCHAR, '\'', 0);
else
getch();
return ;
}
}
while (issymchar(lastch))
{
if (i < 100)
lastid[i++] = lastch;
getch();
}
if ((lastid[i - 1] &0xf0) == 0x90)
lastid[i - 1] = 0x90;
lastid[i] = '\0';
lastst = id;
}
/*
* getsch - get a character in a quoted string.
*
* this routine handles all of the escape mechanisms
* for characters in strings and character constants.
*/
int getsch(int bytes) /* return an in-quote character */
{
register int i, j;
if (lastch == '\n')
return INT_MIN;
if (incconst || lastch != '\\')
{
i = lastch;
getch();
return i;
}
getch(); /* get an escaped character */
if (isdigit(lastch) && lastch < '8')
{
for (i = 0, j = 0; j < 3; ++j)
{
if (lastch <= '7' && lastch >= '0')
i = (i << 3) + lastch - '0';
else
break;
getch();
}
return i;
}
i = lastch;
getch();
switch (i)
{
case '\n':
getch();
return getsch(bytes);
case 'a':
return '\a';
case 'b':
return '\b';
case 'f':
return '\f';
case 'n':
return '\n';
case 'r':
return '\r';
case 'v':
return '\v';
case 't':
return '\t';
case '\'':
return '\'';
case '\"':
return '\"';
case '\\':
return '\\';
case '?':
return '?';
case 'x':
{
int n = 0, count = 0;
while (isxdigit(lastch))
{
count++;
if (lastch >= 0x60)
lastch &= 0xdf;
lastch -= 0x30;
if (lastch > 10)
lastch -= 7;
if (lastch > 15)
lastch -= 32;
n *= 16;
n += lastch;
getch();
}
if (count > bytes *2)
generror(ERR_CONSTTOOLARGE, 0, 0);
if (count == 2 && n > UCHAR_MAX)
n = (int)(char)n;
return n;
}
default:
return i;
}
}
//-------------------------------------------------------------------------
int radix36(char c)
{
if (isdigit(c))
return c - '0';
if (c >= 'a' && c <= 'z')
return c - 'a' + 10;
if (c >= 'A' && c <= 'Z')
return c - 'A' + 10;
return INT_MAX;
}
/*
* getbase - get an integer in any base.
*/
void getbase(int b, char **ptr)
{
LLONG_TYPE i;
int j;
int errd = 0;
i = 0;
while ((j = radix36(**ptr)) < b)
{
(*ptr)++;
if (i > (llminus1 - j) / b)
if (!errd)
{
generror(ERR_CONSTTOOLARGE, 0, 0);
errd++;
}
i = i * b + j;
}
ival = i;
lastst = iconst;
}
/*
* getfrac - get fraction part of a floating number.
*/
void getfrac(int radix, char **ptr)
{
long double frmul;
frmul = 1.0 / radix;
while (radix36(**ptr) < radix)
{
rval += frmul * radix36(*(*ptr)++);
frmul /= radix;
}
lastst = rconst;
}
/*
* getexp - get exponent part of floating number.
*
* this algorithm is primative but usefull. Floating
* exponents are limited to +/-255 but most hardware
* won't support more anyway.
*/
void getexp(int radix, char **ptr)
{
int neg = FALSE;
if (**ptr == '-')
{
neg = TRUE;
(*ptr)++;
}
else
{
if (**ptr == '+')
(*ptr)++;
}
getbase(10, ptr);
#if sizeof(LLONG_TYPE) == 4
if (ival > LDBL_MAX_10_EXP)
{
generror(ERR_FPCON, 0, 0);
ival = 0;
};
#endif
if (neg)
ival = - ival;
#if sizeof(LLONG_TYPE) == 4
if (radix == 10)
rval *= pow10l(ival);
else
{
if (rval == 1 && ival == 128 && lastch == 'F') { // This is an escape to bootstrap
// the floating point support with
// another compiler
rval = *(float *)&floating_infinity;
} else
rval *= powl(2.0, (long double)ival);
}
#endif
lastst = rconst;
}
/*
* getnum - get a number from input.
*
* getnum handles all of the numeric input. it accepts
* decimal, octal, hexidecimal, and floating point numbers.
*/
void getnum(void)
{
char buf[200], *ptr = buf;
int hasdot = FALSE;
int radix = 10;
int floatradix = 0;
if (lastch == '0')
{
getch();
if (lastch == 'x' || lastch == 'X')
{
getch();
radix = 16;
}
else
radix = 8;
}
while (radix36(lastch) < radix)
{
*ptr++ = lastch;
getch();
}
if (lastch == '.')
{
if (radix == 8)
radix = 10;
*ptr++ = lastch;
getch();
while (radix36(lastch) < radix)
{
*ptr++ = lastch;
getch();
}
}
if ((lastch == 'e' || lastch == 'E') && radix != 16)
radix = floatradix = 10;
else if ((lastch == 'p' || lastch == 'P') && radix == 16)
{
floatradix = 2;
}
if (floatradix)
{
*ptr++ = lastch;
getch();
if (lastch == '-' || lastch == '+')
{
*ptr++ = lastch;
getch();
}
while (radix36(lastch) < 10)
{
*ptr++ = lastch;
getch();
}
}
*ptr = 0;
ptr = buf;
// at this point the next char is any qualifier after the number
if (radix36(*ptr) < radix)
getbase(radix, &ptr);
else
{
ival = 0;
lastst = iconst;
}
if (*ptr == '.')
{
ptr++;
rval = ival;
ival = 0;
getfrac(radix, &ptr);
ival = 0;
}
if (*ptr == 'e' || *ptr == 'E' || *ptr == 'p' || *ptr == 'P')
{
if (lastst != rconst)
{
rval = ival;
}
ptr++;
getexp(floatradix, &ptr);
}
if (lastst != rconst)
{
if (lastch == 'i')
{
if (!prm_ansi && *lptr == '6' && *(lptr + 1) == '4')
{
getch();
getch();
getch();
lastst = llconst;
}
}
else if (lastch == 'U' || lastch == 'u')
{
getch();
if (lastch == 'L' || lastch == 'l')
{
getch();
if (prm_c99 && (lastch == 'L' || lastch == 'l'))
{
lastst = lluconst;
getch();
}
else
{
if (prm_c99 && ival > ULONG_MAX)
lastst = lluconst;
else
lastst = luconst;
}
}
else
{
if (prm_c99 && ival > ULONG_MAX)
lastst = lluconst;
else
lastst = iuconst;
}
}
else if (lastch == 'L' || lastch == 'l')
{
getch();
if (prm_c99 && (lastch == 'L' || lastch == 'l'))
{
getch();
if (lastch == 'U' || lastch == 'u')
{
getch();
lastst = lluconst;
}
else
lastst = llconst;
}
else if (lastch == 'U' || lastch == 'u')
{
if (prm_c99 && ival > ULONG_MAX)
lastst = lluconst;
else
lastst = luconst;
getch();
}
else
{
if (prm_c99 && (ival > LONG_MAX || ival < LONG_MIN))
lastst = llconst;
else
lastst = lconst;
}
}
else
{
if (prm_c99 && (ival > LONG_MAX || ival < LONG_MIN))
lastst = llconst;
else
lastst = iconst;
}
}
else
{
if (lastch == 'F' || lastch == 'f')
{
lastst = fconst;
getch();
#if sizeof(LLONG_TYPE) == 8
if (floatradix == 2)
{
if (ival == FLT_MAX_EXP)
*(((short *)&rval) + LDBL_SHIFTWORDS) |= LDBL_INFNAN;
else if (ival < FLT_MAX_EXP && ival >= FLT_MIN_EXP)
rval = scalbnf(rval,ival);
else
generror(ERR_FPCON,0,0);
}
else
{
if (ival <= FLT_MAX_10_EXP && ival >= FLT_MIN_10_EXP)
{
rval *= pow10f(ival);
if (rval == INFINITY)
generror(ERR_FPCON,0,0);
}
else
generror(ERR_FPCON,0,0);
}
if (!isinf(rval) && !isnan(rval))
if (rval > FLT_MAX)
{
generror(ERR_FPCON,0,0);
rval = FLT_MAX;
}
else if (rval < - FLT_MAX)
{
generror(ERR_FPCON,0,0);
rval = -FLT_MAX;
}
#endif
}
else if (lastch == 'L' || lastch == 'l')
{
lastst = lrconst;
getch();
#if sizeof(LLONG_TYPE) == 8
if (floatradix == 2)
{
if (ival == LDBL_MAX_EXP)
*(((short *)&rval) + LDBL_SHIFTWORDS) |= LDBL_INFNAN;
else if (ival < LDBL_MAX_EXP && ival >= LDBL_MIN_EXP)
rval = scalbnl(rval,ival);
else
generror(ERR_FPCON,0,0);
}
else
{
if (ival <= LDBL_MAX_10_EXP && ival >= LDBL_MIN_10_EXP)
{
rval *= pow10l(ival);
if (rval == INFINITY)
generror(ERR_FPCON,0,0);
}
else
generror(ERR_FPCON,0,0);
}
#endif
} else
{
#if sizeof(LLONG_TYPE) == 8
if (floatradix == 2)
{
if (ival == DBL_MAX_EXP)
*(((short *)&rval) + LDBL_SHIFTWORDS) |= LDBL_INFNAN;
else if (ival < DBL_MAX_EXP && ival >= DBL_MIN_EXP)
rval = scalbn(rval,ival);
else
generror(ERR_FPCON,0,0);
}
else
{
if (ival <= DBL_MAX_10_EXP && ival >= DBL_MIN_10_EXP)
{
rval *= pow10(ival);
if (rval == INFINITY)
generror(ERR_FPCON,0,0);
}
else
generror(ERR_FPCON,0,0);
}
if (!isinf(rval) && !isnan(rval))
if (rval > DBL_MAX)
{
generror(ERR_FPCON,0,0);
rval = DBL_MAX;
}
else if (rval < - DBL_MAX)
{
generror(ERR_FPCON,0,0);
rval = -DBL_MAX;
}
#endif
}
}
if (isstartchar(lastch) || isdigit(lastch))
{
generror(ERR_INVCONST, 0, 0);
while ((isstartchar(lastch) || isdigit(lastch)) && lastch != eof)
getch();
}
}
//-------------------------------------------------------------------------
int getsym2(void)
/*
* translate character sequences to appropriate token names
*/
{
register int i, j, k;
int size;
swlp: switch (lastch)
{
case '+':
getch();
if (lastch == '+')
{
getch();
lastst = autoinc;
}
else if (lastch == '=')
{
getch();
lastst = asplus;
}
else
lastst = plus;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -