00001
00019
00020 #ifndef NET_INSTAWEB_JS_PUBLIC_JS_LEXER_H_
00021 #define NET_INSTAWEB_JS_PUBLIC_JS_LEXER_H_
00022
00023 #include "net/instaweb/js/public/js_keywords.h"
00024 #include "net/instaweb/util/public/string_util.h"
00025
00026 namespace net_instaweb {
00027
00029 class JsLexer {
00030 public:
00031 JsLexer();
00032 void Lex(const StringPiece& contents);
00033 const char* keyword_string(JsKeywords::Type keyword) {
00034 return keyword_vector_[static_cast<int>(keyword)];
00035 }
00036
00038 JsKeywords::Type NextToken(StringPiece* token);
00039
00041 bool error() const { return error_; }
00042
00043 private:
00046 typedef bool (JsLexer::*LexicalPredicate)(uint8 ch, int index);
00047
00048 JsKeywords::Type IdentifierOrKeyword(const StringPiece& name);
00049 JsKeywords::Type NumberOrDot(const StringPiece& number_or_dot);
00050
00062 void Consume(LexicalPredicate predicate,
00063 bool include_last_char,
00064 bool ok_to_terminate_with_eof,
00065 StringPiece* token);
00066
00067 bool IsSpace(uint8 ch, int index);
00068 bool IsLineSeparator(uint8 ch, int index);
00069 bool IsNumber(uint8 ch, int index);
00070 bool InBlockComment(uint8 ch, int index);
00071 bool InSingleLineComment(uint8 ch, int index);
00072 bool InIdentifier(uint8 ch, int index);
00073 bool InOperator(uint8 ch, int index);
00074 bool InString(uint8 ch, int index);
00075 bool InRegex(uint8 ch, int index);
00076
00078 bool IdentifierStart(uint8 ch);
00079
00083 bool ProcessBackslash(uint8 ch);
00084
00085 JsKeywords::Type ConsumeSlash(StringPiece* token);
00086
00087 StringPiece input_;
00088 int index_;
00089 int prev_char_;
00090 int token_start_;
00091 int token_start_index_;
00092 int dot_count_;
00093 bool error_;
00094 bool backslash_mode_;
00095 bool last_token_may_end_value_;
00096 bool within_brackets_;
00097 bool seen_a_dot_;
00098
00099 CharStarVector keyword_vector_;
00100
00101 DISALLOW_COPY_AND_ASSIGN(JsLexer);
00102 };
00103
00104 }
00105
00106 #endif ///< NET_INSTAWEB_JS_PUBLIC_JS_LEXER_H_