e7aabc04ac96773fc0d166de679017fcffd2c37d
[WebKit-https.git] / JavaScriptCore / parser / Lexer.h
1 /*
2  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
4  *  Copyright (C) 2010 Zoltan Herczeg (zherczeg@inf.u-szeged.hu)
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Library General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Library General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Library General Public License
17  *  along with this library; see the file COPYING.LIB.  If not, write to
18  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  *  Boston, MA 02110-1301, USA.
20  *
21  */
22
23 #ifndef Lexer_h
24 #define Lexer_h
25
26 #include "Lookup.h"
27 #include "ParserArena.h"
28 #include "SourceCode.h"
29 #include <wtf/ASCIICType.h>
30 #include <wtf/AlwaysInline.h>
31 #include <wtf/SegmentedVector.h>
32 #include <wtf/Vector.h>
33 #include <wtf/unicode/Unicode.h>
34
35 namespace JSC {
36
37     class RegExp;
38
39     class Lexer : public Noncopyable {
40     public:
41         // Character manipulation functions.
42         static bool isWhiteSpace(int character);
43         static bool isLineTerminator(int character);
44         static unsigned char convertHex(int c1, int c2);
45         static UChar convertUnicode(int c1, int c2, int c3, int c4);
46
47         // Functions to set up parsing.
48         void setCode(const SourceCode&, ParserArena&);
49         void setIsReparsing() { m_isReparsing = true; }
50
51         // Functions for the parser itself.
52         int lex(void* lvalp, void* llocp);
53         int lineNumber() const { return m_lineNumber; }
54         void setLastLineNumber(int lastLineNumber) { m_lastLineNumber = lastLineNumber; }
55         int lastLineNumber() const { return m_lastLineNumber; }
56         bool prevTerminator() const { return m_terminator; }
57         SourceCode sourceCode(int openBrace, int closeBrace, int firstLine);
58         bool scanRegExp(const Identifier*& pattern, const Identifier*& flags, UChar patternPrefix = 0);
59         bool skipRegExp();
60
61         // Functions for use after parsing.
62         bool sawError() const { return m_error; }
63         void clear();
64
65     private:
66         friend class JSGlobalData;
67
68         Lexer(JSGlobalData*);
69         ~Lexer();
70
71         void record8(int);
72         void record16(int);
73         void record16(UChar);
74
75         void copyCodeWithoutBOMs();
76
77         ALWAYS_INLINE void shift();
78         ALWAYS_INLINE int peek(int offset);
79         int getUnicodeCharacter();
80         void shiftLineTerminator();
81
82         ALWAYS_INLINE const UChar* currentCharacter() const;
83         ALWAYS_INLINE int currentOffset() const;
84
85         ALWAYS_INLINE const Identifier* makeIdentifier(const UChar* characters, size_t length);
86
87         ALWAYS_INLINE bool lastTokenWasRestrKeyword() const;
88
89         ALWAYS_INLINE bool parseString(void* lvalp);
90
91         static const size_t initialReadBufferCapacity = 32;
92
93         int m_lineNumber;
94         int m_lastLineNumber;
95
96         Vector<char> m_buffer8;
97         Vector<UChar> m_buffer16;
98         bool m_terminator;
99         bool m_delimited; // encountered delimiter like "'" and "}" on last run
100         int m_lastToken;
101
102         const SourceCode* m_source;
103         const UChar* m_code;
104         const UChar* m_codeStart;
105         const UChar* m_codeEnd;
106         bool m_isReparsing;
107         bool m_atLineStart;
108         bool m_error;
109
110         // current and following unicode characters (int to allow for -1 for end-of-file marker)
111         int m_current;
112
113         IdentifierArena* m_arena;
114
115         JSGlobalData* m_globalData;
116
117         const HashTable m_keywordTable;
118
119         Vector<UChar> m_codeWithoutBOMs;
120     };
121
122     inline bool Lexer::isWhiteSpace(int ch)
123     {
124         return isASCII(ch) ? (ch == ' ' || ch == '\t' || ch == 0xB || ch == 0xC) : WTF::Unicode::isSeparatorSpace(ch);
125     }
126
127     inline bool Lexer::isLineTerminator(int ch)
128     {
129         return ch == '\r' || ch == '\n' || (ch & ~1) == 0x2028;
130     }
131
132     inline unsigned char Lexer::convertHex(int c1, int c2)
133     {
134         return (toASCIIHexValue(c1) << 4) | toASCIIHexValue(c2);
135     }
136
137     inline UChar Lexer::convertUnicode(int c1, int c2, int c3, int c4)
138     {
139         return (convertHex(c1, c2) << 8) | convertHex(c3, c4);
140     }
141
142     // A bridge for yacc from the C world to the C++ world.
143     inline int jscyylex(void* lvalp, void* llocp, void* globalData)
144     {
145         return static_cast<JSGlobalData*>(globalData)->lexer->lex(lvalp, llocp);
146     }
147
148 } // namespace JSC
149
150 #endif // Lexer_h