scan.c

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

C
530
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Scanner
*
****************************************************************************/


#include "ftnstd.h"
#include "errcod.h"
#include "extnsw.h"
#include "stmtsw.h"
#include "global.h"
#include "csetinfo.h"
#include "cpopt.h"
#include "ferror.h"
#include "comio.h"

#include <string.h>
#include <stdlib.h>

extern  character_set   CharSetInfo;

#define COLUMNS 17

static  const token_state __FAR StateTable[][COLUMNS] = {

// AL  EX  SG  DP  DI  HL  AP  OP  SP  TC  BC  EL  CM  OL  HX  CS  DB
  SAN,SAN,SSG,SLL,SNM,SAN,SFQ,SOP,SSP,STC,SBC,SNR,SCM,SAN,SAN,SAN,SDB, // NS
  SSO,SEX,SSO,SML,SNM,SHL,SSO,SSO,SSP,STC,SBC,SNR,SCM,SSO,SSO,SSO,SSO, // NM
  SAN,SAN,SSO,SSO,SAN,SAN,SSO,SSO,SSP,STC,SBC,SNR,SCM,SAN,SAN,SAN,SDB, // AN
  SSO,SSO,SSO,SML,SNM,SSO,SSO,SSO,SSP,STC,SBC,SNR,SCM,SSO,SSO,SSO,SSO, // SG
  SSO,SEX,SSO,SSO,SFT,SSO,SSO,SSO,SSP,STC,SBC,SNR,SCM,SSO,SSO,SSO,SSO, // FT
  SLG,SLG,SEN,SSO,SEN,SLG,SSO,SSO,SSP,STC,SBC,SNR,SCM,SLG,SLG,SLG,SDB, // LX
  SSO,SSO,SEN,SSO,SEN,SSO,SSO,SSO,SSP,STC,SBC,SNR,SCM,SSO,SSO,SSO,SSO, // EX
  SSO,SSO,SSO,SSO,SEN,SSO,SSO,SSO,SSP,STC,SBC,SNR,SCM,SSO,SSO,SSO,SSO, // EN
  SLG,SLG,SSO,SFL,SSO,SLG,SSO,SSO,SSP,STC,SBC,SNR,SCM,SLG,SLG,SLG,SDB, // LG
  SLG,SLX,SSO,SSO,SFT,SLG,SSO,SSO,SSP,STC,SBC,SNR,SCM,SLG,SLG,SLG,SDB, // ML
  SIQ,SIQ,SIQ,SIQ,SIQ,SIQ,SAP,SIQ,SIQ,SIQ,SIQ,SNR,SIQ,SIQ,SIQ,SIQ,SIQ, // IQ
  SSO,SSO,SSO,SSO,SSO,SSO,SIQ,SSO,SSO,STC,SBC,SNR,SCM,SOL,SHX,SCS,SSO, // AP
  SIH,SIH,SIH,SIH,SIH,SIH,SIH,SIH,SIH,SIH,SIH,SNR,SIH,SIH,SIH,SIH,SIH, // IH
  SFM,SFM,SFM,SFM,SFM,SFM,SFM,SFM,SFM,SFM,SFM,SNR,SFM,SFM,SFM,SFM,SFM, // FM
  SSO,SSO,SSO,SSO,SSO,SSO,SSO,SSO,SSO,SSO,SBC,SNR,SCM,SSO,SSO,SSO,SSO, // OL
  SSO,SSO,SSO,SSO,SSO,SSO,SSO,SSO,SSO,SSO,SBC,SNR,SCM,SSO,SSO,SSO,SSO, // HX
  SSO,SSO,SSO,SSO,SSO,SSO,SSO,SSO,SSO,SSO,SBC,SNR,SCM,SSO,SSO,SSO,SSO, // CS
  SLG,SLG,SSO,SSO,SFT,SLG,SSO,SSO,SSP,STC,SBC,SNR,SCM,SLG,SLG,SLG,SDB, // LL
};

#define BAD_LOG         14

char    *LogTab[] = {
        "EQ",   "NE",    "LT",    "GT",    "LE",     "GE",
        "OR",   "AND",   "NOT",   "EQV",   "NEQV",   "XOR",
        "TRUE", "FALSE", NULL
};

static  char            ExpREA;
static  char            ExpDBL;
static  char            ExpEXT;
static  TOKCLASS        TokenREA;
static  TOKCLASS        TokenDBL;
static  TOKCLASS        TokenEXT;


