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

📄 getsym.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 3 页
字号:
            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 + -