28 #ifndef V8_DATEPARSER_H_
29 #define V8_DATEPARSER_H_
50 template <
typename Char>
59 static inline bool Between(
int x,
int lo,
int hi) {
60 return static_cast<unsigned>(x -
lo) <= static_cast<unsigned>(hi - lo);
64 static const int kNone =
kMaxInt;
68 static const int kMaxSignificantDigits = 9;
71 template <
typename Char>
74 InputReader(UnicodeCache* unicode_cache, Vector<Char> s)
77 unicode_cache_(unicode_cache) {
81 int position() {
return index_; }
85 ch_ = (index_ < buffer_.length()) ? buffer_[index_] : 0;
92 int ReadUnsignedNumeral() {
95 while (IsAsciiDigit()) {
96 if (i < kMaxSignificantDigits) n = n * 10 + ch_ -
'0';
106 int ReadWord(uint32_t* prefix,
int prefix_size) {
108 for (len = 0; IsAsciiAlphaOrAbove(); Next(), len++) {
111 for (
int i = len; i < prefix_size; i++) prefix[i] = 0;
116 bool Skip(uint32_t c) {
124 bool SkipWhiteSpace() {
125 if (unicode_cache_->IsWhiteSpaceOrLineTerminator(ch_)) {
132 bool SkipParentheses() {
133 if (ch_ !=
'(')
return false;
136 if (ch_ ==
')') --balance;
137 else if (ch_ ==
'(') ++balance;
139 }
while (balance > 0 && ch_);
144 bool Is(uint32_t c)
const {
return ch_ == c; }
145 bool IsEnd()
const {
return ch_ == 0; }
147 bool IsAsciiAlphaOrAbove()
const {
return ch_ >=
'A'; }
148 bool IsAsciiSign()
const {
return ch_ ==
'+' || ch_ ==
'-'; }
151 int GetAsciiSignValue()
const {
return 44 -
static_cast<int>(ch_); }
155 Vector<Char> buffer_;
157 UnicodeCache* unicode_cache_;
161 INVALID, MONTH_NAME, TIME_ZONE_NAME, TIME_SEPARATOR, AM_PM
166 bool IsInvalid() {
return tag_ == kInvalidTokenTag; }
167 bool IsUnknown() {
return tag_ == kUnknownTokenTag; }
168 bool IsNumber() {
return tag_ == kNumberTag; }
169 bool IsSymbol() {
return tag_ == kSymbolTag; }
170 bool IsWhiteSpace() {
return tag_ == kWhiteSpaceTag; }
171 bool IsEndOfInput() {
return tag_ == kEndOfInputTag; }
172 bool IsKeyword() {
return tag_ >= kKeywordTagStart; }
174 int length() {
return length_; }
180 KeywordType keyword_type() {
182 return static_cast<KeywordType
>(tag_);
184 int keyword_value() {
190 return static_cast<char>(value_);
192 bool IsSymbol(
char symbol) {
193 return IsSymbol() && this->symbol() == symbol;
195 bool IsKeywordType(KeywordType tag) {
198 bool IsFixedLengthNumber(
int length) {
199 return IsNumber() && length_ == length;
202 return tag_ == kSymbolTag && (value_ ==
'-' || value_ ==
'+');
209 return IsKeywordType(TIME_ZONE_NAME) && length_ == 1 && value_ == 0;
211 bool IsUnknown(
int character) {
212 return IsUnknown() && value_ == character;
215 static DateToken Keyword(KeywordType tag,
int value,
int length) {
216 return DateToken(tag, length, value);
218 static DateToken Number(
int value,
int length) {
219 return DateToken(kNumberTag, length, value);
221 static DateToken
Symbol(
char symbol) {
222 return DateToken(kSymbolTag, 1, symbol);
224 static DateToken EndOfInput() {
225 return DateToken(kEndOfInputTag, 0, -1);
227 static DateToken WhiteSpace(
int length) {
228 return DateToken(kWhiteSpaceTag, length, -1);
230 static DateToken Unknown() {
231 return DateToken(kUnknownTokenTag, 1, -1);
233 static DateToken Invalid() {
234 return DateToken(kInvalidTokenTag, 0, -1);
239 kInvalidTokenTag = -6,
240 kUnknownTokenTag = -5,
247 DateToken(
int tag,
int length,
int value)
257 template <
typename Char>
258 class DateStringTokenizer {
260 explicit DateStringTokenizer(InputReader<Char>* in)
261 : in_(in), next_(Scan()) { }
263 DateToken result = next_;
271 bool SkipSymbol(
char symbol) {
272 if (next_.IsSymbol(symbol)) {
282 InputReader<Char>* in_;
286 static int ReadMilliseconds(DateToken number);
289 class KeywordTable :
public AllStatic {
294 static int Lookup(
const uint32_t* pre,
int len);
296 static KeywordType GetType(
int i) {
297 return static_cast<KeywordType
>(array[i][kTypeOffset]);
300 static int GetValue(
int i) {
return array[i][kValueOffset]; }
302 static const int kPrefixLength = 3;
303 static const int kTypeOffset = kPrefixLength;
304 static const int kValueOffset = kTypeOffset + 1;
305 static const int kEntrySize = kValueOffset + 1;
306 static const int8_t array[][kEntrySize];
311 TimeZoneComposer() : sign_(kNone), hour_(kNone), minute_(kNone) {}
312 void Set(
int offset_in_hours) {
313 sign_ = offset_in_hours < 0 ? -1 : 1;
314 hour_ = offset_in_hours * sign_;
317 void SetSign(
int sign) { sign_ = sign < 0 ? -1 : 1; }
318 void SetAbsoluteHour(
int hour) { hour_ = hour; }
319 void SetAbsoluteMinute(
int minute) { minute_ = minute; }
320 bool IsExpecting(
int n)
const {
321 return hour_ != kNone && minute_ == kNone && TimeComposer::IsMinute(n);
323 bool IsUTC()
const {
return hour_ == 0 && minute_ == 0; }
324 bool Write(FixedArray* output);
325 bool IsEmpty() {
return hour_ == kNone; }
334 TimeComposer() : index_(0), hour_offset_(kNone) {}
335 bool IsEmpty()
const {
return index_ == 0; }
336 bool IsExpecting(
int n)
const {
337 return (index_ == 1 && IsMinute(n)) ||
338 (index_ == 2 && IsSecond(n)) ||
339 (index_ == 3 && IsMillisecond(n));
342 return index_ < kSize ? (comp_[index_++] = n,
true) :
false;
344 bool AddFinal(
int n) {
345 if (!Add(n))
return false;
346 while (index_ < kSize) comp_[index_++] = 0;
349 void SetHourOffset(
int n) { hour_offset_ = n; }
350 bool Write(FixedArray* output);
352 static bool IsMinute(
int x) {
return Between(x, 0, 59); }
353 static bool IsHour(
int x) {
return Between(x, 0, 23); }
354 static bool IsSecond(
int x) {
return Between(x, 0, 59); }
357 static bool IsHour12(
int x) {
return Between(x, 0, 12); }
358 static bool IsMillisecond(
int x) {
return Between(x, 0, 999); }
360 static const int kSize = 4;
368 DayComposer() : index_(0), named_month_(kNone), is_iso_date_(
false) {}
369 bool IsEmpty()
const {
return index_ == 0; }
371 if (index_ < kSize) {
378 void SetNamedMonth(
int n) { named_month_ = n; }
379 bool Write(FixedArray* output);
380 void set_iso_date() { is_iso_date_ =
true; }
381 static bool IsMonth(
int x) {
return Between(x, 1, 12); }
382 static bool IsDay(
int x) {
return Between(x, 1, 31); }
385 static const int kSize = 3;
398 template <
typename Char>
399 static DateParser::DateToken ParseES5DateTime(
400 DateStringTokenizer<Char>* scanner,
403 TimeZoneComposer* tz);
409 #endif // V8_DATEPARSER_H_
int AsciiAlphaToLower(uc32 c)
static bool Parse(Vector< Char > str, FixedArray *output, UnicodeCache *cache)
#define ASSERT(condition)
IN DWORD64 OUT PDWORD64 OUT PIMAGEHLP_SYMBOL64 Symbol
bool IsDecimalDigit(uc32 c)