[scanner] Simplify Scanner::ScanNumber

Change-Id: I5a706b015a36a7a176a03e740f3fc3c406e6a837
Reviewed-on: https://chromium-review.googlesource.com/927263
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: Adam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51411}
This commit is contained in:
Sathya Gunasekaran 2018-02-20 17:54:40 -08:00 committed by Commit Bot
parent 0fae93f401
commit 3e1c00ae97
2 changed files with 73 additions and 46 deletions

View File

@ -1228,6 +1228,56 @@ void Scanner::ScanDecimalDigits() {
AddLiteralCharAdvance(); AddLiteralCharAdvance();
} }
bool Scanner::ScanBinaryDigits() {
// we must have at least one binary digit after 'b'/'B'
if (!IsBinaryDigit(c0_)) return false;
while (IsBinaryDigit(c0_)) {
AddLiteralCharAdvance();
}
return true;
}
bool Scanner::ScanOctalDigits() {
// we must have at least one octal digit after 'o'/'O'
if (!IsOctalDigit(c0_)) return false;
while (IsOctalDigit(c0_)) {
AddLiteralCharAdvance();
}
return true;
}
bool Scanner::ScanImplicitOctalDigits(int start_pos) {
// (possible) octal number
while (true) {
if (c0_ == '8' || c0_ == '9') return false;
if (c0_ < '0' || '7' < c0_) {
// Octal literal finished.
octal_pos_ = Location(start_pos, source_pos());
octal_message_ = MessageTemplate::kStrictOctalLiteral;
break;
}
AddLiteralCharAdvance();
}
return true;
}
bool Scanner::ScanHexDigits() {
// we must have at least one hex digit after 'x'/'X'
if (!IsHexDigit(c0_)) return false;
while (IsHexDigit(c0_)) {
AddLiteralCharAdvance();
}
return true;
}
bool Scanner::ScanSignedInteger() {
if (c0_ == '+' || c0_ == '-') AddLiteralCharAdvance();
// we must have at least one decimal digit after 'e'/'E'
if (!IsDecimalDigit(c0_)) return false;
ScanDecimalDigits();
return true;
}
Token::Value Scanner::ScanNumber(bool seen_period) { Token::Value Scanner::ScanNumber(bool seen_period) {
DCHECK(IsDecimalDigit(c0_)); // the first digit of the number or the fraction DCHECK(IsDecimalDigit(c0_)); // the first digit of the number or the fraction
@ -1257,52 +1307,22 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
// either 0, 0exxx, 0Exxx, 0.xxx, a hex number, a binary number or // either 0, 0exxx, 0Exxx, 0.xxx, a hex number, a binary number or
// an octal number. // an octal number.
if (c0_ == 'x' || c0_ == 'X') { if (c0_ == 'x' || c0_ == 'X') {
// hex number AddLiteralCharAdvance();
kind = HEX; kind = HEX;
AddLiteralCharAdvance(); if (!ScanHexDigits()) return Token::ILLEGAL;
if (!IsHexDigit(c0_)) {
// we must have at least one hex digit after 'x'/'X'
return Token::ILLEGAL;
}
while (IsHexDigit(c0_)) {
AddLiteralCharAdvance();
}
} else if (c0_ == 'o' || c0_ == 'O') { } else if (c0_ == 'o' || c0_ == 'O') {
AddLiteralCharAdvance();
kind = OCTAL; kind = OCTAL;
AddLiteralCharAdvance(); if (!ScanOctalDigits()) return Token::ILLEGAL;
if (!IsOctalDigit(c0_)) {
// we must have at least one octal digit after 'o'/'O'
return Token::ILLEGAL;
}
while (IsOctalDigit(c0_)) {
AddLiteralCharAdvance();
}
} else if (c0_ == 'b' || c0_ == 'B') { } else if (c0_ == 'b' || c0_ == 'B') {
kind = BINARY;
AddLiteralCharAdvance(); AddLiteralCharAdvance();
if (!IsBinaryDigit(c0_)) { kind = BINARY;
// we must have at least one binary digit after 'b'/'B' if (!ScanBinaryDigits()) return Token::ILLEGAL;
return Token::ILLEGAL;
}
while (IsBinaryDigit(c0_)) {
AddLiteralCharAdvance();
}
} else if ('0' <= c0_ && c0_ <= '7') { } else if ('0' <= c0_ && c0_ <= '7') {
// (possible) octal number
kind = IMPLICIT_OCTAL; kind = IMPLICIT_OCTAL;
while (true) { if (!ScanImplicitOctalDigits(start_pos)) {
if (c0_ == '8' || c0_ == '9') { kind = DECIMAL_WITH_LEADING_ZERO;
at_start = false; at_start = false;
kind = DECIMAL_WITH_LEADING_ZERO;
break;
}
if (c0_ < '0' || '7' < c0_) {
// Octal literal finished.
octal_pos_ = Location(start_pos, source_pos());
octal_message_ = MessageTemplate::kStrictOctalLiteral;
break;
}
AddLiteralCharAdvance();
} }
} else if (c0_ == '8' || c0_ == '9') { } else if (c0_ == '8' || c0_ == '9') {
kind = DECIMAL_WITH_LEADING_ZERO; kind = DECIMAL_WITH_LEADING_ZERO;
@ -1311,6 +1331,7 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
// Parse decimal digits and allow trailing fractional part. // Parse decimal digits and allow trailing fractional part.
if (kind == DECIMAL || kind == DECIMAL_WITH_LEADING_ZERO) { if (kind == DECIMAL || kind == DECIMAL_WITH_LEADING_ZERO) {
// This is an optimization for parsing Decimal numbers as Smi's.
if (at_start) { if (at_start) {
uint64_t value = 0; uint64_t value = 0;
while (IsDecimalDigit(c0_)) { while (IsDecimalDigit(c0_)) {
@ -1365,17 +1386,14 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
} else if (c0_ == 'e' || c0_ == 'E') { } else if (c0_ == 'e' || c0_ == 'E') {
// scan exponent, if any // scan exponent, if any
DCHECK(kind != HEX); // 'e'/'E' must be scanned as part of the hex number DCHECK(kind != HEX); // 'e'/'E' must be scanned as part of the hex number
if (!(kind == DECIMAL || kind == DECIMAL_WITH_LEADING_ZERO)) if (!(kind == DECIMAL || kind == DECIMAL_WITH_LEADING_ZERO))
return Token::ILLEGAL; return Token::ILLEGAL;
// scan exponent // scan exponent
AddLiteralCharAdvance(); AddLiteralCharAdvance();
if (c0_ == '+' || c0_ == '-')
AddLiteralCharAdvance(); if (!ScanSignedInteger()) return Token::ILLEGAL;
if (!IsDecimalDigit(c0_)) {
// we must have at least one decimal digit after 'e'/'E'
return Token::ILLEGAL;
}
ScanDecimalDigits();
} }
// The source character immediately following a numeric literal must // The source character immediately following a numeric literal must
@ -1556,6 +1574,9 @@ static Token::Value KeywordOrIdentifierToken(const uint8_t* input,
KEYWORDS(KEYWORD_GROUP_CASE, KEYWORD) KEYWORDS(KEYWORD_GROUP_CASE, KEYWORD)
} }
return Token::IDENTIFIER; return Token::IDENTIFIER;
#undef KEYWORDS
#undef KEYWORD
#undef KEYWORD_GROUP_CASE
} }
Token::Value Scanner::ScanIdentifierOrKeyword() { Token::Value Scanner::ScanIdentifierOrKeyword() {

View File

@ -721,6 +721,12 @@ class Scanner {
Token::Value ScanHtmlComment(); Token::Value ScanHtmlComment();
void ScanDecimalDigits(); void ScanDecimalDigits();
bool ScanHexDigits();
bool ScanBinaryDigits();
bool ScanSignedInteger();
bool ScanOctalDigits();
bool ScanImplicitOctalDigits(int start_pos);
Token::Value ScanNumber(bool seen_period); Token::Value ScanNumber(bool seen_period);
Token::Value ScanIdentifierOrKeyword(); Token::Value ScanIdentifierOrKeyword();
Token::Value ScanIdentifierOrKeywordInner(LiteralScope* literal); Token::Value ScanIdentifierOrKeywordInner(LiteralScope* literal);