cscan.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,752 行 · 第 1/4 页

C
1,752
字号
    BadTokenInfo = 0;
    TokenLen = 0;
    do {
        Buffer[TokenLen++] = CurrChar;
        doScanAsmToken();
    } while( CurrChar == '.' );
    CurToken = T_ID;
    return( CurToken );
}

int ScanDot( void )
{
    if( CompFlags.inside_asm_stmt == 1 )
        return( doScanAsm() );

    Buffer[0] = '.';
    TokenLen = 1;
    return( doScanFloat() );
}

static int ScanPPNumber( void )
{
    int         c;
    int         prevc;
    // 3.1.8 pp-number
    // pp-number:
    //          digit           (checked by caller)
    //          . digit         (checked by caller)
    //          pp-number digit
    //          pp-number non-digit
    //          pp-number e sign
    //          pp-number E sign
    //          pp-number .
    //
    c = 0;
    for( ;; ) {
        prevc = c;
        c = SaveNextChar();
        if( CharSet[c] & (C_AL | C_DI) ) continue;
        if( c == '.' ) continue;
        if( c == '+' || c == '-' ) {
            if( prevc == 'e' || prevc == 'E' ) {
                if( CompFlags.extensions_enabled ) {
                    /* concession to existing practice...
                        #define A2 0x02
                        #define A3 0xaa0e+A2
                        // users want: 0xaa0e + 0x02
                        // not: 0xaa0e + A2 (but, this is what ISO C requires!)
                    */
                    prevc = c;  //advance to next
                    c = SaveNextChar();
                    if( !(CharSet[c] &  C_DI) ) break;  //allow e+<digit>
                }
                continue;
            }
        }
        break;
    }
    --TokenLen;
    Buffer[TokenLen] = '\0';
    return( T_PPNUMBER );
}

int ScanPPDigit( void )
{
    Buffer[0] = CurrChar;
    TokenLen = 1;
    return( ScanPPNumber() );
}

int ScanPPDot( void )
{
    int         c;

    Buffer[0] = '.';
    TokenLen = 1;
    c = SaveNextChar();
    if( c >= '0' && c <= '9' ) {
        return( ScanPPNumber() );
    } else {
        return( ScanDotSomething( c ) );
    }
}

int ScanHex( int max, const char **pbuf )
{
    int                 c;
    int                 count;
    unsigned char       chrclass;
    char                too_big;
    unsigned long       value;

    too_big = 0;
    count = max;
    value = 0;
    for( ;; ) {
        if( pbuf == NULL ) {
            c = SaveNextChar();
        } else {
            c = *++*pbuf;
        }
        if( max == 0 ) break;
        chrclass = CharSet[ c ];
        if( ( chrclass & (C_HX|C_DI) ) == 0 ) break;
        if( chrclass & C_HX )  c = (( c | HEX_MASK ) - HEX_BASE ) + 10 + '0';
        if( value & 0xF0000000 )  too_big = 1;          /* 26-mar-91 */
        value = value * 16 + c - '0';
        --max;
    }
    Constant = value;
    if( count == max ) {                /* no characters matched */
        return( 0 );            /* indicate no characters matched */
/*          CErr1( ERR_INVALID_HEX_CONSTANT );  */
    }
    if( too_big ) {                                     /* 26-mar-91 */
        BadTokenInfo = ERR_CONSTANT_TOO_BIG;
        if( NestLevel == SkipLevel ) {  /* 10-sep-92 */
            CWarn1( WARN_CONSTANT_TOO_BIG, ERR_CONSTANT_TOO_BIG );
        }
    }
    return( 1 );                        /* indicate characters were matched */
}

typedef enum { CNV_32, CNV_64, CNV_OVR } cnv_cc;

static cnv_cc Cnv8( void )
{
    char    *curr;
    char    c;
    int     len;
    long    value;
    uint64  value64;
    cnv_cc  ret;

    curr = Buffer;
    len = TokenLen;
    value = 0;
    while( --len > 0 ) {
        c = *curr;
        if( value & 0xE0000000 ) goto is64; /* 64 bit */
        value = value * 8 + c - '0';
        ++curr;
    }
    Constant = value;
    return( CNV_32 );
is64:
    ret = CNV_64;
    U32ToU64( value, &value64 );
    do{
        c = *curr;
        if( U64Cnv8( &value64, c-'0' ) ) {
            ret = CNV_OVR;
        }
        ++curr;
    } while( --len > 0 );
    Const64 = value64;
    return( ret );
}

