scan.c

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

C
530
字号
                if( ++Column >= LastColumn ) { // we've just processed column 72
                    *Cursor = NULLCHAR;
                }
                State = SOP;
                class = TO_OPR;
                goto token;
            case SFL :
                if( old_state == SNS ) {
                    // Consider: i .eq. j
                    LkUpLog();
                    if( LexToken.log != BAD_LOG ) {
                        // if it's a valid logical operator,
                        // set final state to SFL
                        State = state2;
                    } else if( dpt == NULL ) {
                        dpt = LexToken.start;
                    }
                } else {
                    // Consider: 1 .eq. 2
                    State = state2;
                }
                goto token;
            case SHL :
                if( LexToken.flags & TK_LENSPEC ) {
                    LexToken.flags &= ~TK_LENSPEC;
                    goto token;
                }
                *TkCrsr = NULLCHAR;
                len = atoi( LexToken.start );
                LexToken.start = TkCrsr;
                State = SIH;
                class = TO_LIT;
                StmtSw |= SS_HOLLERITH;
                break;
            case SIH :
                if( TkCrsr - LexToken.start >= len ) {
                    TkCrsr = LexToken.start + len; // in case of TABCHAR
                    State = SSO;
                    goto token;
                }
                if( ch_class == C_TC ) {
                    tab = 8 - Column % 8;
                    // Column gets incremented normally at bottom of loop
                    Column += tab - 1;
                    memset( TkCrsr, ' ', tab );
                    TkCrsr += tab;
                } else {
                    *TkCrsr = ch;
                    TkCrsr++;
                }
                break;
            case SSP :
                if( State == SNS ) {
                    LexToken.col = Column;
                }
                break;
            case STC :
                // Column gets incremented normally at bottom of loop
                Column += 7 - Column % 8;
                break;
            case SBC :
                Error( CC_BAD_CHAR );
                break;
            case SCM :
                if( !(ExtnSw & XS_EOL_COMMENT) ) {
                    Extension( CC_EOL_COMMENT );
                    ExtnSw |= XS_EOL_COMMENT;
                }
            case SNR :
                if( LexToken.flags & TK_INCLUDE ) {
                    LexToken.flags |= TK_LAST;
                    goto token;
                }
                // 0..71 is the statement area
                // 72..79 is the sequence area
                // calculate the number of spaces
                // that we may require for filling
                tab = LastColumn - Column;
                ComRead();
                if( StmtType != STMT_CONT ) {
                    LexToken.flags |= TK_LAST;
                    goto token;
                }
                if( ( State == SIQ ) || ( State == SIH ) || ( State == SFM ) ) {
                    memset( TkCrsr, ' ', tab );
                    TkCrsr += tab;
                }
                ++Line;
                ComPrint();
                ScanNum();
                if( Line >= 20 ) {
                    if( !(ExtnSw & XS_CONT_20) ) {
                        Extension( CC_TOO_MANY_CONT );
                        ExtnSw |= XS_CONT_20;
                    }
                    if( (TkCrsr-TokenBuff) + (LastColumn-CONT_COL) > TOKLEN ) {
                        TkCrsr = TokenBuff; // so we don't overflow TokenBuff
                        if( !(StmtSw & SS_CONT_ERROR_ISSUED) ) {
                            Error( CC_CONT_OVERFLOW );
                            StmtSw |= SS_CONT_ERROR_ISSUED;
                        }
                    }
                }
                if( State == SNS ) {
                    LexToken.col = Column;
                }
                Column--; // to offset ++Cursor and ++Column in code
                Cursor--; // after } (must be after ScanNum
                break;    // and Error since Error uses Column)
            }
            // 0..71 is the statement area
            // 72..79 is the sequence area
            ++Cursor;
            if( ++Column >= LastColumn ) { // we've just processed column 72
                *Cursor = NULLCHAR;
            }
        }
