static int ScanIdentifier() { unsigned char* start = CURSOR; if('L' == *CURSOR) { if('\'' == CURSOR[1]) { return ScanCharLiteral(); } else if('\"' == CURSOR[1]) { return ScanStringLiteral(); } } CURSOR++; while(IsLetterOrDigit(*CURSOR)) { CURSOR++; } return FindKeyword((char *)start, (int)(CURSOR - start)); }
/* 标示符扫描函数 */ static int ScanIdentifierOR (int def) { unsigned char *start = CURRENT; int tok; /* 处理宽字符或宽字符串 */ if ('L' == *CURRENT) { /* 处理字符 */ if ('\'' == CURRENT[1]) return ScanCharLiteral (); /* 处理宽字符串 */ if ('"' == CURRENT[1]) return ScanStringLiteral (); } if ( !IsLetterOrDigit (*CURRENT) ) return TK_BEGIN; CURRENT++; /* 字母和数字下画线都符合标示符的要求 */ while (IsLetterOrDigit (*CURRENT)) CURRENT++; /* 判断是否是关键字 */ tok = FindKeyword ((char*)start, (int)(CURRENT - start)); if (TK_ID == tok) { Symbol p; /* 将字符串的值保存在字符串池中 */ TokenValue.p = InternStr ((char*)start, (int)(CURRENT - start)); // 该符号是define if (!def && (p = LookupDefine (TokenValue.p))) { LoadDefine (p); return GetNextToken (); } } else TokenValue.p = TokenString[tok]; return tok; }
TokenPtr SLScanner::ScanToken() { std::string spell; /* Scan directive (beginning with '#') */ if (Is('#')) return ScanDirective(); /* Scan identifier */ if (std::isalpha(UChr()) || Is('_')) return ScanIdentifier(); /* Scan number */ if (Is('.')) return ScanNumberOrDot(); if (std::isdigit(UChr())) return ScanNumber(); /* Scan string literal */ if (Is('\"')) return ScanStringLiteral(); /* Scan operators */ if (Is('=')) { spell += TakeIt(); if (Is('=')) return Make(Tokens::BinaryOp, spell, true); return Make(Tokens::AssignOp, spell); } if (Is('~')) return Make(Tokens::UnaryOp, spell, true); if (Is('!')) { spell += TakeIt(); if (Is('=')) return Make(Tokens::BinaryOp, spell, true); return Make(Tokens::UnaryOp, spell); } if (Is('%')) { spell += TakeIt(); if (Is('=')) return Make(Tokens::AssignOp, spell, true); return Make(Tokens::BinaryOp, spell); } if (Is('*')) { spell += TakeIt(); if (Is('=')) return Make(Tokens::AssignOp, spell, true); return Make(Tokens::BinaryOp, spell); } if (Is('^')) { spell += TakeIt(); if (Is('=')) return Make(Tokens::AssignOp, spell, true); return Make(Tokens::BinaryOp, spell); } if (Is('+')) return ScanPlusOp(); if (Is('-')) return ScanMinusOp(); if (Is('<') || Is('>')) return ScanAssignShiftRelationOp(Chr()); if (Is('&')) { spell += TakeIt(); if (Is('=')) return Make(Tokens::AssignOp, spell, true); if (Is('&')) return Make(Tokens::BinaryOp, spell, true); return Make(Tokens::BinaryOp, spell); } if (Is('|')) { spell += TakeIt(); if (Is('=')) return Make(Tokens::AssignOp, spell, true); if (Is('|')) return Make(Tokens::BinaryOp, spell, true); return Make(Tokens::BinaryOp, spell); } if (Is(':')) { spell += TakeIt(); if (Is(':')) return Make(Tokens::DColon, spell, true); return Make(Tokens::Colon, spell); } /* Scan punctuation, special characters and brackets */ switch (Chr()) { case ';': return Make(Tokens::Semicolon, true); break; case ',': return Make(Tokens::Comma, true); break; case '?': return Make(Tokens::TernaryOp, true); break; case '(': return Make(Tokens::LBracket, true); break; case ')': return Make(Tokens::RBracket, true); break; case '{': return Make(Tokens::LCurly, true); break; case '}': return Make(Tokens::RCurly, true); break; case '[': return Make(Tokens::LParen, true); break; case ']': return Make(Tokens::RParen, true); break; } ErrorUnexpected(); return nullptr; }