⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scanner.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
    case '"' :  // fall through    case '\\': break;    case 'b' : c = '\b'; break;    case 'f' : c = '\f'; break;    case 'n' : c = '\n'; break;    case 'r' : c = '\r'; break;    case 't' : c = '\t'; break;    case 'u' : c = ScanHexEscape(c, 4); break;    case 'v' : c = '\v'; break;    case 'x' : c = ScanHexEscape(c, 2); break;    case '0' :  // fall through    case '1' :  // fall through    case '2' :  // fall through    case '3' :  // fall through    case '4' :  // fall through    case '5' :  // fall through    case '6' :  // fall through    case '7' : c = ScanOctalEscape(c, 2); break;  }  // According to ECMA-262, 3rd, 7.8.4 (p 18ff) these  // should be illegal, but they are commonly handled  // as non-escaped characters by JS VMs.  AddChar(c);}Token::Value Scanner::ScanString() {  uc32 quote = c0_;  Advance();  // consume quote  StartLiteral();  while (c0_ != quote && c0_ >= 0 && !kIsLineTerminator.get(c0_)) {    uc32 c = c0_;    Advance();    if (c == '\\') {      if (c0_ < 0) return Token::ILLEGAL;      ScanEscape();    } else {      AddChar(c);    }  }  if (c0_ != quote) {    return Token::ILLEGAL;  }  TerminateLiteral();  Advance();  // consume quote  return Token::STRING;}Token::Value Scanner::Select(Token::Value tok) {  Advance();  return tok;}Token::Value Scanner::Select(uc32 next, Token::Value then, Token::Value else_) {  Advance();  if (c0_ == next) {    Advance();    return then;  } else {    return else_;  }}Token::Value Scanner::ScanToken() {  switch (c0_) {    // strings    case '"': case '\'':      return ScanString();    case '<':      // < <= << <<= <!--      Advance();      if (c0_ == '=') return Select(Token::LTE);      if (c0_ == '<') return Select('=', Token::ASSIGN_SHL, Token::SHL);      if (c0_ == '!') return ScanHtmlComment();      return Token::LT;    case '>':      // > >= >> >>= >>> >>>=      Advance();      if (c0_ == '=') return Select(Token::GTE);      if (c0_ == '>') {        // >> >>= >>> >>>=        Advance();        if (c0_ == '=') return Select(Token::ASSIGN_SAR);        if (c0_ == '>') return Select('=', Token::ASSIGN_SHR, Token::SHR);        return Token::SAR;      }      return Token::GT;    case '=':      // = == ===      Advance();      if (c0_ == '=') return Select('=', Token::EQ_STRICT, Token::EQ);      return Token::ASSIGN;    case '!':      // ! != !==      Advance();      if (c0_ == '=') return Select('=', Token::NE_STRICT, Token::NE);      return Token::NOT;    case '+':      // + ++ +=      Advance();      if (c0_ == '+') return Select(Token::INC);      if (c0_ == '=') return Select(Token::ASSIGN_ADD);      return Token::ADD;    case '-':      // - -- -=      Advance();      if (c0_ == '-') return Select(Token::DEC);      if (c0_ == '=') return Select(Token::ASSIGN_SUB);      return Token::SUB;    case '*':      // * *=      return Select('=', Token::ASSIGN_MUL, Token::MUL);    case '%':      // % %=      return Select('=', Token::ASSIGN_MOD, Token::MOD);    case '/':      // /  // /* /=      Advance();      if (c0_ == '/') return SkipSingleLineComment();      if (c0_ == '*') return SkipMultiLineComment();      if (c0_ == '=') return Select(Token::ASSIGN_DIV);      return Token::DIV;    case '&':      // & && &=      Advance();      if (c0_ == '&') return Select(Token::AND);      if (c0_ == '=') return Select(Token::ASSIGN_BIT_AND);      return Token::BIT_AND;    case '|':      // | || |=      Advance();      if (c0_ == '|') return Select(Token::OR);      if (c0_ == '=') return Select(Token::ASSIGN_BIT_OR);      return Token::BIT_OR;    case '^':      // ^ ^=      return Select('=', Token::ASSIGN_BIT_XOR, Token::BIT_XOR);    case '.':      // . Number      Advance();      if (IsDecimalDigit(c0_)) return ScanNumber(true);      return Token::PERIOD;    case ':':      return Select(Token::COLON);    case ';':      return Select(Token::SEMICOLON);    case ',':      return Select(Token::COMMA);    case '(':      return Select(Token::LPAREN);    case ')':      return Select(Token::RPAREN);    case '[':      return Select(Token::LBRACK);    case ']':      return Select(Token::RBRACK);    case '{':      return Select(Token::LBRACE);    case '}':      return Select(Token::RBRACE);    case '?':      return Select(Token::CONDITIONAL);    case '~':      return Select(Token::BIT_NOT);    default:      if (kIsIdentifierStart.get(c0_))        return ScanIdentifier();      if (IsDecimalDigit(c0_))        return ScanNumber(false);      if (c0_ < 0)        return Token::EOS;      return Select(Token::ILLEGAL);  }  UNREACHABLE();  return Token::ILLEGAL;}// Returns true if any decimal digits were scanned, returns false otherwise.void Scanner::ScanDecimalDigits() {  while (IsDecimalDigit(c0_))    AddCharAdvance();}Token::Value Scanner::ScanNumber(bool seen_period) {  ASSERT(IsDecimalDigit(c0_));  // the first digit of the number or the fraction  enum { DECIMAL, HEX, OCTAL } kind = DECIMAL;  StartLiteral();  if (seen_period) {    // we have already seen a decimal point of the float    AddChar('.');    ScanDecimalDigits();  // we know we have at least one digit  } else {    // if the first character is '0' we must check for octals and hex    if (c0_ == '0') {      AddCharAdvance();      // either 0, 0exxx, 0Exxx, 0.xxx, an octal number, or a hex number      if (c0_ == 'x' || c0_ == 'X') {        // hex number        kind = HEX;        AddCharAdvance();        if (!IsHexDigit(c0_))          // we must have at least one hex digit after 'x'/'X'          return Token::ILLEGAL;        while (IsHexDigit(c0_))          AddCharAdvance();      } else if ('0' <= c0_ && c0_ <= '7') {        // (possible) octal number        kind = OCTAL;        while (true) {          if (c0_ == '8' || c0_ == '9') {            kind = DECIMAL;            break;          }          if (c0_  < '0' || '7'  < c0_) break;          AddCharAdvance();        }      }    }    // Parse decimal digits and allow trailing fractional part.    if (kind == DECIMAL) {      ScanDecimalDigits();  // optional      if (c0_ == '.') {        AddCharAdvance();        ScanDecimalDigits();  // optional      }    }  }  // scan exponent, if any  if (c0_ == 'e' || c0_ == 'E') {    ASSERT(kind != HEX);  // 'e'/'E' must be scanned as part of the hex number    if (kind == OCTAL) return Token::ILLEGAL;  // no exponent for octals allowed    // scan exponent    AddCharAdvance();    if (c0_ == '+' || c0_ == '-')      AddCharAdvance();    if (!IsDecimalDigit(c0_))      // we must have at least one decimal digit after 'e'/'E'      return Token::ILLEGAL;    ScanDecimalDigits();  }  TerminateLiteral();  // The source character immediately following a numeric literal must  // not be an identifier start or a decimal digit; see ECMA-262  // section 7.8.3, page 17 (note that we read only one decimal digit  // if the value is 0).  if (IsDecimalDigit(c0_) || kIsIdentifierStart.get(c0_))    return Token::ILLEGAL;  return Token::NUMBER;}uc32 Scanner::ScanIdentifierUnicodeEscape() {  Advance();  if (c0_ != 'u') return unibrow::Utf8::kBadChar;  Advance();  uc32 c = ScanHexEscape('u', 4);  // We do not allow a unicode escape sequence to start another  // unicode escape sequence.  if (c == '\\') return unibrow::Utf8::kBadChar;  return c;}Token::Value Scanner::ScanIdentifier() {  ASSERT(kIsIdentifierStart.get(c0_));  bool has_escapes = false;  StartLiteral();  // Scan identifier start character.  if (c0_ == '\\') {    has_escapes = true;    uc32 c = ScanIdentifierUnicodeEscape();    // Only allow legal identifier start characters.    if (!kIsIdentifierStart.get(c)) return Token::ILLEGAL;    AddChar(c);  } else {    AddCharAdvance();  }  // Scan the rest of the identifier characters.  while (kIsIdentifierPart.get(c0_)) {    if (c0_ == '\\') {      has_escapes = true;      uc32 c = ScanIdentifierUnicodeEscape();      // Only allow legal identifier part characters.      if (!kIsIdentifierPart.get(c)) return Token::ILLEGAL;      AddChar(c);    } else {      AddCharAdvance();    }  }  TerminateLiteral();  // We don't have any 1-letter keywords (this is probably a common case).  if ((next_.literal_end - next_.literal_pos) == 1)    return Token::IDENTIFIER;  // If the identifier contains unicode escapes, it must not be  // resolved to a keyword.  if (has_escapes)    return Token::IDENTIFIER;  return Token::Lookup(&literals_.data()[next_.literal_pos]);}bool Scanner::IsIdentifier(unibrow::CharacterStream* buffer) {  // Checks whether the buffer contains an identifier (no escapse).  if (!buffer->has_more()) return false;  if (!kIsIdentifierStart.get(buffer->GetNext())) return false;  while (buffer->has_more()) {    if (!kIsIdentifierPart.get(buffer->GetNext())) return false;  }  return true;}bool Scanner::ScanRegExpPattern(bool seen_equal) {  // Scan: ('/' | '/=') RegularExpressionBody '/' RegularExpressionFlags  bool in_character_class = false;  // Previous token is either '/' or '/=', in the second case, the  // pattern starts at =.  next_.location.beg_pos = source_pos() - (seen_equal ? 2 : 1);  next_.location.end_pos = source_pos() - (seen_equal ? 1 : 0);  // Scan regular expression body: According to ECMA-262, 3rd, 7.8.5,  // the scanner should pass uninterpreted bodies to the RegExp  // constructor.  StartLiteral();  if (seen_equal)    AddChar('=');  while (c0_ != '/' || in_character_class) {    if (kIsLineTerminator.get(c0_) || c0_ < 0)      return false;    if (c0_ == '\\') {  // escaped character      AddCharAdvance();      if (kIsLineTerminator.get(c0_) || c0_ < 0)        return false;      AddCharAdvance();    } else {  // unescaped character      if (c0_ == '[')        in_character_class = true;      if (c0_ == ']')        in_character_class = false;      AddCharAdvance();    }  }  Advance();  // consume '/'  TerminateLiteral();  return true;}bool Scanner::ScanRegExpFlags() {  // Scan regular expression flags.  StartLiteral();  while (kIsIdentifierPart.get(c0_))    AddCharAdvance();  TerminateLiteral();  next_.location.end_pos = source_pos() - 1;  return true;}} }  // namespace v8::internal

⌨️ 快捷键说明

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