static cnv_cc Cnv16( void )
{
    unsigned char   *curr;
    unsigned char   c;
    int             len;
    unsigned long   value;
    uint64          value64;
    cnv_cc          ret;

    curr = Buffer + 2;      // skip 0x thing
    len = TokenLen - 2;
    value = 0;
    while( --len > 0 ) {
        c = *curr;
        if( value & 0xF0000000 ) goto is64; /* 64 bit */
        if( CharSet[ c ] & C_HX ) {
            c = (( c | HEX_MASK ) - HEX_BASE ) + 10 + '0';
        }
        value = value * 16 + c - '0';
        ++curr;
    }
    Constant = value;
    return( CNV_32 );
is64:
    ret = CNV_64;
    U32ToU64( value, &value64 );
    do {
        c = *curr;
        if( CharSet[ c ] & C_HX ) {
            c = (( c | HEX_MASK ) - HEX_BASE ) + 10 + '0';
        }
        if( U64Cnv16( &value64, c-'0' ) ) {
            ret = CNV_OVR;
        }
        ++curr;
    } while( --len > 0 );
    Const64 = value64;
    return( ret );
}

static cnv_cc Cnv10( void )
{
    char            *curr;
    char            c;
    int             len;
    unsigned long   value;
    uint64          value64;
    cnv_cc          ret;

    curr = Buffer;      // skip 0x thing
    len = TokenLen;
    value = 0;
    while( --len > 0 ) {
        c = *curr;
        if( value >= 429496729 ) {          /* 15-feb-93 */
            if( value == 429496729 ) {
                if( c > '5' )  goto is64;
            } else {
                goto is64;
            }
        }
        value = value * 10 + c - '0';
        ++curr;
    }
    Constant = value;
    return( CNV_32 );
is64:
    ret = CNV_64;
    U32ToU64( value, &value64 );
    do {
        c = *curr;
        if( U64Cnv10( &value64, c-'0') ) {
            ret = CNV_OVR;
        }
        ++curr;
    } while( --len > 0 );
    Const64 = value64;
    return( ret );
}