token:  LexToken.stop  = TkCrsr;
        state2 = State;                // final state for Scan
        State = SNS;                   // set to no state for next time
        switch( state2 ) {
        case SAN :
            class = TO_NAM;
            break;
        case SNM :
            class = TO_INT;
            break;
        case SFT :
            class = TokenREA;
            break;
        case SOL :
            class = TO_OCT;
            break;
        case SHX :
            class = TO_HEX;
            break;
        case SCS :
        case SAP :
            class = TO_LIT;
            break;
        case SFL :
            if( old_state == SNS ) {
                LexToken.start++;              // skip over starting dot
                // 0..71 is the statement area
                // 72..79 is the sequence area
                ++Cursor;
                if( ++Column >= LastColumn ) { // just processed column 72
                    *Cursor = NULLCHAR;
                }
                class = TO_LGL;
            } else {
                State = SLG;               // remember logical collected
                LexToken.stop = dpt;          // decimal not part of token
                class = TO_INT;
            }
            break;
        case SML :
            if( ( old_state == SNS ) || ( old_state == SSG ) ) {
                class = TO_OPR;
            } else {
                class = TokenREA;
            }
            break;
        case SLX :
        case SLG :
            LexToken.stop = dpt + sizeof( char ); // decimal is part of token
            State = SAN;                       // remember alphanumeric started
            if( old_state == SNS ) {
                class = TO_OPR;
            } else {
                class = TokenREA;
            }
            break;
        case SNS :
            LexToken.flags |= TK_EOL;
        case SLL :
            class = TO_OPR;
            break;
        case SIH :
            // We get here if and only if we are in a hollerith constant
            // and we've reached the end of the line (next line is not a
            // continuation line) and the length of the hollerith constant
            // has not been met.
            // "tab" is how may characters left until column 72
            hlen = TkCrsr - LexToken.start;        // get how many chars so far
            if( tab + hlen < len ) {            // if not enough characters
                Warning( HO_CUT_OFF );          // - say the hollerith cut off
                len = tab + hlen;               // - set length up to col 72
            }                                   // }
            memset( TkCrsr, ' ', len - hlen );  // fill rest of hollerith
            TkCrsr = LexToken.start + len;         // set new collection location
            break;
        case SFM :
            class = TO_FMT;
            break;
        case SIQ :
            Error( SX_QUOTE );
            class = TO_LIT;
            break;
        }
        LexToken.class = class;
        if( !(ExtnSw & XS_CHAR_EXTN) && ( class != TO_LIT ) &&
            ( class != TO_FMT ) && ( wasextch & C_EXT ) ) {
            Extension( CC_SET_EXTEND );
            ExtnSw |= XS_CHAR_EXTN;
        }
    } else {
        if( State == SAN ) {
            // Consider:   ... SYM.FIELD
            // ".FIELD" would have been scanned in anticipation of a logical
            // constant or operator but we reached the end of the statement
            // so that last token is "FIELD".
            LexToken.start = LexToken.stop;
            LexToken.stop = TkCrsr;
            LexToken.class = TO_NAM;
        } else {
            LexToken.class = TO_OPR;
        }
        LexToken.flags |= TK_EOL;
    }
}


static  void    ScanNum( void ) {
//=========================

    if( StmtType != STMT_CONT ) {
        StmtNo = NextStmtNo;
        if( StmtNo == 0 ) {
            if( StmtNoFound ) {
                Error( ST_NUM_ZERO );
            }
        }
    } else {
        if( StmtNoFound ) {
            Error( CC_STMTNO_ON_CONT );
        }
        if( ( ContType == C_BC ) || ( ContType & C_EXT ) ) {
            // non-FORTRAN char or WATFOR-77 extension
            // but issue message only once
            if( !(ExtnSw & XS_CHAR_EXTN) ) {
                Extension( CC_SET_EXTEND );
                ExtnSw |= XS_CHAR_EXTN;
            }
        }
    }
}


static  void    LkUpLog( void ) {
//=========================

    int         index;
    char        *ptr;

    index = 0;
    ptr = LexToken.start + sizeof( char ); // skip over "."
    *TkCrsr = NULLCHAR;
    for(;;) {
        if( strcmp( LogTab[ index ], ptr ) == 0 ) break;
        if( LogTab[ ++index ] == NULL ) break;
    }
    LexToken.log = index;
}

⌨️ 快捷键说明

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