説明を見る。00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef V8_DATEPARSER_H_
00029 #define V8_DATEPARSER_H_
00030
00031 #include "scanner.h"
00032
00033 namespace v8 { namespace internal {
00034
00035
00036 class DateParser : public AllStatic {
00037 public:
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 static bool Parse(String* str, FixedArray* output);
00050
00051 enum {YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, UTC_OFFSET, OUTPUT_SIZE};
00052
00053 private:
00054
00055 static bool Between(int x, int lo, int hi) { return x >= lo && x <= hi; }
00056
00057 static const int kNone = kMaxInt;
00058
00059
00060 class InputReader BASE_EMBEDDED {
00061 public:
00062 explicit InputReader(String* s) : buffer_(s), has_read_number_(false) {
00063 Next();
00064 }
00065
00066
00067 void Next() { ch_ = buffer_.has_more() ? buffer_.GetNext() : 0; }
00068
00069
00070 int ReadUnsignedNumber() {
00071 has_read_number_ = true;
00072 int n;
00073 for (n = 0; IsAsciiDigit() && n < kMaxInt / 10 - 1; Next()) {
00074 n = n * 10 + ch_ - '0';
00075 }
00076 return n;
00077 }
00078
00079
00080
00081
00082 int ReadWord(uint32_t* prefix, int prefix_size) {
00083 int len;
00084 for (len = 0; IsAsciiAlphaOrAbove(); Next(), len++) {
00085 if (len < prefix_size) prefix[len] = GetAsciiAlphaLower();
00086 }
00087 for (int i = len; i < prefix_size; i++) prefix[i] = 0;
00088 return len;
00089 }
00090
00091
00092 bool Skip(uint32_t c) { return ch_ == c ? (Next(), true) : false; }
00093
00094 bool SkipWhiteSpace() {
00095 return Scanner::kIsWhiteSpace.get(ch_) ? (Next(), true) : false;
00096 }
00097
00098 bool SkipParentheses() {
00099 if (ch_ != '(') return false;
00100 int balance = 0;
00101 do {
00102 if (ch_ == ')') --balance;
00103 else if (ch_ == '(') ++balance;
00104 Next();
00105 } while (balance > 0 && ch_);
00106 return true;
00107 }
00108
00109
00110 bool Is(uint32_t c) const { return ch_ == c; }
00111 bool IsEnd() const { return ch_ == 0; }
00112 bool IsAsciiDigit() const { return IsDecimalDigit(ch_); }
00113 bool IsAsciiAlphaOrAbove() const { return ch_ >= 'A'; }
00114 bool IsAsciiSign() const { return ch_ == '+' || ch_ == '-'; }
00115
00116
00117 int GetAsciiSignValue() const { return 44 - static_cast<int>(ch_); }
00118
00119
00120 bool HasReadNumber() const { return has_read_number_; }
00121
00122 private:
00123
00124
00125 uint32_t GetAsciiAlphaLower() const { return ch_ | 32; }
00126
00127 StringInputBuffer buffer_;
00128 bool has_read_number_;
00129 uint32_t ch_;
00130 };
00131
00132 enum KeywordType { INVALID, MONTH_NAME, TIME_ZONE_NAME, AM_PM };
00133
00134
00135 class KeywordTable : public AllStatic {
00136 public:
00137
00138
00139
00140 static int Lookup(const uint32_t* pre, int len);
00141
00142 static KeywordType GetType(int i) {
00143 return static_cast<KeywordType>(array[i][kTypeOffset]);
00144 }
00145
00146 static int GetValue(int i) { return array[i][kValueOffset]; }
00147
00148 static const int kPrefixLength = 3;
00149 static const int kTypeOffset = kPrefixLength;
00150 static const int kValueOffset = kTypeOffset + 1;
00151 static const int kEntrySize = kValueOffset + 1;
00152 static const int8_t array[][kEntrySize];
00153 };
00154
00155 class TimeZoneComposer BASE_EMBEDDED {
00156 public:
00157 TimeZoneComposer() : sign_(kNone), hour_(kNone), minute_(kNone) {}
00158 void Set(int offset_in_hours) {
00159 sign_ = offset_in_hours < 0 ? -1 : 1;
00160 hour_ = offset_in_hours * sign_;
00161 minute_ = 0;
00162 }
00163 void SetSign(int sign) { sign_ = sign < 0 ? -1 : 1; }
00164 void SetAbsoluteHour(int hour) { hour_ = hour; }
00165 void SetAbsoluteMinute(int minute) { minute_ = minute; }
00166 bool IsExpecting(int n) const {
00167 return hour_ != kNone && minute_ == kNone && TimeComposer::IsMinute(n);
00168 }
00169 bool IsUTC() const { return hour_ == 0 && minute_ == 0; }
00170 bool Write(FixedArray* output);
00171 private:
00172 int sign_;
00173 int hour_;
00174 int minute_;
00175 };
00176
00177 class TimeComposer BASE_EMBEDDED {
00178 public:
00179 TimeComposer() : index_(0), hour_offset_(kNone) {}
00180 bool IsEmpty() const { return index_ == 0; }
00181 bool IsExpecting(int n) const {
00182 return (index_ == 1 && IsMinute(n)) || (index_ == 2 && IsSecond(n));
00183 }
00184 bool Add(int n) {
00185 return index_ < kSize ? (comp_[index_++] = n, true) : false;
00186 }
00187 bool AddFinal(int n) {
00188 if (!Add(n)) return false;
00189 while (index_ < kSize) comp_[index_++] = 0;
00190 return true;
00191 }
00192 void SetHourOffset(int n) { hour_offset_ = n; }
00193 bool Write(FixedArray* output);
00194
00195 static bool IsMinute(int x) { return Between(x, 0, 59); }
00196 private:
00197 static bool IsHour(int x) { return Between(x, 0, 23); }
00198 static bool IsHour12(int x) { return Between(x, 0, 12); }
00199 static bool IsSecond(int x) { return Between(x, 0, 59); }
00200
00201 static const int kSize = 3;
00202 int comp_[kSize];
00203 int index_;
00204 int hour_offset_;
00205 };
00206
00207 class DayComposer BASE_EMBEDDED {
00208 public:
00209 DayComposer() : index_(0), named_month_(kNone) {}
00210 bool IsEmpty() const { return index_ == 0; }
00211 bool Add(int n) {
00212 return index_ < kSize ? (comp_[index_++] = n, true) : false;
00213 }
00214 void SetNamedMonth(int n) { named_month_ = n; }
00215 bool Write(FixedArray* output);
00216 private:
00217 static bool IsMonth(int x) { return Between(x, 1, 12); }
00218 static bool IsDay(int x) { return Between(x, 1, 31); }
00219
00220 static const int kSize = 3;
00221 int comp_[kSize];
00222 int index_;
00223 int named_month_;
00224 };
00225 };
00226
00227
00228 } }
00229
00230 #endif // V8_DATEPARSER_H_