static int ScanNum( void )
{
    int                 c;
    int                 bad_token_type;
    cnv_cc              ov;

    struct {
        enum { CON_DEC, CON_HEX, CON_OCT, CON_ERR } form;
        enum { SUFF_NONE,SUFF_U, SUFF_L,SUFF_UL,  SUFF_I, SUFF_UI,
               SUFF_LL,SUFF_ULL } suffix;
    } con;

    if( CompFlags.inside_asm_stmt == 1 )
        return( doScanAsm() );

    BadTokenInfo = 0;
    ov = CNV_32;
    Constant = 0;
    TokenLen = 1;
    c = CurrChar;
    Buffer[0] = c;
    if( c == '0' ) {
        c = SaveNextChar();
        if( c == 'x'  ||  c == 'X' ) {
            unsigned char       chrclass;

            bad_token_type = ERR_INVALID_HEX_CONSTANT;
            con.form = CON_HEX;
            for( ;; ) {
                c = SaveNextChar();
                chrclass = CharSet[ c ];
                if( ( chrclass & (C_HX|C_DI) ) == 0 ) break;
            }
            if( TokenLen == 3 ) {   /* just collected a 0x */
                BadTokenInfo = ERR_INVALID_HEX_CONSTANT;
                if( NestLevel == SkipLevel ) {
                    CErr1( ERR_INVALID_HEX_CONSTANT );
                    con.form = CON_ERR;
                }
            }
        } else {    /* scan octal number */
            unsigned char   digit_mask;

            bad_token_type = ERR_INVALID_OCTAL_CONSTANT;
            con.form = CON_OCT;
            digit_mask = 0;
            // if collecting tokens for macro preprocessor, allow 8 and 9
            // since the argument may be used in with # or ##. 28-oct-92
            while( c >= '0'  &&  c <= '9' ) {
                digit_mask |= c;
                c = SaveNextChar();
            }
            if( c == '.' || c == 'e' || c == 'E' ) {
                return( doScanFloat() );
            }
            if( digit_mask & 0x08 ) {   /* if digit 8 or 9 somewhere */
                BadTokenInfo = ERR_INVALID_OCTAL_CONSTANT;
                con.form = CON_ERR;
                if( NestLevel == SkipLevel ) {
                    CErr1( ERR_INVALID_OCTAL_CONSTANT );
                }
            }
        }
    } else {    /* scan decimal number */
        bad_token_type = ERR_INVALID_CONSTANT;
        con.form = CON_DEC;
        do {
            c = SaveNextChar();
        } while( c >= '0'  &&  c <= '9' );
        if( c == '.' || c == 'e' || c == 'E' ) {
            return( doScanFloat() );
        }
    }
    switch( con.form ) {
    case CON_OCT:
        ov = Cnv8();
        break;
    case CON_HEX:
        ov = Cnv16();
        break;
    case CON_DEC:
        ov = Cnv10();
        break;
    case CON_ERR:
        ov = CNV_32;
    }
    con.suffix = SUFF_NONE;
    if( c == 'l'  ||  c == 'L' ) {   // collect suffix
        c = SaveNextChar();
        if( c == 'u' || c == 'U' ) {
            c = SaveNextChar();
            con.suffix = SUFF_UL;
        } else if( c == 'l' || c == 'L' ) {
            c = SaveNextChar();
            if( c == 'u' || c == 'U' ) {
                c = SaveNextChar();
                con.suffix = SUFF_ULL;
            } else {
                con.suffix = SUFF_LL;
            }
        } else {
            con.suffix = SUFF_L;
        }
    } else if( c == 'u' || c == 'U' ) {
        c = SaveNextChar();
        if( c == 'l' || c == 'L' ) {
            c = SaveNextChar();
            if( c == 'l' || c == 'L' ) {
                c = SaveNextChar();
                con.suffix = SUFF_ULL;
            } else {
                con.suffix = SUFF_UL;
            }
        } else if( c == 'i' || c == 'I' ) {
            c = SaveNextChar();
            con.suffix = SUFF_UI;
        } else {
            con.suffix = SUFF_U;
        }
    } else if( c == 'i' || c == 'I' ) {
        c = SaveNextChar();
        con.suffix = SUFF_I;
    }
    if( con.suffix == SUFF_UI || con.suffix == SUFF_I ) {
        unsigned_32 value;

        value  = 0;
        while( c >= '0'  &&  c <= '9' ) {
            value = value * 10 + c - '0';
            c = SaveNextChar();
        }
        if( value == 64 ) {
            if( con.suffix == SUFF_I ) {
                ConstType = TYPE_LONG64;
            } else {
                ConstType = TYPE_ULONG64;
            }
            if( ov == CNV_32 ) {
                U32ToU64( Constant, &Const64 );
            }
        } else if( value == 32 ) {
            if( con.suffix == SUFF_I ) {
                ConstType = TYPE_LONG;
            } else {
                ConstType = TYPE_ULONG;
            }
        } else if( value == 16 ) {
            if( con.suffix == SUFF_I ) {
                ConstType = TYPE_SHORT;
            } else {
                ConstType = TYPE_USHORT;
            }
        } else if( value == 8 ) {
            if( con.suffix == SUFF_I ) {
                ConstType = TYPE_CHAR;
            } else {
                ConstType = TYPE_UCHAR;
            }
        } else {
            if( NestLevel == SkipLevel ) {
                CErr1( ERR_INVALID_CONSTANT );
            }
        }
        if( ov == CNV_64 && value < 64 ) {
            BadTokenInfo = ERR_CONSTANT_TOO_BIG;
            if( NestLevel == SkipLevel ) {      /* 10-sep-92 */
                CWarn1( WARN_CONSTANT_TOO_BIG, ERR_CONSTANT_TOO_BIG );
            }
            Constant =  Const64.u._32[I64LO32];
        }
    } else if( ov == CNV_32 && con.suffix != SUFF_LL && con.suffix != SUFF_ULL ) {
        switch( con.suffix ) {
        case SUFF_NONE:
            if( Constant <= TARGET_INT_MAX ) {
                ConstType = TYPE_INT;
#if TARGET_INT < TARGET_LONG
            } else if( Constant <= TARGET_UINT_MAX && con.form != CON_DEC ) {
                ConstType = TYPE_UINT;
            } else if( Constant <= 0x7ffffffful ) {
                ConstType = TYPE_LONG;
            } else {
                ConstType = TYPE_ULONG;
            }
#else
            } else if( con.form != CON_DEC ) {
                ConstType = TYPE_UINT;
            } else {
                ConstType = TYPE_ULONG;
            }
#endif
            break;
        case SUFF_L:
            if( Constant <= 0x7FFFFFFFul ) {     /* 13-sep-89 */
                ConstType = TYPE_LONG;
            } else {
                ConstType = TYPE_ULONG;
            }
            break;
        case SUFF_U:

⌨️ 快捷键说明

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