18Lexer::Lexer(Engine *engine,
const char *source,
unsigned size)
26 _variant(Variant_Mask & ~Variant_Reserved),
38 _yychar = (
unsigned char) *_it++;
43int Lexer::yylex(Token *tk)
45 const char *pos =
nullptr;
48 const int kind = yylex_helper(&pos, &line);
50 tk->position = pos - _source;
51 tk->length = _it - pos - 1;
62int Lexer::yylex_helper(
const char **position,
int *line)
66 while (std::isspace(_yychar))
73 return Parser::EOF_SYMBOL;
75 if (_state == State_comment) {
81 _state = State_normal;
88 return Parser::T_COMMENT;
91 const int ch = _yychar;
96 for (; _yychar; yyinp()) {
104 if (_yychar ==
'=') {
106 return Parser::T_NE_OP;
108 return Parser::T_BANG;
114 if (_yychar ==
'=') {
116 return Parser::T_MOD_ASSIGN;
118 return Parser::T_PERCENT;
125 if (_yychar ==
'=') {
127 return Parser::T_AND_ASSIGN;
128 }
else if (_yychar ==
'&') {
130 return Parser::T_AND_OP;
132 return Parser::T_AMPERSAND;
136 return Parser::T_LEFT_PAREN;
140 return Parser::T_RIGHT_PAREN;
146 if (_yychar ==
'=') {
148 return Parser::T_MUL_ASSIGN;
150 return Parser::T_STAR;
157 if (_yychar ==
'=') {
159 return Parser::T_ADD_ASSIGN;
160 }
else if (_yychar ==
'+') {
162 return Parser::T_INC_OP;
164 return Parser::T_PLUS;
168 return Parser::T_COMMA;
175 if (_yychar ==
'=') {
177 return Parser::T_SUB_ASSIGN;
178 }
else if (_yychar ==
'-') {
180 return Parser::T_DEC_OP;
182 return Parser::T_DASH;
188 if (std::isdigit(_yychar)) {
189 const char *word = _it - 2;
190 while (std::isalnum(_yychar)) {
194 _yyval.string = _engine->number(word, _it - word - 1);
195 return Parser::T_NUMBER;
197 return Parser::T_DOT;
204 if (_yychar ==
'/') {
205 for (; _yychar; yyinp()) {
210 return Parser::T_COMMENT;
212 }
else if (_yychar ==
'*') {
215 if (_yychar ==
'*') {
217 if (_yychar ==
'/') {
220 return Parser::T_COMMENT;
228 _state = State_comment;
229 return Parser::T_COMMENT;
232 }
else if (_yychar ==
'=') {
234 return Parser::T_DIV_ASSIGN;
236 return Parser::T_SLASH;
240 return Parser::T_COLON;
244 return Parser::T_SEMICOLON;
252 if (_yychar ==
'=') {
254 return Parser::T_LE_OP;
255 }
else if (_yychar ==
'<') {
257 if (_yychar ==
'=') {
259 return Parser::T_LEFT_ASSIGN;
261 return Parser::T_LEFT_OP;
263 return Parser::T_LEFT_ANGLE;
269 if (_yychar ==
'=') {
271 return Parser::T_EQ_OP;
273 return Parser::T_EQUAL;
281 if (_yychar ==
'=') {
283 return Parser::T_GE_OP;
284 }
else if (_yychar ==
'>') {
286 if (_yychar ==
'=') {
288 return Parser::T_RIGHT_ASSIGN;
290 return Parser::T_RIGHT_OP;
292 return Parser::T_RIGHT_ANGLE;
296 return Parser::T_QUESTION;
300 return Parser::T_LEFT_BRACKET;
304 return Parser::T_RIGHT_BRACKET;
310 if (_yychar ==
'=') {
312 return Parser::T_XOR_ASSIGN;
313 }
else if (_yychar ==
'^') {
315 return Parser::T_XOR_OP;
317 return Parser::T_CARET;
321 return Parser::T_LEFT_BRACE;
328 if (_yychar ==
'=') {
330 return Parser::T_OR_ASSIGN;
331 }
else if (_yychar ==
'|') {
333 return Parser::T_OR_OP;
335 return Parser::T_VERTICAL_BAR;
339 return Parser::T_RIGHT_BRACE;
343 return Parser::T_TILDE;
346 if (std::isalpha(ch) || ch ==
'_') {
347 const char *word = _it - 2;
348 while (std::isalnum(_yychar) || _yychar ==
'_') {
352 const int k = findKeyword(word, _it - word - 1);
354 if (k != Parser::T_IDENTIFIER)
358 _yyval.string = _engine->identifier(word, _it - word - 1);
359 return Parser::T_IDENTIFIER;
360 }
else if (std::isdigit(ch)) {
361 const char *word = _it - 2;
362 while (std::isalnum(_yychar) || _yychar ==
'.') {
366 _yyval.string = _engine->number(word, _it - word - 1);
367 return Parser::T_NUMBER;
372 return Parser::T_ERROR;
375int Lexer::findKeyword(
const char *word,
int length)
const
377 int t = classify(word, length);
378 if (!(t & Variant_Mask))
380 if ((_variant & t & Variant_Mask) == 0) {
385 return Parser::T_RESERVED;
387 return t & ~Variant_Mask;
390void Lexer::warning(
int line,
const QString &message)
392 _engine->warning(line, message);
395void Lexer::error(
int line,
const QString &message)
397 _engine->error(line, message);