1a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifndef V8_DATEPARSER_H_ 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define V8_DATEPARSER_H_ 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/allocation.h" 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/char-predicates-inl.h" 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 1271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass DateParser : public AllStatic { 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Parse the string as a date. If parsing succeeds, return true after 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // filling out the output array as follows (all integers are Smis): 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // [0]: year 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // [1]: month (0 = Jan, 1 = Feb, ...) 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // [2]: day 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // [3]: hour 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // [4]: minute 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // [5]: second 244111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org // [6]: millisecond 254111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org // [7]: UTC offset in seconds, or null value if no timezone specified 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If parsing fails, return false (content of output array is not defined). 27bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org template <typename Char> 28a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org static bool Parse(Vector<Char> str, FixedArray* output, UnicodeCache* cache); 2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 30bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org enum { 314111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, MILLISECOND, UTC_OFFSET, OUTPUT_SIZE 32bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org }; 3343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 3543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Range testing 36bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org static inline bool Between(int x, int lo, int hi) { 37bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return static_cast<unsigned>(x - lo) <= static_cast<unsigned>(hi - lo); 38bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org } 394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 4043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Indicates a missing value. 4143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int kNone = kMaxInt; 4243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // Maximal number of digits used to build the value of a numeral. 444f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // Remaining digits are ignored. 454f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org static const int kMaxSignificantDigits = 9; 464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 4743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // InputReader provides basic string parsing and character classification. 48bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org template <typename Char> 4943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen class InputReader BASE_EMBEDDED { 5043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 51a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org InputReader(UnicodeCache* unicode_cache, Vector<Char> s) 52bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org : index_(0), 53bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org buffer_(s), 54a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org unicode_cache_(unicode_cache) { 5543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 5643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 584f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int position() { return index_; } 594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 6043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Advance to the next character of the string. 614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org void Next() { 624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ch_ = (index_ < buffer_.length()) ? buffer_[index_] : 0; 634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org index_++; 6443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 6543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 664f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // Read a string of digits as an unsigned number. Cap value at 674f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // kMaxSignificantDigits, but skip remaining digits if the numeral 684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // is longer. 694f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int ReadUnsignedNumeral() { 70beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org int n = 0; 714f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int i = 0; 724f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org while (IsAsciiDigit()) { 734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (i < kMaxSignificantDigits) n = n * 10 + ch_ - '0'; 744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org i++; 754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Next(); 76beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org } 77beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org return n; 78beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org } 79beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org 8043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Read a word (sequence of chars. >= 'A'), fill the given buffer with a 8143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // lower-case prefix, and pad any remainder of the buffer with zeroes. 8243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return word length. 8343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int ReadWord(uint32_t* prefix, int prefix_size) { 8443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int len; 8543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (len = 0; IsAsciiAlphaOrAbove(); Next(), len++) { 863cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org if (len < prefix_size) prefix[len] = AsciiAlphaToLower(ch_); 8743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 8843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = len; i < prefix_size; i++) prefix[i] = 0; 8943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return len; 9043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 9143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 9243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The skip methods return whether they actually skipped something. 934a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com bool Skip(uint32_t c) { 944a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com if (ch_ == c) { 954a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com Next(); 964a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com return true; 974a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com } 984a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com return false; 994a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com } 10043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 10143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool SkipWhiteSpace() { 102f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (unicode_cache_->IsWhiteSpaceOrLineTerminator(ch_)) { 1034a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com Next(); 1044a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com return true; 1054a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com } 1064a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com return false; 10743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 10843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 10943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool SkipParentheses() { 11043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (ch_ != '(') return false; 11143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int balance = 0; 11243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen do { 11343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (ch_ == ')') --balance; 11443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen else if (ch_ == '(') ++balance; 11543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Next(); 11643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } while (balance > 0 && ch_); 11743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 11843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 11943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Character testing/classification. Non-ASCII digits are not supported. 12143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool Is(uint32_t c) const { return ch_ == c; } 12243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool IsEnd() const { return ch_ == 0; } 12343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool IsAsciiDigit() const { return IsDecimalDigit(ch_); } 12443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool IsAsciiAlphaOrAbove() const { return ch_ >= 'A'; } 12543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool IsAsciiSign() const { return ch_ == '+' || ch_ == '-'; } 12643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return 1 for '+' and -1 for '-'. 12843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int GetAsciiSignValue() const { return 44 - static_cast<int>(ch_); } 12943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 13043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 131bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org int index_; 132bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org Vector<Char> buffer_; 13343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen uint32_t ch_; 134a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org UnicodeCache* unicode_cache_; 13543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen }; 13643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org enum KeywordType { 1384f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org INVALID, MONTH_NAME, TIME_ZONE_NAME, TIME_SEPARATOR, AM_PM 1394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org }; 1404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 1414f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org struct DateToken { 1424f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org public: 1434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool IsInvalid() { return tag_ == kInvalidTokenTag; } 1444f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool IsUnknown() { return tag_ == kUnknownTokenTag; } 1454f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool IsNumber() { return tag_ == kNumberTag; } 1464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool IsSymbol() { return tag_ == kSymbolTag; } 1474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool IsWhiteSpace() { return tag_ == kWhiteSpaceTag; } 1484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool IsEndOfInput() { return tag_ == kEndOfInputTag; } 1494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool IsKeyword() { return tag_ >= kKeywordTagStart; } 1504f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 1514f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int length() { return length_; } 1524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 1534f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int number() { 154e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsNumber()); 1554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return value_; 1564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 1574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org KeywordType keyword_type() { 158e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsKeyword()); 1594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return static_cast<KeywordType>(tag_); 1604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 1614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int keyword_value() { 162e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsKeyword()); 1634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return value_; 1644f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 1654f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org char symbol() { 166e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsSymbol()); 1674f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return static_cast<char>(value_); 1684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 1694f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool IsSymbol(char symbol) { 1704f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return IsSymbol() && this->symbol() == symbol; 1714f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 1724f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool IsKeywordType(KeywordType tag) { 1734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return tag_ == tag; 1744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 1754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool IsFixedLengthNumber(int length) { 1764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return IsNumber() && length_ == length; 1774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 1784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool IsAsciiSign() { 1794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return tag_ == kSymbolTag && (value_ == '-' || value_ == '+'); 1804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 1814f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int ascii_sign() { 182e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsAsciiSign()); 1834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return 44 - value_; 1844f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 1854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool IsKeywordZ() { 1864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return IsKeywordType(TIME_ZONE_NAME) && length_ == 1 && value_ == 0; 1874f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 1884f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool IsUnknown(int character) { 1894f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return IsUnknown() && value_ == character; 1904f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 1914f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // Factory functions. 1924f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org static DateToken Keyword(KeywordType tag, int value, int length) { 1934f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return DateToken(tag, length, value); 1944f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 1954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org static DateToken Number(int value, int length) { 1964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return DateToken(kNumberTag, length, value); 1974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 1984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org static DateToken Symbol(char symbol) { 1994f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return DateToken(kSymbolTag, 1, symbol); 2004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 2014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org static DateToken EndOfInput() { 2024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return DateToken(kEndOfInputTag, 0, -1); 2034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 2044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org static DateToken WhiteSpace(int length) { 2054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return DateToken(kWhiteSpaceTag, length, -1); 2064f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 2074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org static DateToken Unknown() { 2084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return DateToken(kUnknownTokenTag, 1, -1); 2094f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 2104f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org static DateToken Invalid() { 2114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return DateToken(kInvalidTokenTag, 0, -1); 2124f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 21383e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org 2144f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org private: 2154f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org enum TagType { 2164f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org kInvalidTokenTag = -6, 2174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org kUnknownTokenTag = -5, 2184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org kWhiteSpaceTag = -4, 2194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org kNumberTag = -3, 2204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org kSymbolTag = -2, 2214f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org kEndOfInputTag = -1, 2224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org kKeywordTagStart = 0 2234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org }; 2244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DateToken(int tag, int length, int value) 2254f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org : tag_(tag), 2264f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org length_(length), 2274f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org value_(value) { } 2284f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 2294f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int tag_; 2304f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int length_; // Number of characters. 2314f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int value_; 2324f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org }; 2334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 2344f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org template <typename Char> 2354f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org class DateStringTokenizer { 2364f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org public: 2374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org explicit DateStringTokenizer(InputReader<Char>* in) 2384f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org : in_(in), next_(Scan()) { } 2394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DateToken Next() { 2404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DateToken result = next_; 2414f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org next_ = Scan(); 2424f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return result; 2434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 2444f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 2454f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DateToken Peek() { 2464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return next_; 2474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 2484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool SkipSymbol(char symbol) { 2494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (next_.IsSymbol(symbol)) { 2504f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org next_ = Scan(); 2514f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return true; 2524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 2534f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return false; 2544f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 25583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org 2564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org private: 2574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DateToken Scan(); 2584f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 2594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org InputReader<Char>* in_; 2604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DateToken next_; 2614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org }; 2624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 2634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org static int ReadMilliseconds(DateToken number); 26443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 26543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // KeywordTable maps names of months, time zones, am/pm to numbers. 26643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen class KeywordTable : public AllStatic { 26743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 26843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Look up a word in the keyword table and return an index. 26943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 'pre' contains a prefix of the word, zero-padded to size kPrefixLength 27043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // and 'len' is the word length. 27143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static int Lookup(const uint32_t* pre, int len); 27243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the type of the keyword at index i. 27343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static KeywordType GetType(int i) { 27443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return static_cast<KeywordType>(array[i][kTypeOffset]); 27543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 27643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the value of the keyword at index i. 27743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static int GetValue(int i) { return array[i][kValueOffset]; } 27843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int kPrefixLength = 3; 28043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int kTypeOffset = kPrefixLength; 28143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int kValueOffset = kTypeOffset + 1; 28243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int kEntrySize = kValueOffset + 1; 28343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int8_t array[][kEntrySize]; 28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen }; 28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen class TimeZoneComposer BASE_EMBEDDED { 28743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 28843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TimeZoneComposer() : sign_(kNone), hour_(kNone), minute_(kNone) {} 28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void Set(int offset_in_hours) { 29043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen sign_ = offset_in_hours < 0 ? -1 : 1; 29143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen hour_ = offset_in_hours * sign_; 29243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen minute_ = 0; 29343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 29443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void SetSign(int sign) { sign_ = sign < 0 ? -1 : 1; } 29543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void SetAbsoluteHour(int hour) { hour_ = hour; } 29643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void SetAbsoluteMinute(int minute) { minute_ = minute; } 29743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool IsExpecting(int n) const { 29843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return hour_ != kNone && minute_ == kNone && TimeComposer::IsMinute(n); 29943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 30043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool IsUTC() const { return hour_ == 0 && minute_ == 0; } 30143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool Write(FixedArray* output); 3024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool IsEmpty() { return hour_ == kNone; } 30343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int sign_; 30543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int hour_; 30643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int minute_; 30743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen }; 30843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 30943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen class TimeComposer BASE_EMBEDDED { 31043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TimeComposer() : index_(0), hour_offset_(kNone) {} 31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool IsEmpty() const { return index_ == 0; } 31343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool IsExpecting(int n) const { 3144111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org return (index_ == 1 && IsMinute(n)) || 3154111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org (index_ == 2 && IsSecond(n)) || 3164111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org (index_ == 3 && IsMillisecond(n)); 31743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 31843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool Add(int n) { 31943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return index_ < kSize ? (comp_[index_++] = n, true) : false; 32043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 32143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool AddFinal(int n) { 32243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!Add(n)) return false; 32343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (index_ < kSize) comp_[index_++] = 0; 32443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 32543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 32643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void SetHourOffset(int n) { hour_offset_ = n; } 32743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool Write(FixedArray* output); 32843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 32943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static bool IsMinute(int x) { return Between(x, 0, 59); } 33043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static bool IsHour(int x) { return Between(x, 0, 23); } 33143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static bool IsSecond(int x) { return Between(x, 0, 59); } 33283e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org 3334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org private: 3344f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org static bool IsHour12(int x) { return Between(x, 0, 12); } 3354111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org static bool IsMillisecond(int x) { return Between(x, 0, 999); } 33643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3374111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org static const int kSize = 4; 33843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int comp_[kSize]; 33943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int index_; 34043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int hour_offset_; 34143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen }; 34243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 34343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen class DayComposer BASE_EMBEDDED { 34443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 3454f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DayComposer() : index_(0), named_month_(kNone), is_iso_date_(false) {} 34643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool IsEmpty() const { return index_ == 0; } 34743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool Add(int n) { 3484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (index_ < kSize) { 3494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org comp_[index_] = n; 3504f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org index_++; 3514f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return true; 3524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 3534f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return false; 35443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 35543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void SetNamedMonth(int n) { named_month_ = n; } 35643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool Write(FixedArray* output); 3574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org void set_iso_date() { is_iso_date_ = true; } 35843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static bool IsMonth(int x) { return Between(x, 1, 12); } 35943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static bool IsDay(int x) { return Between(x, 1, 31); } 36043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org private: 36243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int kSize = 3; 36343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int comp_[kSize]; 36443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int index_; 36543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int named_month_; 3664f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // If set, ensures that data is always parsed in year-month-date order. 3674f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool is_iso_date_; 36843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen }; 3694f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 3704f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // Tries to parse an ES5 Date Time String. Returns the next token 3714f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // to continue with in the legacy date string parser. If parsing is 3724f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // complete, returns DateToken::EndOfInput(). If terminally unsuccessful, 3734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // returns DateToken::Invalid(). Otherwise parsing continues in the 3744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // legacy parser. 3754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org template <typename Char> 3764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org static DateParser::DateToken ParseES5DateTime( 3774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DateStringTokenizer<Char>* scanner, 3784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DayComposer* day, 3794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org TimeComposer* time, 3804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org TimeZoneComposer* tz); 38143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 38243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 38343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 38443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 38543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 38643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif // V8_DATEPARSER_H_ 387