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 + -
显示快捷键?