16Lexer::Lexer(Engine *engine,
const char *source,
unsigned size)
24 _variant(Variant_Mask & ~Variant_Reserved),
36 _yychar = (
unsigned char) *_it++;
41int Lexer::yylex(Token *tk)
43 const char *pos =
nullptr;
46 const int kind = yylex_helper(&pos, &line);
48 tk->position = pos - _source;
49 tk->length = _it - pos - 1;
60int Lexer::yylex_helper(
const char **position,
int *line)
64 while (std::isspace(_yychar))
71 return Parser::EOF_SYMBOL;
73 if (_state == State_comment) {
79 _state = State_normal;
86 return Parser::T_COMMENT;
89 const int ch = _yychar;
94 for (; _yychar; yyinp()) {
102 if (_yychar ==
'=') {
104 return Parser::T_NE_OP;
106 return Parser::T_BANG;
112 if (_yychar ==
'=') {
114 return Parser::T_MOD_ASSIGN;
116 return Parser::T_PERCENT;
123 if (_yychar ==
'=') {
125 return Parser::T_AND_ASSIGN;
126 }
else if (_yychar ==
'&') {
128 return Parser::T_AND_OP;
130 return Parser::T_AMPERSAND;
134 return Parser::T_LEFT_PAREN;
138 return Parser::T_RIGHT_PAREN;
144 if (_yychar ==
'=') {
146 return Parser::T_MUL_ASSIGN;
148 return Parser::T_STAR;
155 if (_yychar ==
'=') {
157 return Parser::T_ADD_ASSIGN;
158 }
else if (_yychar ==
'+') {
160 return Parser::T_INC_OP;
162 return Parser::T_PLUS;
166 return Parser::T_COMMA;
173 if (_yychar ==
'=') {
175 return Parser::T_SUB_ASSIGN;
176 }
else if (_yychar ==
'-') {
178 return Parser::T_DEC_OP;
180 return Parser::T_DASH;
186 if (std::isdigit(_yychar)) {
187 const char *word = _it - 2;
188 while (std::isalnum(_yychar)) {
192 _yyval.string = _engine->number(word, _it - word - 1);
193 return Parser::T_NUMBER;
195 return Parser::T_DOT;
202 if (_yychar ==
'/') {
203 for (; _yychar; yyinp()) {
208 return Parser::T_COMMENT;
210 }
else if (_yychar ==
'*') {
213 if (_yychar ==
'*') {
215 if (_yychar ==
'/') {
218 return Parser::T_COMMENT;
226 _state = State_comment;
227 return Parser::T_COMMENT;
230 }
else if (_yychar ==
'=') {
232 return Parser::T_DIV_ASSIGN;
234 return Parser::T_SLASH;
238 return Parser::T_COLON;
242 return Parser::T_SEMICOLON;
250 if (_yychar ==
'=') {
252 return Parser::T_LE_OP;
253 }
else if (_yychar ==
'<') {
255 if (_yychar ==
'=') {
257 return Parser::T_LEFT_ASSIGN;
259 return Parser::T_LEFT_OP;
261 return Parser::T_LEFT_ANGLE;
267 if (_yychar ==
'=') {
269 return Parser::T_EQ_OP;
271 return Parser::T_EQUAL;
279 if (_yychar ==
'=') {
281 return Parser::T_GE_OP;
282 }
else if (_yychar ==
'>') {
284 if (_yychar ==
'=') {
286 return Parser::T_RIGHT_ASSIGN;
288 return Parser::T_RIGHT_OP;
290 return Parser::T_RIGHT_ANGLE;
294 return Parser::T_QUESTION;
298 return Parser::T_LEFT_BRACKET;
302 return Parser::T_RIGHT_BRACKET;
308 if (_yychar ==
'=') {
310 return Parser::T_XOR_ASSIGN;
311 }
else if (_yychar ==
'^') {
313 return Parser::T_XOR_OP;
315 return Parser::T_CARET;
319 return Parser::T_LEFT_BRACE;
326 if (_yychar ==
'=') {
328 return Parser::T_OR_ASSIGN;
329 }
else if (_yychar ==
'|') {
331 return Parser::T_OR_OP;
333 return Parser::T_VERTICAL_BAR;
337 return Parser::T_RIGHT_BRACE;
341 return Parser::T_TILDE;
344 if (std::isalpha(ch) || ch ==
'_') {
345 const char *word = _it - 2;
346 while (std::isalnum(_yychar) || _yychar ==
'_') {
350 const int k = findKeyword(word, _it - word - 1);
352 if (k != Parser::T_IDENTIFIER)
356 _yyval.string = _engine->identifier(word, _it - word - 1);
357 return Parser::T_IDENTIFIER;
358 }
else if (std::isdigit(ch)) {
359 const char *word = _it - 2;
360 while (std::isalnum(_yychar) || _yychar ==
'.') {
364 _yyval.string = _engine->number(word, _it - word - 1);
365 return Parser::T_NUMBER;
370 return Parser::T_ERROR;
373int Lexer::findKeyword(
const char *word,
int length)
const
375 int t = classify(word, length);
376 if (!(t & Variant_Mask))
378 if ((_variant & t & Variant_Mask) == 0) {
383 return Parser::T_RESERVED;
385 return t & ~Variant_Mask;
388void Lexer::warning(
int line,
const QString &message)
390 _engine->warning(line, message);
393void Lexer::error(
int line,
const QString &message)
395 _engine->error(line, message);