| Index: src/scanner.h
|
| diff --git a/src/scanner.h b/src/scanner.h
|
| index a201d0e9766f114f9610d1390740eae79539cad5..201803da5e0f4d02654df44dac66d232ae1f2b79 100644
|
| --- a/src/scanner.h
|
| +++ b/src/scanner.h
|
| @@ -123,6 +123,121 @@ class TwoByteStringUTF16Buffer: public UTF16Buffer {
|
| };
|
|
|
|
|
| +class KeywordMatcher {
|
| +// Incrementally recognize keywords.
|
| +//
|
| +// Recognized keywords:
|
| +// break case catch const* continue debugger* default delete do else
|
| +// finally false for function if in instanceof native* new null
|
| +// return switch this throw true try typeof var void while with
|
| +//
|
| +// *: Actually "future reserved keywords". These are the only ones we
|
| +// recognized, the remaining are allowed as identifiers.
|
| + public:
|
| + KeywordMatcher() : state_(INITIAL), token_(Token::IDENTIFIER) {}
|
| +
|
| + Token::Value token() { return token_; }
|
| +
|
| + inline void AddChar(uc32 input) {
|
| + if (state_ != UNMATCHABLE) {
|
| + Step(input);
|
| + }
|
| + }
|
| +
|
| + void Fail() {
|
| + token_ = Token::IDENTIFIER;
|
| + state_ = UNMATCHABLE;
|
| + }
|
| +
|
| + private:
|
| + enum State {
|
| + UNMATCHABLE,
|
| + INITIAL,
|
| + KEYWORD_PREFIX,
|
| + KEYWORD_MATCHED,
|
| + C,
|
| + CA,
|
| + CO,
|
| + CON,
|
| + D,
|
| + DE,
|
| + F,
|
| + I,
|
| + IN,
|
| + N,
|
| + T,
|
| + TH,
|
| + TR,
|
| + V,
|
| + W
|
| + };
|
| +
|
| + struct FirstState {
|
| + const char* keyword;
|
| + State state;
|
| + Token::Value token;
|
| + };
|
| +
|
| + // Range of possible first characters of a keyword.
|
| + static const unsigned int kFirstCharRangeMin = 'b';
|
| + static const unsigned int kFirstCharRangeMax = 'w';
|
| + static const unsigned int kFirstCharRangeLength =
|
| + kFirstCharRangeMax - kFirstCharRangeMin + 1;
|
| + // State map for first keyword character range.
|
| + static FirstState first_states_[kFirstCharRangeLength];
|
| +
|
| + // Current state.
|
| + State state_;
|
| + // Token for currently added characters.
|
| + Token::Value token_;
|
| +
|
| + // Matching a specific keyword string (there is only one possible valid
|
| + // keyword with the current prefix).
|
| + const char* keyword_;
|
| + int counter_;
|
| + Token::Value keyword_token_;
|
| +
|
| + // If input equals keyword's character at position, continue matching keyword
|
| + // from that position.
|
| + inline bool MatchKeywordStart(uc32 input,
|
| + const char* keyword,
|
| + int position,
|
| + Token::Value token_if_match) {
|
| + if (input == keyword[position]) {
|
| + state_ = KEYWORD_PREFIX;
|
| + this->keyword_ = keyword;
|
| + this->counter_ = position + 1;
|
| + this->keyword_token_ = token_if_match;
|
| + return true;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + // If input equals match character, transition to new state and return true.
|
| + inline bool MatchState(uc32 input, char match, State new_state) {
|
| + if (input == match) {
|
| + state_ = new_state;
|
| + return true;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + inline bool MatchKeyword(uc32 input,
|
| + char match,
|
| + State new_state,
|
| + Token::Value keyword_token) {
|
| + if (input == match) { // Matched "do".
|
| + state_ = new_state;
|
| + token_ = keyword_token;
|
| + return true;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + void Step(uc32 input);
|
| +};
|
| +
|
| +
|
| class Scanner {
|
| public:
|
|
|
|
|