static void ProcLibrary( void ) /*****************************/ { bool gotprivate; gotprivate = ProcessKeyword( LibraryTypes ); FmtInfo = DLL_INITGLOBAL; if( !MakeToken( SEP_NO, true ) ) { return; } if( !IsInitType() ) { if( CmdFile->len > 8 ) { Warning( "module name too large", OPTION_SLOT ); } else if( GotModName ) { Warning( "module name multiply defined" , OPTION_SLOT ); } else { AddStringOption( "modname", CmdFile->token, CmdFile->len ); GotModName = true; } if( !MakeToken( SEP_NO, true ) ) { return; } } if( !IsInitType() ) { DirectiveError(); } if( !gotprivate ) { ProcessKeyword( LibraryTypes ); } }
static void ProcName( void ) /**************************/ { int index; if( !MakeToken( SEP_NO, true ) ) { return; } if( !ProcessKeyList( ApplicationTypes, CmdFile->token, CmdFile->len ) ) { if( GotModName ) { Warning( "module name multiply defined", OPTION_SLOT ); } else { AddStringOption( "modname", CmdFile->token, CmdFile->len ); GotModName = true; } } for( index = 0; index < 2; index++ ) { if( !MakeToken( SEP_NO, true ) ) { return; } if( !ProcessKeyList( ApplicationTypes, CmdFile->token, CmdFile->len ) ) { DirectiveError(); } } }
static void ProcAppLoader( void ) /*******************************/ { NotSupported( "apploader" ); if( !MakeToken( SEP_QUOTE, true ) ) { MakeToken( SEP_NO, true ); } }
static void ProcInclude ( void ) /******************************/ { if( MakeToken( SEP_QUOTE, true ) || MakeToken( SEP_NO, true ) ) { StartNewFile( ToString() ); ParseDefFile(); } else { Warning( "invalid include statement", OPTION_SLOT ); } }
static void ProcOvl( void ) /*************************/ { MakeToken( SEP_COLON, false ); Warning( "ovl option on segment directive not supported by wlink", OPTION_SLOT ); GotOvl = true; }
static void ProcFunctions( void ) /*******************************/ { Warning( "Functions style overlay management not directly translatable to watcom", OPTION_SLOT ); MakeToken( SEP_COLON, false ); // skip number. MultiLine = SkipFunction; }
static void ProcClass( void ) /***************************/ { if( !MakeToken( SEP_QUOTE, true ) ) { Warning( "class argument invalid", OPTION_SLOT ); } }
Error Lexer(const wchar_t*& Input , vector<LexerToken>& Tokens , bool StopAtLineBreak) { Error aError; aError.Position=0; Tokens.clear(); while(true) { int Count=0; LexerChars(Input,lSpace); if(Count=LexerName(Input)) { Tokens.push_back(MakeToken(Input,ltName,Count,0,0)); } else if(Count=LexerString(Input)) { Tokens.push_back(MakeToken(Input,ltString,Count,1,1)); } else if(Count=LexerReal(Input)) { Tokens.push_back(MakeToken(Input,ltReal,Count,0,0)); } else if(Count=LexerInt(Input)) { Tokens.push_back(MakeToken(Input,ltInt,Count,0,0)); } else if(Count=LexerChar(Input,L':')) { Tokens.push_back(MakeToken(Input,ltColon,Count,0,0)); } else if(Count=LexerChars(Input,lSpaceCrLf)) { if(StopAtLineBreak)break; } else if(*Input==L'\0') { break; } else { aError.Position=Input; aError.Message=wstring(L"遇到不可识别字符:")+(*Input)+L"。"; break; } } return aError; }
static void ProcOld( void ) /*************************/ { if( !MakeToken( SEP_QUOTE, TRUE ) ) { Warning( "argument for old not valid", OPTION_SLOT ); } else { AddStringOption( "old", CmdFile->token, CmdFile->len ); } }
static void ProcStub( void ) /**************************/ { if( !MakeToken( SEP_QUOTE, true ) ) { Warning( "argument for stub not valid", OPTION_SLOT ); } else { AddStringOption( "stub", CmdFile->token, CmdFile->len ); } }
static void GetSegments( void ) /*****************************/ { char *segname; size_t seglen; char buffer[ CODE_BUFFER_LEN ]; char *result; char *currloc; size_t len; GotOvl = false; if( MakeToken( SEP_QUOTE, true ) || MakeToken( SEP_NO, true ) ) { DUPBUF_STACK( segname, CmdFile->token, CmdFile->len ); // store it temporarily seglen = CmdFile->len; } else { Warning( "segment argument not recognized", OPTION_SLOT ); return; } if( ProcessKeyword( SegOptions ) ) { // process the options ProcessKeyword( SegOptions ); } OptionBuffer = buffer; BufferLeft = CODE_BUFFER_LEN; if( !ProcessKeyword( SegAttributes ) && !GotOvl ) { Warning( "no segment attributes specified", OPTION_SLOT ); } else { // get the rest of the attributes. while( ProcessKeyword( SegAttributes ) ) {} // NULL statement. if( BufferLeft != CODE_BUFFER_LEN && !GotOvl ) { // something spec'd. len = CODE_BUFFER_LEN - BufferLeft; result = MemAlloc( len + seglen + 12 ); memcpy( result, "segment '", 9 ); currloc = result + 9; memcpy( currloc, segname, seglen ); currloc += seglen; *currloc++ = '\''; *currloc++ = ' '; memcpy( currloc, buffer, len ); *(currloc + len) = '\0'; AddCommand( result, OPTION_SLOT, false ); } } MultiLine = GetSegments; }
void Scanner::IdentifyAndMake() { TokenType t; TokenValue v; if (!reserved_words.Identify(buffer_low, t, v)) //如果不是保留字,注意在Identify函数中 { //用的是引用,所以会改变t,v的值 t = IDENTIFIER; //说明其实普通标识符 v = TOK_UNRESERVED; //值为不是保留字 } MakeToken(t, v); }
bool Scanner::TryToIdentify() { TokenType t; TokenValue v; if (reserved_words.Identify(buffer_low, t, v)) { MakeToken(t, v); return true; } return false; }
static void SetWindows( void ) /****************************/ { unsigned long bogus; FmtType = FMT_WINDOWS; if( !MakeToken( SEP_NO, FALSE ) ) return; if( !GetNumber( &bogus ) ) { CmdFile->current = CmdFile->token; // reparse the token later } }
static void ProcDescription( void ) /*********************************/ { #define PREFIX "description '" char *msg; MakeToken( SEP_QUOTE, true ); msg = alloca( CmdFile->len + sizeof( PREFIX ) + 1 ); memcpy( msg, PREFIX, sizeof( PREFIX ) ); memcpy( msg + sizeof( PREFIX ) - 1, CmdFile->token, CmdFile->len ); strcpy( msg + sizeof( PREFIX ) - 1 + CmdFile->len, "'" ); AddOption( msg ); }
static void ProcStackSize( void ) /*******************************/ { unsigned long value; if( !MakeToken( SEP_NO, true ) ) { Warning( "argument for stacksize is invalid", OPTION_SLOT ); } else if( !GetNumber( &value ) || value >= (64*1024UL) ) { Warning( "argument for stacksize is invalid", OPTION_SLOT ); } else { AddNumOption( "stack", value ); } }
static void ProcHeapsize( void ) /******************************/ { unsigned long value; if( !MakeToken( SEP_NO, true ) ) { Warning( "argument for heapsize not recognized", OPTION_SLOT ); } else if( memicmp( CmdFile->token, "maxval", 6 ) == 0 ) { AddNumOption( "heapsize", 0xFFFF ); } else if( !GetNumber( &value ) || value >= (64*1024UL) ) { Warning( "argument for heapsize not valid", OPTION_SLOT ); } else { AddNumOption( "heapsize", value ); } }
static bool ProcessKeyword( parse_entry *entry ) /**********************************************/ // returns true if keyword found. { bool ret; if( !MakeToken( SEP_NO, false ) ) { return( false ); } ret = ProcessKeyList( entry, CmdFile->token, CmdFile->len ); if( !ret ) { CmdFile->current = CmdFile->token; // reparse the token later. } return( ret ); }
void Scanner::AtInterger() { while (isdigit(c)) // { AddToBuffer(c); ExtractChar(); } /*if (tolower(c) == 'e' || (c == '.' && in.peek() != '.')) { AddToBuffer(c); ExtractChar(); EatRealFractPart(); }*/ MakeToken(INT_CONST); }
static void GetImport( void ) /***************************/ { char *first; size_t firstlen; char *second; size_t secondlen; unsigned long value; char *result; size_t toklen; char *currloc; if( !MakeToken( SEP_NO, false ) ) { Warning( "import library name is invalid", OPTION_SLOT ); return; } DUPBUF_STACK( first, CmdFile->token, CmdFile->len ); // store it temporarily toklen = firstlen = CmdFile->len; second = NULL; secondlen = 0; if( MakeToken( SEP_EQUALS, false ) ) { // got an internal name. DUPBUF_STACK( second, CmdFile->token, CmdFile->len ); // store it temporarily secondlen = CmdFile->len; toklen += secondlen + 1; // name & = sign. } if( !MakeToken( SEP_PERIOD, true ) ) { Warning( "import entry is invalid", OPTION_SLOT ); return; } value = 0xFFFFF; // arbitrary > 64k. if( GetNumber( &value ) ) { if( second == NULL ) { Warning("must have an internal name when an ordinal is specified", OPTION_SLOT ); return; } else if( value >= (64*1024UL) ) { Warning( "import ordinal out of range", OPTION_SLOT ); return; } toklen += 6; // maximum size of ordinal + dot. } else { toklen += CmdFile->len + 1; // string length + dot. } toklen += 8; // import keyword + space + nullchar; result = MemAlloc( toklen ); memcpy( result, "import ", 7 ); currloc = result + 7; if( second != NULL ) { // got a internal name in first. memcpy( currloc, first, firstlen ); currloc += firstlen; first = second; // make sure module name is in first. firstlen = secondlen; } else { memcpy( currloc, CmdFile->token, CmdFile->len ); currloc += CmdFile->len; } *currloc++ = ' '; memcpy( currloc, first, firstlen ); // module name currloc += firstlen; if( value < (64*1024UL) ) { *currloc++ = '.'; ultoa( value, currloc, 10 ); } else { if( second != NULL ) { *currloc++ = '.'; memcpy( currloc, CmdFile->token, CmdFile->len ); currloc += CmdFile->len; } *currloc = '\0'; } AddCommand( result, OPTION_SLOT, false ); }
Token Scanner::GetNextToken() { bool match = false; do { ExtractChar(); //从文件中获取一个字符 //列如 begin,首先c=b;加入缓冲区,重新读取c=e if (state != NONE_ST) match = true; //此时状态为标识符,则调用AtIdentifier switch (state) { case IDENTIFIER_ST: AtIdentifier(); break; case INTEGER_ST: AtInterger(); break; case OPERATION_ST: AtOperation(); break; case EOF_ST: MakeToken(END_OF_FILE); break; case NONE_ST: //不做运算 break; default: break; } if (state == NONE_ST) { AtLineComment(); //注释 if (c == '\n') { ++row; column= 0; } else { first_line= row; //第几列 first_pos = column; //第几行 if (in.eof()) { state = EOF_ST; } else if (!isspace(c)) //空格 { if (isalpha(c) || c == '_') //字母或下划线开头 { state = IDENTIFIER_ST; //表明其实标识符 } else if (isdigit(c)) { state = INTEGER_ST; } else { state = OPERATION_ST; } AddToBuffer(c); } } } } while (!match); return token; }
static void SkipFunction( void ) /******************************/ // this skips a function name { MakeToken( SEP_SPACE, true ); // skip a function name }
static void GetExport( void ) /***************************/ { char *internal; size_t intlen; char *name; size_t namelen; unsigned long value; unsigned long iopl; bool isresident; bool gottoken; bool gotnodata; size_t toklen; char *command; char *currloc; if( !MakeToken( SEP_NO, true ) ) { Warning( "invalid export name", OPTION_SLOT ); return; } DUPBUF_STACK( name, CmdFile->token, CmdFile->len ); // store it temporarily toklen = namelen = CmdFile->len; internal = NULL; intlen = 0; if( MakeToken( SEP_EQUALS, true ) ) { // got an internal name. DUPBUF_STACK( internal, CmdFile->token, CmdFile->len ); // store it temporarily intlen = CmdFile->len; toklen += intlen + 1; // +1 for = sign. } value = 0xFFFFF; // arbitrary >64K. if( MakeToken( SEP_AT, true ) ) { // got an ordinal. if( !GetNumber( &value ) || value > (64 * 1024UL) ) { Warning( "export ordinal value is invalid", OPTION_SLOT ); return; } else { toklen += 6; // maximum integer length + dot } } isresident = false; EatWhite(); gottoken = MakeToken( SEP_NO, true ); if( gottoken ) { if( CmdFile->len == 12 && memicmp( CmdFile->token, "residentname", 12 ) == 0 ) { isresident = true; gottoken = MakeToken( SEP_NO, true ); toklen += 9; // length of resident + space. } } gotnodata = false; if( gottoken ) { if( memicmp( CmdFile->token, "nodata", 6 ) == 0 ) { gottoken = MakeToken( SEP_NO, true ); gotnodata = true; } } iopl = 1024; // arbitrary > 63 if( gottoken ) { if( !GetNumber( &iopl ) || iopl > 63 ) { Warning( "iopl value is invalid", OPTION_SLOT ); } else { toklen += 3; // maximum iopl length + space. } if( !gotnodata ) { gottoken = MakeToken( SEP_NO, true ); } } if( gottoken && !gotnodata ) { if( memicmp( CmdFile->token, "nodata", 6 ) == 0 ) { gotnodata = true; } else { CmdFile->current = CmdFile->token; // reparse the token later } } toklen += 8; // export keyword + space + nullchar; command = MemAlloc( toklen ); memcpy( command, "export ", 7 ); currloc = command + 7; memcpy( currloc, name, namelen ); currloc += namelen; if( value <= (64*1024UL) ) { // if an ordinal was specified.... *currloc++ = '.'; ultoa( value, currloc, 10 ); while( *currloc != '\0' ) { // find end of string. currloc++; } } if( internal != NULL ) { *currloc++ = '='; memcpy( currloc, internal, intlen ); currloc += intlen; } if( isresident ) { *currloc++ = ' '; memcpy( currloc, "resident", 8 ); currloc += 8; } if( iopl <= 63 ) { *currloc++ = ' '; ultoa( iopl * 2, currloc, 10 ); // convert iopl value to a byte value } else { *currloc = '\0'; } AddCommand( command, OPTION_SLOT, false ); }