18b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_DATEPARSER_H_ 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_DATEPARSER_H_ 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "allocation.h" 328a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang#include "char-predicates-inl.h" 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass DateParser : public AllStatic { 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Parse the string as a date. If parsing succeeds, return true after 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // filling out the output array as follows (all integers are Smis): 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [0]: year 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [1]: month (0 = Jan, 1 = Feb, ...) 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [2]: day 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [3]: hour 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [4]: minute 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [5]: second 476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // [6]: millisecond 486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // [7]: UTC offset in seconds, or null value if no timezone specified 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If parsing fails, return false (content of output array is not defined). 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block template <typename Char> 518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch static bool Parse(Vector<Char> str, FixedArray* output, UnicodeCache* cache); 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum { 546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, MILLISECOND, UTC_OFFSET, OUTPUT_SIZE 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Range testing 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline bool Between(int x, int lo, int hi) { 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<unsigned>(x - lo) <= static_cast<unsigned>(hi - lo); 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Indicates a missing value. 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kNone = kMaxInt; 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Maximal number of digits used to build the value of a numeral. 673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Remaining digits are ignored. 683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static const int kMaxSignificantDigits = 9; 693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // InputReader provides basic string parsing and character classification. 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block template <typename Char> 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class InputReader BASE_EMBEDDED { 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch InputReader(UnicodeCache* unicode_cache, Vector<Char> s) 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : index_(0), 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_(s), 778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch unicode_cache_(unicode_cache) { 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Next(); 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int position() { return index_; } 823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Advance to the next character of the string. 843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void Next() { 853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ch_ = (index_ < buffer_.length()) ? buffer_[index_] : 0; 863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch index_++; 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Read a string of digits as an unsigned number. Cap value at 903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // kMaxSignificantDigits, but skip remaining digits if the numeral 913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // is longer. 923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int ReadUnsignedNumeral() { 938a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang int n = 0; 943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int i = 0; 953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (IsAsciiDigit()) { 963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (i < kMaxSignificantDigits) n = n * 10 + ch_ - '0'; 973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch i++; 983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Next(); 998a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 1008a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return n; 1018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 1028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Read a word (sequence of chars. >= 'A'), fill the given buffer with a 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // lower-case prefix, and pad any remainder of the buffer with zeroes. 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return word length. 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int ReadWord(uint32_t* prefix, int prefix_size) { 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int len; 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (len = 0; IsAsciiAlphaOrAbove(); Next(), len++) { 1099ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick if (len < prefix_size) prefix[len] = AsciiAlphaToLower(ch_); 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = len; i < prefix_size; i++) prefix[i] = 0; 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return len; 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The skip methods return whether they actually skipped something. 1168a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang bool Skip(uint32_t c) { 1178a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang if (ch_ == c) { 1188a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang Next(); 1198a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return true; 1208a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 1218a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return false; 1228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool SkipWhiteSpace() { 1258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (unicode_cache_->IsWhiteSpace(ch_)) { 1268a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang Next(); 1278a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return true; 1288a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 1298a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return false; 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool SkipParentheses() { 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (ch_ != '(') return false; 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int balance = 0; 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (ch_ == ')') --balance; 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else if (ch_ == '(') ++balance; 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Next(); 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (balance > 0 && ch_); 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Character testing/classification. Non-ASCII digits are not supported. 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool Is(uint32_t c) const { return ch_ == c; } 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsEnd() const { return ch_ == 0; } 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsAsciiDigit() const { return IsDecimalDigit(ch_); } 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsAsciiAlphaOrAbove() const { return ch_ >= 'A'; } 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsAsciiSign() const { return ch_ == '+' || ch_ == '-'; } 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return 1 for '+' and -1 for '-'. 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int GetAsciiSignValue() const { return 44 - static_cast<int>(ch_); } 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index_; 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Vector<Char> buffer_; 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t ch_; 1578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch UnicodeCache* unicode_cache_; 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch enum KeywordType { 1613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch INVALID, MONTH_NAME, TIME_ZONE_NAME, TIME_SEPARATOR, AM_PM 1623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch }; 1633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch struct DateToken { 1653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public: 1663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool IsInvalid() { return tag_ == kInvalidTokenTag; } 1673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool IsUnknown() { return tag_ == kUnknownTokenTag; } 1683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool IsNumber() { return tag_ == kNumberTag; } 1693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool IsSymbol() { return tag_ == kSymbolTag; } 1703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool IsWhiteSpace() { return tag_ == kWhiteSpaceTag; } 1713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool IsEndOfInput() { return tag_ == kEndOfInputTag; } 1723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool IsKeyword() { return tag_ >= kKeywordTagStart; } 1733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int length() { return length_; } 1753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int number() { 1773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(IsNumber()); 1783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return value_; 1793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch KeywordType keyword_type() { 1813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(IsKeyword()); 1823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return static_cast<KeywordType>(tag_); 1833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int keyword_value() { 1853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(IsKeyword()); 1863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return value_; 1873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch char symbol() { 1893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(IsSymbol()); 1903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return static_cast<char>(value_); 1913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool IsSymbol(char symbol) { 1933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return IsSymbol() && this->symbol() == symbol; 1943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool IsKeywordType(KeywordType tag) { 1963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return tag_ == tag; 1973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool IsFixedLengthNumber(int length) { 1993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return IsNumber() && length_ == length; 2003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool IsAsciiSign() { 2023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return tag_ == kSymbolTag && (value_ == '-' || value_ == '+'); 2033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int ascii_sign() { 2053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(IsAsciiSign()); 2063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return 44 - value_; 2073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool IsKeywordZ() { 2093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return IsKeywordType(TIME_ZONE_NAME) && length_ == 1 && value_ == 0; 2103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool IsUnknown(int character) { 2123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return IsUnknown() && value_ == character; 2133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Factory functions. 2153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static DateToken Keyword(KeywordType tag, int value, int length) { 2163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return DateToken(tag, length, value); 2173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static DateToken Number(int value, int length) { 2193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return DateToken(kNumberTag, length, value); 2203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static DateToken Symbol(char symbol) { 2223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return DateToken(kSymbolTag, 1, symbol); 2233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static DateToken EndOfInput() { 2253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return DateToken(kEndOfInputTag, 0, -1); 2263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static DateToken WhiteSpace(int length) { 2283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return DateToken(kWhiteSpaceTag, length, -1); 2293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static DateToken Unknown() { 2313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return DateToken(kUnknownTokenTag, 1, -1); 2323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static DateToken Invalid() { 2343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return DateToken(kInvalidTokenTag, 0, -1); 2353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 236589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 2373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private: 2383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch enum TagType { 2393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch kInvalidTokenTag = -6, 2403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch kUnknownTokenTag = -5, 2413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch kWhiteSpaceTag = -4, 2423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch kNumberTag = -3, 2433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch kSymbolTag = -2, 2443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch kEndOfInputTag = -1, 2453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch kKeywordTagStart = 0 2463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch }; 2473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DateToken(int tag, int length, int value) 2483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : tag_(tag), 2493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch length_(length), 2503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch value_(value) { } 2513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int tag_; 2533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int length_; // Number of characters. 2543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int value_; 2553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch }; 2563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch template <typename Char> 2583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch class DateStringTokenizer { 2593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public: 2603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch explicit DateStringTokenizer(InputReader<Char>* in) 2613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : in_(in), next_(Scan()) { } 2623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DateToken Next() { 2633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DateToken result = next_; 2643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch next_ = Scan(); 2653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return result; 2663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DateToken Peek() { 2693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return next_; 2703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool SkipSymbol(char symbol) { 2723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (next_.IsSymbol(symbol)) { 2733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch next_ = Scan(); 2743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return true; 2753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return false; 2773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 278589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 2793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private: 2803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DateToken Scan(); 2813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch InputReader<Char>* in_; 2833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DateToken next_; 2843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch }; 2853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static int ReadMilliseconds(DateToken number); 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // KeywordTable maps names of months, time zones, am/pm to numbers. 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class KeywordTable : public AllStatic { 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Look up a word in the keyword table and return an index. 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 'pre' contains a prefix of the word, zero-padded to size kPrefixLength 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and 'len' is the word length. 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static int Lookup(const uint32_t* pre, int len); 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the type of the keyword at index i. 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static KeywordType GetType(int i) { 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<KeywordType>(array[i][kTypeOffset]); 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the value of the keyword at index i. 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static int GetValue(int i) { return array[i][kValueOffset]; } 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kPrefixLength = 3; 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kTypeOffset = kPrefixLength; 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kValueOffset = kTypeOffset + 1; 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kEntrySize = kValueOffset + 1; 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int8_t array[][kEntrySize]; 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class TimeZoneComposer BASE_EMBEDDED { 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TimeZoneComposer() : sign_(kNone), hour_(kNone), minute_(kNone) {} 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Set(int offset_in_hours) { 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sign_ = offset_in_hours < 0 ? -1 : 1; 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block hour_ = offset_in_hours * sign_; 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block minute_ = 0; 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void SetSign(int sign) { sign_ = sign < 0 ? -1 : 1; } 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void SetAbsoluteHour(int hour) { hour_ = hour; } 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void SetAbsoluteMinute(int minute) { minute_ = minute; } 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsExpecting(int n) const { 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return hour_ != kNone && minute_ == kNone && TimeComposer::IsMinute(n); 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsUTC() const { return hour_ == 0 && minute_ == 0; } 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool Write(FixedArray* output); 3253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool IsEmpty() { return hour_ == kNone; } 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sign_; 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int hour_; 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int minute_; 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class TimeComposer BASE_EMBEDDED { 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TimeComposer() : index_(0), hour_offset_(kNone) {} 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsEmpty() const { return index_ == 0; } 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsExpecting(int n) const { 3376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return (index_ == 1 && IsMinute(n)) || 3386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block (index_ == 2 && IsSecond(n)) || 3396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block (index_ == 3 && IsMillisecond(n)); 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool Add(int n) { 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return index_ < kSize ? (comp_[index_++] = n, true) : false; 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool AddFinal(int n) { 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Add(n)) return false; 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (index_ < kSize) comp_[index_++] = 0; 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void SetHourOffset(int n) { hour_offset_ = n; } 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool Write(FixedArray* output); 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static bool IsMinute(int x) { return Between(x, 0, 59); } 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static bool IsHour(int x) { return Between(x, 0, 23); } 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static bool IsSecond(int x) { return Between(x, 0, 59); } 355589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 3563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private: 3573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static bool IsHour12(int x) { return Between(x, 0, 12); } 3586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static bool IsMillisecond(int x) { return Between(x, 0, 999); } 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static const int kSize = 4; 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int comp_[kSize]; 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index_; 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int hour_offset_; 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block class DayComposer BASE_EMBEDDED { 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 3683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DayComposer() : index_(0), named_month_(kNone), is_iso_date_(false) {} 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool IsEmpty() const { return index_ == 0; } 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool Add(int n) { 3713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (index_ < kSize) { 3723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch comp_[index_] = n; 3733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch index_++; 3743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return true; 3753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return false; 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void SetNamedMonth(int n) { named_month_ = n; } 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool Write(FixedArray* output); 3803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void set_iso_date() { is_iso_date_ = true; } 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static bool IsMonth(int x) { return Between(x, 1, 12); } 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static bool IsDay(int x) { return Between(x, 1, 31); } 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private: 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kSize = 3; 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int comp_[kSize]; 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int index_; 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int named_month_; 3893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // If set, ensures that data is always parsed in year-month-date order. 3903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool is_iso_date_; 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 3923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Tries to parse an ES5 Date Time String. Returns the next token 3943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // to continue with in the legacy date string parser. If parsing is 3953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // complete, returns DateToken::EndOfInput(). If terminally unsuccessful, 3963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // returns DateToken::Invalid(). Otherwise parsing continues in the 3973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // legacy parser. 3983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch template <typename Char> 3993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static DateParser::DateToken ParseES5DateTime( 4003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DateStringTokenizer<Char>* scanner, 4013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DayComposer* day, 4023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch TimeComposer* time, 4033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch TimeZoneComposer* tz); 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_DATEPARSER_H_ 410