1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QQMLJSLEXER_P_H
41#define QQMLJSLEXER_P_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists purely as an
48// implementation detail. This header file may change from version to
49// version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include <private/qqmljsglobal_p.h>
55#include <private/qqmljsgrammar_p.h>
56
57#include <QtCore/qstring.h>
58#include <QtCore/qstack.h>
59
60QT_BEGIN_NAMESPACE
61
62namespace QQmlJS {
63
64class Engine;
65struct DiagnosticMessage;
66class Directives;
67
68class QML_PARSER_EXPORT Lexer: public QQmlJSGrammar
69{
70public:
71 enum {
72 T_ABSTRACT = T_RESERVED_WORD,
73 T_BOOLEAN = T_RESERVED_WORD,
74 T_BYTE = T_RESERVED_WORD,
75 T_CHAR = T_RESERVED_WORD,
76 T_DOUBLE = T_RESERVED_WORD,
77 T_FINAL = T_RESERVED_WORD,
78 T_FLOAT = T_RESERVED_WORD,
79 T_GOTO = T_RESERVED_WORD,
80 T_IMPLEMENTS = T_RESERVED_WORD,
81 T_INT = T_RESERVED_WORD,
82 T_INTERFACE = T_RESERVED_WORD,
83 T_LONG = T_RESERVED_WORD,
84 T_NATIVE = T_RESERVED_WORD,
85 T_PACKAGE = T_RESERVED_WORD,
86 T_PRIVATE = T_RESERVED_WORD,
87 T_PROTECTED = T_RESERVED_WORD,
88 T_SHORT = T_RESERVED_WORD,
89 T_SYNCHRONIZED = T_RESERVED_WORD,
90 T_THROWS = T_RESERVED_WORD,
91 T_TRANSIENT = T_RESERVED_WORD,
92 T_VOLATILE = T_RESERVED_WORD
93 };
94
95 enum Error {
96 NoError,
97 IllegalCharacter,
98 IllegalNumber,
99 UnclosedStringLiteral,
100 IllegalEscapeSequence,
101 IllegalUnicodeEscapeSequence,
102 UnclosedComment,
103 IllegalExponentIndicator,
104 IllegalIdentifier,
105 IllegalHexadecimalEscapeSequence
106 };
107
108 enum RegExpBodyPrefix {
109 NoPrefix,
110 EqualPrefix
111 };
112
113 enum RegExpFlag {
114 RegExp_Global = 0x01,
115 RegExp_IgnoreCase = 0x02,
116 RegExp_Multiline = 0x04,
117 RegExp_Unicode = 0x08,
118 RegExp_Sticky = 0x10
119 };
120
121 enum ParseModeFlags {
122 QmlMode = 0x1,
123 YieldIsKeyword = 0x2,
124 StaticIsKeyword = 0x4
125 };
126
127 enum class ImportState {
128 SawImport,
129 NoQmlImport
130 };
131
132public:
133 Lexer(Engine *engine);
134
135 int parseModeFlags() const {
136 int flags = 0;
137 if (qmlMode())
138 flags |= QmlMode|StaticIsKeyword;
139 if (yieldIsKeyWord())
140 flags |= YieldIsKeyword;
141 if (_staticIsKeyword)
142 flags |= StaticIsKeyword;
143 return flags;
144 }
145
146 bool qmlMode() const;
147 bool yieldIsKeyWord() const { return _generatorLevel != 0; }
148 void setStaticIsKeyword(bool b) { _staticIsKeyword = b; }
149
150 QString code() const;
151 void setCode(const QString &code, int lineno, bool qmlMode = true);
152
153 int lex();
154
155 bool scanRegExp(RegExpBodyPrefix prefix = NoPrefix);
156 bool scanDirectives(Directives *directives, DiagnosticMessage *error);
157
158 int regExpFlags() const { return _patternFlags; }
159 QString regExpPattern() const { return _tokenText; }
160
161 int tokenKind() const { return _tokenKind; }
162 int tokenOffset() const { return _tokenStartPtr - _code.unicode(); }
163 int tokenLength() const { return _tokenLength; }
164
165 int tokenStartLine() const { return _tokenLine; }
166 int tokenStartColumn() const { return _tokenColumn; }
167
168 inline QStringRef tokenSpell() const { return _tokenSpell; }
169 inline QStringRef rawString() const { return _rawString; }
170 double tokenValue() const { return _tokenValue; }
171 QString tokenText() const;
172
173 Error errorCode() const;
174 QString errorMessage() const;
175
176 bool prevTerminator() const;
177 bool followsClosingBrace() const;
178 bool canInsertAutomaticSemicolon(int token) const;
179
180 enum ParenthesesState {
181 IgnoreParentheses,
182 CountParentheses,
183 BalancedParentheses
184 };
185
186 void enterGeneratorBody() { ++_generatorLevel; }
187 void leaveGeneratorBody() { --_generatorLevel; }
188
189protected:
190 static int classify(const QChar *s, int n, int parseModeFlags);
191
192private:
193 inline void scanChar();
194 int scanToken();
195 int scanNumber(QChar ch);
196 int scanVersionNumber(QChar ch);
197 enum ScanStringMode {
198 SingleQuote = '\'',
199 DoubleQuote = '"',
200 TemplateHead = '`',
201 TemplateContinuation = 0
202 };
203 int scanString(ScanStringMode mode);
204
205 bool isLineTerminator() const;
206 unsigned isLineTerminatorSequence() const;
207 static bool isIdentLetter(QChar c);
208 static bool isDecimalDigit(ushort c);
209 static bool isHexDigit(QChar c);
210 static bool isOctalDigit(ushort c);
211
212 void syncProhibitAutomaticSemicolon();
213 uint decodeUnicodeEscapeCharacter(bool *ok);
214 QChar decodeHexEscapeCharacter(bool *ok);
215
216private:
217 Engine *_engine;
218
219 QString _code;
220 QString _tokenText;
221 QString _errorMessage;
222 QStringRef _tokenSpell;
223 QStringRef _rawString;
224
225 const QChar *_codePtr;
226 const QChar *_endPtr;
227 const QChar *_tokenStartPtr;
228
229 QChar _char;
230 Error _errorCode;
231
232 int _currentLineNumber;
233 int _currentColumnNumber;
234 double _tokenValue;
235
236 // parentheses state
237 ParenthesesState _parenthesesState;
238 int _parenthesesCount;
239
240 // template string stack
241 QStack<int> _outerTemplateBraceCount;
242 int _bracesCount = -1;
243
244 int _stackToken;
245
246 int _patternFlags;
247 int _tokenKind;
248 int _tokenLength;
249 int _tokenLine;
250 int _tokenColumn;
251 ImportState _importState = ImportState::NoQmlImport;
252
253 bool _validTokenText;
254 bool _prohibitAutomaticSemicolon;
255 bool _restrictedKeyword;
256 bool _terminator;
257 bool _followsClosingBrace;
258 bool _delimited;
259 bool _qmlMode;
260 bool _skipLinefeed = false;
261 int _generatorLevel = 0;
262 bool _staticIsKeyword = false;
263 bool _handlingDirectives = false;
264};
265
266} // end of namespace QQmlJS
267
268QT_END_NAMESPACE
269
270#endif // LEXER_H
271

source code of qtdeclarative/src/qml/parser/qqmljslexer_p.h