void    InitScan( void ) {
//==================

// Initialize the scanner.

    if( Options & OPT_EXTEND_REAL ) {
        TokenREA = TO_DBL;
        ExpREA = 'D';
        TokenDBL = TO_EXT;
        ExpDBL = 'Q';
    } else {
        TokenREA = TO_REA;
        ExpREA = 'E';
        TokenDBL = TO_DBL;
        ExpDBL = 'D';
    }
    TokenEXT = TO_EXT;
    ExpEXT = 'Q';
    Line = 0;
    State = SNS;
    TkCrsr = &TokenBuff[ 0 ];
    LexToken.stop = TkCrsr;
    LexToken.col = Column;
    LexToken.flags = 0;
    LexToken.line = 0;
    SrcRecNum = CurrFile->rec;
    // at this point, the line has already been read
    // so just print it with an ISN in front
    LinePrint();
    if( StmtType == STMT_CONT ) {
        Error( CC_NOT_INITIAL );
    }
    // examine the statement number if there was one
    ScanNum();
    ExtnSw &= ~XS_CONT_20;
}


void    Scan( void ) {
//==============

// Collect a token.

    token_state state2;
    char        ch;
    token_state old_state;
    char        *dpt = NULL;
    byte        tab;
    int         len;
    int         hlen;
    TOKCLASS    class;
    char_class  ch_class;
    char_class  wasextch;

    if( !(LexToken.flags & TK_LAST) ) {
        wasextch = 0;
        old_state = SNS;
        LexToken.start = LexToken.stop;
        LexToken.col = Column;
        LexToken.line = Line;
        for(;;) {
            ch = *Cursor;
            ch_class = CharSetInfo.character_set[ ch ];
            wasextch |= ch_class;
            state2 = StateTable[ State ][ ch_class & C_MASK ];
            switch( state2 ) {
            case SAN :
            case SLG :
                if( ch_class & C_LOW ) { // lower case character
                    ch += 'A' - 'a';
                }
                *TkCrsr = ch;
                TkCrsr++;
                State = state2;
                break;
            case SDB :
                if( CharSetInfo.character_width( Cursor ) != 2 ) {
                    Error( CC_BAD_CHAR );
                } else if( CharSetInfo.is_double_byte_blank( Cursor ) ) {
                    *Cursor = ' ';
                    *( Cursor + 1 ) = ' ';
                    Column--; // compensate for Column++ and Cursor++
                    Cursor--; // after select
                } else {
                    State = StateTable[ State ][ C_AL ];
                    *TkCrsr = ch;
                    TkCrsr++;
                    Cursor++;
                    Column++;
                    *TkCrsr = *Cursor;
                    TkCrsr++;
                }
                break;
            case SNM :
            case SFT :
            case SEN :
                *TkCrsr = ch;
                TkCrsr++;
                State = state2;
                break;
            case SSG :
                *TkCrsr = ch;
                TkCrsr++;
                // 0..71 is the statement area
                // 72..79 is the sequence area
                ++Cursor;
                if( ++Column >= LastColumn ) { // we've just processed column 72
                    *Cursor = NULLCHAR;
                }
                State = SOP;
                class = TO_OPR;
                goto token;
            case SEX :
            case SLX :
                if( LexToken.flags & TK_LENSPEC ) {
                    LexToken.flags &= ~TK_LENSPEC;
                    goto token;
                }
                if( ch_class & C_LOW ) { // lower case character
                    ch += 'A' - 'a';
                }
                State = state2;
                switch( ch ) {
                case( 'Q' ):
                    class = TokenEXT;
                    break;
                case( 'D' ):
                    class = TokenDBL;
                    break;
                case( 'E' ):
                    class = TokenREA;
                    break;
                }
                *TkCrsr = ch;
                TkCrsr++;
                break;
            case SML :
            case SLL :
                dpt = TkCrsr;
                old_state = State;
                *TkCrsr = ch;
                TkCrsr++;
                State = state2;
                break;
            case SFQ :
                State = SIQ;
                break;
            case SIQ :
                state2 = SIQ;
            case SFM :
                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++;
                }
                State = state2;
                break;
            case SOL :
            case SHX :
            case SCS :
                *TkCrsr = NULLCHAR; // for conversion routines
                TkCrsr++;
            case SAP :
                State = state2;
                break;
            case SSO :
                goto token;
            case SOP :
                *TkCrsr = ch;
                TkCrsr++;
                // 0..71 is the statement area
                // 72..79 is the sequence area
                ++Cursor;

⌨️ 快捷键说明

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