diff generator/parser/lexer.cpp @ 1:e78566595089

initial import
author mandel
date Mon, 11 May 2009 16:01:50 +0000
parents
children 09a0f1d048f2
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/generator/parser/lexer.cpp	Mon May 11 16:01:50 2009 +0000
@@ -0,0 +1,1886 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Nokia. All rights reserved.
+** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
+**
+** This file is part of Qt Jambi.
+**
+** * Commercial Usage
+* Licensees holding valid Qt Commercial licenses may use this file in
+* accordance with the Qt Commercial License Agreement provided with the
+* Software or, alternatively, in accordance with the terms contained in
+* a written agreement between you and Nokia.
+*
+*
+* GNU General Public License Usage
+* Alternatively, this file may be used under the terms of the GNU
+* General Public License versions 2.0 or 3.0 as published by the Free
+* Software Foundation and appearing in the file LICENSE.GPL included in
+* the packaging of this file.  Please review the following information
+* to ensure GNU General Public Licensing requirements will be met:
+* http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+* http://www.gnu.org/copyleft/gpl.html.  In addition, as a special
+* exception, Nokia gives you certain additional rights. These rights
+* are described in the Nokia Qt GPL Exception version 1.2, included in
+* the file GPL_EXCEPTION.txt in this package.
+* 
+* Qt for Windows(R) Licensees
+* As a special exception, Nokia, as the sole copyright holder for Qt
+* Designer, grants users of the Qt/Eclipse Integration plug-in the
+* right for the Qt/Eclipse Integration to link to functionality
+* provided by Qt Designer and its related libraries.
+*
+*
+* If you are unsure which license is appropriate for your use, please
+* contact the sales department at qt-sales@nokia.com.
+
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+
+#include "lexer.h"
+#include "tokens.h"
+#include "control.h"
+
+#include <cctype>
+#include <iostream>
+
+scan_fun_ptr Lexer::s_scan_keyword_table[] = {
+  &Lexer::scanKeyword0, &Lexer::scanKeyword0,
+  &Lexer::scanKeyword2, &Lexer::scanKeyword3,
+  &Lexer::scanKeyword4, &Lexer::scanKeyword5,
+  &Lexer::scanKeyword6, &Lexer::scanKeyword7,
+  &Lexer::scanKeyword8, &Lexer::scanKeyword9,
+  &Lexer::scanKeyword10, &Lexer::scanKeyword11,
+  &Lexer::scanKeyword12, &Lexer::scanKeyword13,
+  &Lexer::scanKeyword14, &Lexer::scanKeyword0,
+  &Lexer::scanKeyword16
+};
+
+void LocationManager::extract_line(int offset, int *line, QString *filename) const
+{
+  *line = 0;
+  if (token_stream.size () < 1)
+    return;
+
+  const unsigned char *begin_buffer = reinterpret_cast<const unsigned char *>(token_stream[0].text);
+  const unsigned char *cursor = begin_buffer + offset;
+
+  ++cursor; // skip '#'
+  if (std::isspace(*cursor) && std::isdigit(*(cursor + 1)))
+    {
+      ++cursor;
+      char buffer[1024], *cp = buffer;
+      do {
+        *cp++ = *cursor++;
+      } while (std::isdigit(*cursor));
+      *cp = '\0';
+      int l = strtol(buffer, 0, 0);
+
+      Q_ASSERT(std::isspace(*cursor));
+      ++cursor;
+
+      Q_ASSERT(*cursor == '"');
+      ++cursor;
+
+      cp = buffer;
+      while (*cursor && *cursor != '"') {
+        *cp++ = *cursor++;
+      }
+      *cp = '\0';
+      Q_ASSERT(*cursor == '"');
+      ++cursor;
+
+      *filename = buffer;
+      *line = l;
+      // printf("filename: %s line: %d\n", buffer, line);
+    }
+}
+
+void LocationManager::positionAt(std::size_t offset, int *line, int *column,
+                                 QString *filename) const
+{
+  int ppline, ppcolumn;
+  line_table.positionAt(offset, &ppline, &ppcolumn);
+
+  int base_line;
+  extract_line((int) line_table[ppline-1], &base_line, filename);
+
+  int line2, column2;
+  location_table.positionAt((int) line_table[ppline-1], &line2, &column2);
+
+  location_table.positionAt(offset, line, column);
+  *line = base_line + *line - line2  - 1;
+}
+
+scan_fun_ptr Lexer::s_scan_table[256];
+bool Lexer::s_initialized = false;
+
+void Lexer::tokenize(const char *contents, std::size_t size)
+{
+  if (!s_initialized)
+    initialize_scan_table();
+
+  token_stream.resize(1024);
+  token_stream[0].kind = Token_EOF;
+  token_stream[0].text = contents;
+
+  index = 1;
+
+  cursor = (const unsigned char *) contents;
+  begin_buffer = (const unsigned char *) contents;
+  end_buffer = cursor + size;
+
+  location_table.resize(1024);
+  location_table[0] = 0;
+  location_table.current_line = 1;
+
+  line_table.resize(1024);
+  line_table[0] = 0;
+  line_table.current_line = 1;
+
+  do {
+    if (index == token_stream.size())
+      token_stream.resize(token_stream.size() * 2);
+
+    Token *current_token = &token_stream[(int) index];
+    current_token->text = reinterpret_cast<const char*>(begin_buffer);
+    current_token->position = cursor - begin_buffer;
+    (this->*s_scan_table[*cursor])();
+    current_token->size = cursor - begin_buffer - current_token->position;
+  } while (cursor < end_buffer);
+
+  if (index == token_stream.size())
+      token_stream.resize(token_stream.size() * 2);
+
+  Q_ASSERT(index < token_stream.size());
+  token_stream[(int) index].position = cursor - begin_buffer;
+  token_stream[(int) index].kind = Token_EOF;
+}
+
+void Lexer::reportError(const QString& msg)
+{
+    int line, column;
+    QString fileName;
+
+    std::size_t tok = token_stream.cursor();
+    _M_location.positionAt(token_stream.position(tok),
+        &line, &column, &fileName);
+
+    Control::ErrorMessage errmsg;
+    errmsg.setLine(line + 1);
+    errmsg.setColumn(column);
+    errmsg.setFileName(fileName);
+    errmsg.setMessage(QLatin1String("** LEXER ERROR ") + msg);
+    control->reportError(errmsg);
+}
+
+void Lexer::initialize_scan_table()
+{
+  s_initialized = true;
+
+  for (int i=0; i<256; ++i)
+    {
+      if (isspace(i))
+    s_scan_table[i] = &Lexer::scan_white_spaces;
+      else if (isalpha(i) || i == '_')
+    s_scan_table[i] = &Lexer::scan_identifier_or_keyword;
+      else if (isdigit(i))
+    s_scan_table[i] = &Lexer::scan_int_constant;
+      else
+    s_scan_table[i] = &Lexer::scan_invalid_input;
+    }
+
+  s_scan_table[int('L')] = &Lexer::scan_identifier_or_literal;
+  s_scan_table[int('\n')] = &Lexer::scan_newline;
+  s_scan_table[int('#')] = &Lexer::scan_preprocessor;
+
+  s_scan_table[int('\'')] = &Lexer::scan_char_constant;
+  s_scan_table[int('"')]  = &Lexer::scan_string_constant;
+
+  s_scan_table[int('.')] = &Lexer::scan_int_constant;
+
+  s_scan_table[int('!')] = &Lexer::scan_not;
+  s_scan_table[int('%')] = &Lexer::scan_remainder;
+  s_scan_table[int('&')] = &Lexer::scan_and;
+  s_scan_table[int('(')] = &Lexer::scan_left_paren;
+  s_scan_table[int(')')] = &Lexer::scan_right_paren;
+  s_scan_table[int('*')] = &Lexer::scan_star;
+  s_scan_table[int('+')] = &Lexer::scan_plus;
+  s_scan_table[int(',')] = &Lexer::scan_comma;
+  s_scan_table[int('-')] = &Lexer::scan_minus;
+  s_scan_table[int('/')] = &Lexer::scan_divide;
+  s_scan_table[int(':')] = &Lexer::scan_colon;
+  s_scan_table[int(';')] = &Lexer::scan_semicolon;
+  s_scan_table[int('<')] = &Lexer::scan_less;
+  s_scan_table[int('=')] = &Lexer::scan_equal;
+  s_scan_table[int('>')] = &Lexer::scan_greater;
+  s_scan_table[int('?')] = &Lexer::scan_question;
+  s_scan_table[int('[')] = &Lexer::scan_left_bracket;
+  s_scan_table[int(']')] = &Lexer::scan_right_bracket;
+  s_scan_table[int('^')] = &Lexer::scan_xor;
+  s_scan_table[int('{')] = &Lexer::scan_left_brace;
+  s_scan_table[int('|')] = &Lexer::scan_or;
+  s_scan_table[int('}')] = &Lexer::scan_right_brace;
+  s_scan_table[int('~')] = &Lexer::scan_tilde;
+
+  s_scan_table[0] = &Lexer::scan_EOF;
+}
+
+void Lexer::scan_preprocessor()
+{
+  if (line_table.current_line == line_table.size())
+    line_table.resize(line_table.current_line * 2);
+
+  line_table[(int) line_table.current_line++] = (cursor - begin_buffer);
+
+  while (*cursor && *cursor != '\n')
+    ++cursor;
+
+  if (*cursor != '\n')
+      reportError("expected newline");
+}
+
+void Lexer::scan_char_constant()
+{
+  const unsigned char *begin = cursor;
+
+  ++cursor;
+  while (*cursor && *cursor != '\'')
+    {
+      if (*cursor == '\n')
+        reportError("did not expect newline");
+
+      if (*cursor == '\\')
+    ++cursor;
+      ++cursor;
+    }
+
+    if (*cursor != '\'')
+      reportError("expected \'");
+
+  ++cursor;
+
+  token_stream[(int) index].extra.symbol =
+    control->findOrInsertName((const char*) begin, cursor - begin);
+
+  token_stream[(int) index++].kind = Token_char_literal;
+}
+
+void Lexer::scan_string_constant()
+{
+  const unsigned char *begin = cursor;
+
+  ++cursor;
+  while (*cursor && *cursor != '"')
+    {
+      if (*cursor == '\n')
+        reportError("did not expect newline");
+
+      if (*cursor == '\\')
+    ++cursor;
+      ++cursor;
+    }
+
+  if (*cursor != '"')
+    reportError("expected \"");
+
+  ++cursor;
+
+  token_stream[(int) index].extra.symbol =
+    control->findOrInsertName((const char*) begin, cursor - begin);
+
+  token_stream[(int) index++].kind = Token_string_literal;
+}
+
+void Lexer::scan_newline()
+{
+  if (location_table.current_line == location_table.size())
+    location_table.resize(location_table.current_line * 2);
+
+  location_table[(int) location_table.current_line++] = (cursor - begin_buffer);
+  ++cursor;
+}
+
+void Lexer::scan_white_spaces()
+{
+  while (isspace(*cursor))
+    {
+      if (*cursor == '\n')
+    scan_newline();
+      else
+    ++cursor;
+    }
+}
+
+void Lexer::scan_identifier_or_literal()
+{
+  switch (*(cursor + 1))
+    {
+    case '\'':
+      ++cursor;
+      scan_char_constant();
+      break;
+
+    case '\"':
+      ++cursor;
+      scan_string_constant();
+      break;
+
+    default:
+      scan_identifier_or_keyword();
+      break;
+    }
+}
+
+void Lexer::scan_identifier_or_keyword()
+{
+  const unsigned char *skip = cursor;
+  while (isalnum(*skip) || *skip== '_')
+    ++skip;
+
+  int n = skip - cursor;
+  Token *current_token = &token_stream[(int) index];
+  (this->*s_scan_keyword_table[n < 17 ? n : 0])();
+
+  if (current_token->kind == Token_identifier)
+    {
+      current_token->extra.symbol =
+    control->findOrInsertName((const char*) cursor, n);
+    }
+
+  cursor = skip;
+}
+
+void Lexer::scan_int_constant()
+{
+  if (*cursor == '.' && !std::isdigit(*(cursor + 1)))
+    {
+      scan_dot();
+      return;
+    }
+
+  const unsigned char *begin = cursor;
+
+  while (isalnum(*cursor) || *cursor == '.')
+    ++cursor;
+
+  token_stream[(int) index].extra.symbol =
+    control->findOrInsertName((const char*) begin, cursor - begin);
+
+  token_stream[(int) index++].kind = Token_number_literal;
+}
+
+void Lexer::scan_not()
+{
+  /*
+    '!'     ::= not
+    '!='        ::= not_equal
+  */
+
+  ++cursor;
+
+  if (*cursor == '=')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_not_eq;
+    }
+  else
+    {
+      token_stream[(int) index++].kind = '!';
+    }
+}
+
+void Lexer::scan_remainder()
+{
+  /*
+    '%'     ::= remainder
+    '%='        ::= remainder_equal
+  */
+
+  ++cursor;
+
+  if (*cursor == '=')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_assign;
+    }
+  else
+    {
+      token_stream[(int) index++].kind = '%';
+    }
+}
+
+void Lexer::scan_and()
+{
+  /*
+    '&&'        ::= and_and
+    '&'     ::= and
+    '&='        ::= and_equal
+  */
+
+  ++cursor;
+  if (*cursor == '=')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_assign;
+    }
+  else if (*cursor == '&')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_and;
+    }
+  else
+    {
+      token_stream[(int) index++].kind = '&';
+    }
+}
+
+void Lexer::scan_left_paren()
+{
+  ++cursor;
+  token_stream[(int) index++].kind = '(';
+}
+
+void Lexer::scan_right_paren()
+{
+  ++cursor;
+  token_stream[(int) index++].kind = ')';
+}
+
+void Lexer::scan_star()
+{
+  /*
+    '*'     ::= star
+    '*='        ::= star_equal
+  */
+
+  ++cursor;
+
+  if (*cursor == '=')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_assign;
+    }
+  else
+    {
+      token_stream[(int) index++].kind = '*';
+    }
+}
+
+void Lexer::scan_plus()
+{
+  /*
+    '+'     ::= plus
+    '++'        ::= incr
+    '+='        ::= plus_equal
+  */
+
+  ++cursor;
+  if (*cursor == '=')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_assign;
+    }
+  else if (*cursor == '+')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_incr;
+    }
+  else
+    {
+      token_stream[(int) index++].kind = '+';
+    }
+}
+
+void Lexer::scan_comma()
+{
+  ++cursor;
+  token_stream[(int) index++].kind = ',';
+}
+
+void Lexer::scan_minus()
+{
+  /*
+    '-'     ::= minus
+    '--'        ::= decr
+    '-='        ::= minus_equal
+    '->'        ::= left_arrow
+  */
+
+  ++cursor;
+  if (*cursor == '=')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_assign;
+    }
+  else if (*cursor == '-')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_decr;
+    }
+  else if (*cursor == '>')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_arrow;
+      if (*cursor == '*')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_ptrmem;
+    }
+    }
+  else
+    {
+      token_stream[(int) index++].kind = '-';
+    }
+}
+
+void Lexer::scan_dot()
+{
+  /*
+    '.'     ::= dot
+    '...'       ::= ellipsis
+  */
+
+  ++cursor;
+  if (*cursor == '.' && *(cursor + 1) == '.')
+    {
+      cursor += 2;
+      token_stream[(int) index++].kind = Token_ellipsis;
+    }
+  else if (*cursor == '.' && *(cursor + 1) == '*')
+    {
+      cursor += 2;
+      token_stream[(int) index++].kind = Token_ptrmem;
+    }
+  else
+    token_stream[(int) index++].kind = '.';
+}
+
+void Lexer::scan_divide()
+{
+  /*
+    '/'     ::= divide
+    '/='    ::= divide_equal
+  */
+
+  ++cursor;
+
+  if (*cursor == '=')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_assign;
+    }
+  else
+    {
+      token_stream[(int) index++].kind = '/';
+    }
+}
+
+void Lexer::scan_colon()
+{
+  ++cursor;
+  if (*cursor == ':')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_scope;
+    }
+  else
+    {
+      token_stream[(int) index++].kind = ':';
+    }
+}
+
+void Lexer::scan_semicolon()
+{
+  ++cursor;
+  token_stream[(int) index++].kind = ';';
+}
+
+void Lexer::scan_less()
+{
+  /*
+    '<'         ::= less
+    '<<'        ::= left_shift
+    '<<='       ::= left_shift_equal
+    '<='        ::= less_equal
+  */
+
+  ++cursor;
+  if (*cursor == '=')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_leq;
+    }
+  else if (*cursor == '<')
+    {
+      ++cursor;
+      if (*cursor == '=')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_assign;
+    }
+      else
+    {
+      token_stream[(int) index++].kind = Token_shift;
+    }
+    }
+  else
+    {
+      token_stream[(int) index++].kind = '<';
+    }
+}
+
+void Lexer::scan_equal()
+{
+  /*
+    '='         ::= equal
+    '=='        ::= equal_equal
+  */
+  ++cursor;
+
+  if (*cursor == '=')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_eq;
+    }
+  else
+    {
+      token_stream[(int) index++].kind = '=';
+    }
+}
+
+void Lexer::scan_greater()
+{
+  /*
+    '>'         ::= greater
+    '>='        ::= greater_equal
+    '>>'        ::= right_shift
+    '>>='       ::= right_shift_equal
+  */
+
+  ++cursor;
+  if (*cursor == '=')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_geq;
+    }
+  else if (*cursor == '>')
+    {
+      ++cursor;
+      if (*cursor == '=')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_assign;
+    }
+      else
+    {
+      token_stream[(int) index++].kind = Token_shift;
+    }
+    }
+  else
+    {
+      token_stream[(int) index++].kind = '>';
+    }
+}
+
+void Lexer::scan_question()
+{
+  ++cursor;
+  token_stream[(int) index++].kind = '?';
+}
+
+void Lexer::scan_left_bracket()
+{
+  ++cursor;
+  token_stream[(int) index++].kind = '[';
+}
+
+void Lexer::scan_right_bracket()
+{
+  ++cursor;
+  token_stream[(int) index++].kind = ']';
+}
+
+void Lexer::scan_xor()
+{
+  /*
+    '^'         ::= xor
+    '^='        ::= xor_equal
+  */
+  ++cursor;
+
+  if (*cursor == '=')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_assign;
+    }
+  else
+    {
+      token_stream[(int) index++].kind = '^';
+    }
+}
+
+void Lexer::scan_left_brace()
+{
+  ++cursor;
+  token_stream[(int) index++].kind = '{';
+}
+
+void Lexer::scan_or()
+{
+  /*
+    '|'         ::= or
+    '|='        ::= or_equal
+    '||'        ::= or_or
+  */
+  ++cursor;
+  if (*cursor == '=')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_assign;
+    }
+  else if (*cursor == '|')
+    {
+      ++cursor;
+      token_stream[(int) index++].kind = Token_or;
+    }
+  else
+    {
+    token_stream[(int) index++].kind = '|';
+  }
+}
+
+void Lexer::scan_right_brace()
+{
+  ++cursor;
+  token_stream[(int) index++].kind = '}';
+}
+
+void Lexer::scan_tilde()
+{
+  ++cursor;
+  token_stream[(int) index++].kind = '~';
+}
+
+void Lexer::scan_EOF()
+{
+  ++cursor;
+  token_stream[(int) index++].kind = Token_EOF;
+}
+
+void Lexer::scan_invalid_input()
+{
+  QString errmsg("invalid input: %1");
+  errmsg.arg(int(*cursor));
+  reportError(errmsg);
+  ++cursor;
+}
+
+void LocationTable::positionAt(std::size_t offset, int max_line,
+                   int *line, int *column) const
+{
+  if (!(line && column && max_line != 0))
+    return;
+
+  int first = 0;
+  int len = max_line;
+  int half;
+  int middle;
+
+  while (len > 0)
+    {
+      half = len >> 1;
+      middle = first;
+
+      middle += half;
+
+      if (lines[middle] < offset)
+    {
+      first = middle;
+      ++first;
+      len = len - half - 1;
+    }
+      else
+    len = half;
+    }
+
+  *line = std::max(first, 1);
+  *column = (int) (offset - lines[*line - 1] - 1);
+
+  if (*column < 0)
+    {
+      *column = 0;
+    }
+}
+
+void Lexer::scanKeyword0()
+{
+  token_stream[(int) index++].kind = Token_identifier;
+}
+
+void Lexer::scanKeyword2()
+{
+  switch (*cursor)
+    {
+    case 'i':
+      if (*(cursor + 1) == 'f')
+    {
+      token_stream[(int) index++].kind = Token_if;
+      return;
+    }
+      break;
+
+    case 'd':
+      if (*(cursor + 1) == 'o')
+    {
+      token_stream[(int) index++].kind = Token_do;
+      return;
+    }
+      break;
+
+    case 'o':
+      if (*(cursor + 1) == 'r')
+    {
+      token_stream[(int) index++].kind = Token_or;
+      return;
+    }
+      break;
+
+    }
+  token_stream[(int) index++].kind = Token_identifier;
+}
+
+void Lexer::scanKeyword3()
+{
+  switch (*cursor)
+    {
+    case 'a':
+      if (*(cursor + 1) == 'n' &&
+      *(cursor + 2) == 'd')
+    {
+      token_stream[(int) index++].kind = Token_and;
+      return;
+    }
+      if (*(cursor + 1) == 's' &&
+      *(cursor + 2) == 'm')
+    {
+      token_stream[(int) index++].kind = Token_asm;
+      return;
+    }
+      break;
+
+    case 'f':
+      if (*(cursor + 1) == 'o' &&
+      *(cursor + 2) == 'r')
+    {
+      token_stream[(int) index++].kind = Token_for;
+      return;
+    }
+      break;
+
+    case 'i':
+      if (*(cursor + 1) == 'n' &&
+      *(cursor + 2) == 't')
+    {
+      token_stream[(int) index++].kind = Token_int;
+      return;
+    }
+      break;
+
+    case 'n':
+      if (*(cursor + 1) == 'e' &&
+      *(cursor + 2) == 'w')
+    {
+      token_stream[(int) index++].kind = Token_new;
+      return;
+    }
+      if (*(cursor + 1) == 'o' &&
+      *(cursor + 2) == 't')
+    {
+      token_stream[(int) index++].kind = Token_not;
+      return;
+    }
+      break;
+
+    case 't':
+      if (*(cursor + 1) == 'r' &&
+      *(cursor + 2) == 'y')
+    {
+      token_stream[(int) index++].kind = Token_try;
+      return;
+    }
+      break;
+
+    case 'x':
+      if (*(cursor + 1) == 'o' &&
+      *(cursor + 2) == 'r')
+    {
+      token_stream[(int) index++].kind = Token_xor;
+      return;
+    }
+      break;
+
+    }
+  token_stream[(int) index++].kind = Token_identifier;
+}
+
+void Lexer::scanKeyword4()
+{
+  switch (*cursor)
+    {
+    case 'a':
+      if (*(cursor + 1) == 'u' &&
+      *(cursor + 2) == 't' &&
+      *(cursor + 3) == 'o')
+    {
+      token_stream[(int) index++].kind = Token_auto;
+      return;
+    }
+      break;
+
+    case 'c':
+      if (*(cursor + 1) == 'a' &&
+      *(cursor + 2) == 's' &&
+      *(cursor + 3) == 'e')
+    {
+      token_stream[(int) index++].kind = Token_case;
+      return;
+    }
+      if (*(cursor + 1) == 'h' &&
+      *(cursor + 2) == 'a' &&
+      *(cursor + 3) == 'r')
+    {
+      token_stream[(int) index++].kind = Token_char;
+      return;
+    }
+      break;
+
+    case 'b':
+      if (*(cursor + 1) == 'o' &&
+      *(cursor + 2) == 'o' &&
+      *(cursor + 3) == 'l')
+    {
+      token_stream[(int) index++].kind = Token_bool;
+      return;
+    }
+      break;
+
+    case 'e':
+      if (*(cursor + 1) == 'l' &&
+      *(cursor + 2) == 's' &&
+      *(cursor + 3) == 'e')
+    {
+      token_stream[(int) index++].kind = Token_else;
+      return;
+    }
+      if (*(cursor + 1) == 'm' &&
+      *(cursor + 2) == 'i' &&
+      *(cursor + 3) == 't')
+    {
+      token_stream[(int) index++].kind = Token_emit;
+      return;
+    }
+      if (*(cursor + 1) == 'n' &&
+      *(cursor + 2) == 'u' &&
+      *(cursor + 3) == 'm')
+    {
+      token_stream[(int) index++].kind = Token_enum;
+      return;
+    }
+      break;
+
+    case 'g':
+      if (*(cursor + 1) == 'o' &&
+      *(cursor + 2) == 't' &&
+      *(cursor + 3) == 'o')
+    {
+      token_stream[(int) index++].kind = Token_goto;
+      return;
+    }
+      break;
+
+    case 'l':
+      if (*(cursor + 1) == 'o' &&
+      *(cursor + 2) == 'n' &&
+      *(cursor + 3) == 'g')
+    {
+      token_stream[(int) index++].kind = Token_long;
+      return;
+    }
+      break;
+
+    case 't':
+      if (*(cursor + 1) == 'h' &&
+      *(cursor + 2) == 'i' &&
+      *(cursor + 3) == 's')
+    {
+      token_stream[(int) index++].kind = Token_this;
+      return;
+    }
+      break;
+
+    case 'v':
+      if (*(cursor + 1) == 'o' &&
+      *(cursor + 2) == 'i' &&
+      *(cursor + 3) == 'd')
+    {
+      token_stream[(int) index++].kind = Token_void;
+      return;
+    }
+      break;
+
+    }
+  token_stream[(int) index++].kind = Token_identifier;
+}
+
+void Lexer::scanKeyword5()
+{
+  switch (*cursor)
+    {
+    case 'c':
+      if (*(cursor + 1) == 'a' &&
+      *(cursor + 2) == 't' &&
+      *(cursor + 3) == 'c' &&
+      *(cursor + 4) == 'h')
+    {
+      token_stream[(int) index++].kind = Token_catch;
+      return;
+    }
+      if (*(cursor + 1) == 'l' &&
+      *(cursor + 2) == 'a' &&
+      *(cursor + 3) == 's' &&
+      *(cursor + 4) == 's')
+    {
+      token_stream[(int) index++].kind = Token_class;
+      return;
+    }
+      if (*(cursor + 1) == 'o' &&
+      *(cursor + 2) == 'm' &&
+      *(cursor + 3) == 'p' &&
+      *(cursor + 4) == 'l')
+    {
+      token_stream[(int) index++].kind = Token_compl;
+      return;
+    }
+      if (*(cursor + 1) == 'o' &&
+      *(cursor + 2) == 'n' &&
+      *(cursor + 3) == 's' &&
+      *(cursor + 4) == 't')
+    {
+      token_stream[(int) index++].kind = Token_const;
+      return;
+    }
+      break;
+
+    case 'b':
+      if (*(cursor + 1) == 'i' &&
+      *(cursor + 2) == 't' &&
+      *(cursor + 3) == 'o' &&
+      *(cursor + 4) == 'r')
+    {
+      token_stream[(int) index++].kind = Token_bitor;
+      return;
+    }
+      if (*(cursor + 1) == 'r' &&
+      *(cursor + 2) == 'e' &&
+      *(cursor + 3) == 'a' &&
+      *(cursor + 4) == 'k')
+    {
+      token_stream[(int) index++].kind = Token_break;
+      return;
+    }
+      break;
+
+    case 'f':
+      if (*(cursor + 1) == 'l' &&
+      *(cursor + 2) == 'o' &&
+      *(cursor + 3) == 'a' &&
+      *(cursor + 4) == 't')
+    {
+      token_stream[(int) index++].kind = Token_float;
+      return;
+    }
+      break;
+
+    case 'o':
+      if (*(cursor + 1) == 'r' &&
+      *(cursor + 2) == '_' &&
+      *(cursor + 3) == 'e' &&
+      *(cursor + 4) == 'q')
+    {
+      token_stream[(int) index++].kind = Token_or_eq;
+      return;
+    }
+      break;
+
+    case 's':
+      if (*(cursor + 1) == 'h' &&
+      *(cursor + 2) == 'o' &&
+      *(cursor + 3) == 'r' &&
+      *(cursor + 4) == 't')
+    {
+      token_stream[(int) index++].kind = Token_short;
+      return;
+    }
+      if (*(cursor + 1) == 'l' &&
+      *(cursor + 2) == 'o' &&
+      *(cursor + 3) == 't' &&
+      *(cursor + 4) == 's')
+    {
+      token_stream[(int) index++].kind = Token_slots;
+      return;
+    }
+      break;
+
+    case 'u':
+      if (*(cursor + 1) == 'n' &&
+      *(cursor + 2) == 'i' &&
+      *(cursor + 3) == 'o' &&
+      *(cursor + 4) == 'n')
+    {
+      token_stream[(int) index++].kind = Token_union;
+      return;
+    }
+      if (*(cursor + 1) == 's' &&
+      *(cursor + 2) == 'i' &&
+      *(cursor + 3) == 'n' &&
+      *(cursor + 4) == 'g')
+    {
+      token_stream[(int) index++].kind = Token_using;
+      return;
+    }
+      break;
+
+    case 't':
+      if (*(cursor + 1) == 'h' &&
+      *(cursor + 2) == 'r' &&
+      *(cursor + 3) == 'o' &&
+      *(cursor + 4) == 'w')
+    {
+      token_stream[(int) index++].kind = Token_throw;
+      return;
+    }
+      break;
+
+    case 'w':
+      if (*(cursor + 1) == 'h' &&
+      *(cursor + 2) == 'i' &&
+      *(cursor + 3) == 'l' &&
+      *(cursor + 4) == 'e')
+    {
+      token_stream[(int) index++].kind = Token_while;
+      return;
+    }
+      break;
+
+    }
+  token_stream[(int) index++].kind = Token_identifier;
+}
+
+void Lexer::scanKeyword6()
+{
+  switch (*cursor)
+    {
+    case 'a':
+      if (*(cursor + 1) == 'n' &&
+      *(cursor + 2) == 'd' &&
+      *(cursor + 3) == '_' &&
+      *(cursor + 4) == 'e' &&
+      *(cursor + 5) == 'q')
+    {
+      token_stream[(int) index++].kind = Token_and_eq;
+      return;
+    }
+      break;
+
+    case 'b':
+      if (*(cursor + 1) == 'i' &&
+      *(cursor + 2) == 't' &&
+      *(cursor + 3) == 'a' &&
+      *(cursor + 4) == 'n' &&
+      *(cursor + 5) == 'd')
+    {
+      token_stream[(int) index++].kind = Token_bitand;
+      return;
+    }
+      break;
+
+    case 'e':
+      if (*(cursor + 1) == 'x' &&
+      *(cursor + 2) == 'p' &&
+      *(cursor + 3) == 'o' &&
+      *(cursor + 4) == 'r' &&
+      *(cursor + 5) == 't')
+    {
+      token_stream[(int) index++].kind = Token_export;
+      return;
+    }
+      if (*(cursor + 1) == 'x' &&
+      *(cursor + 2) == 't' &&
+      *(cursor + 3) == 'e' &&
+      *(cursor + 4) == 'r' &&
+      *(cursor + 5) == 'n')
+    {
+      token_stream[(int) index++].kind = Token_extern;
+      return;
+    }
+      break;
+
+    case 'd':
+      if (*(cursor + 1) == 'e' &&
+      *(cursor + 2) == 'l' &&
+      *(cursor + 3) == 'e' &&
+      *(cursor + 4) == 't' &&
+      *(cursor + 5) == 'e')
+    {
+      token_stream[(int) index++].kind = Token_delete;
+      return;
+    }
+      if (*(cursor + 1) == 'o' &&
+      *(cursor + 2) == 'u' &&
+      *(cursor + 3) == 'b' &&
+      *(cursor + 4) == 'l' &&
+      *(cursor + 5) == 'e')
+    {
+      token_stream[(int) index++].kind = Token_double;
+      return;
+    }
+      break;
+
+    case 'f':
+      if (*(cursor + 1) == 'r' &&
+      *(cursor + 2) == 'i' &&
+      *(cursor + 3) == 'e' &&
+      *(cursor + 4) == 'n' &&
+      *(cursor + 5) == 'd')
+    {
+      token_stream[(int) index++].kind = Token_friend;
+      return;
+    }
+      break;
+
+    case 'i':
+      if (*(cursor + 1) == 'n' &&
+      *(cursor + 2) == 'l' &&
+      *(cursor + 3) == 'i' &&
+      *(cursor + 4) == 'n' &&
+      *(cursor + 5) == 'e')
+    {
+      token_stream[(int) index++].kind = Token_inline;
+      return;
+    }
+      break;
+
+    case 'K':
+      if (*(cursor + 1) == '_' &&
+      *(cursor + 2) == 'D' &&
+      *(cursor + 3) == 'C' &&
+      *(cursor + 4) == 'O' &&
+      *(cursor + 5) == 'P')
+    {
+      token_stream[(int) index++].kind = Token_K_DCOP;
+      return;
+    }
+      break;
+
+    case 'n':
+      if (*(cursor + 1) == 'o' &&
+      *(cursor + 2) == 't' &&
+      *(cursor + 3) == '_' &&
+      *(cursor + 4) == 'e' &&
+      *(cursor + 5) == 'q')
+    {
+      token_stream[(int) index++].kind = Token_not_eq;
+      return;
+    }
+      break;
+
+    case 'p':
+      if (*(cursor + 1) == 'u' &&
+      *(cursor + 2) == 'b' &&
+      *(cursor + 3) == 'l' &&
+      *(cursor + 4) == 'i' &&
+      *(cursor + 5) == 'c')
+    {
+      token_stream[(int) index++].kind = Token_public;
+      return;
+    }
+      break;
+
+    case 's':
+      if (*(cursor + 1) == 'i' &&
+      *(cursor + 2) == 'g' &&
+      *(cursor + 3) == 'n' &&
+      *(cursor + 4) == 'e' &&
+      *(cursor + 5) == 'd')
+    {
+      token_stream[(int) index++].kind = Token_signed;
+      return;
+    }
+      if (*(cursor + 1) == 'i' &&
+      *(cursor + 2) == 'z' &&
+      *(cursor + 3) == 'e' &&
+      *(cursor + 4) == 'o' &&
+      *(cursor + 5) == 'f')
+    {
+      token_stream[(int) index++].kind = Token_sizeof;
+      return;
+    }
+      if (*(cursor + 1) == 't' &&
+      *(cursor + 2) == 'a' &&
+      *(cursor + 3) == 't' &&
+      *(cursor + 4) == 'i' &&
+      *(cursor + 5) == 'c')
+    {
+      token_stream[(int) index++].kind = Token_static;
+      return;
+    }
+      if (*(cursor + 1) == 't' &&
+      *(cursor + 2) == 'r' &&
+      *(cursor + 3) == 'u' &&
+      *(cursor + 4) == 'c' &&
+      *(cursor + 5) == 't')
+    {
+      token_stream[(int) index++].kind = Token_struct;
+      return;
+    }
+      if (*(cursor + 1) == 'w' &&
+      *(cursor + 2) == 'i' &&
+      *(cursor + 3) == 't' &&
+      *(cursor + 4) == 'c' &&
+      *(cursor + 5) == 'h')
+    {
+      token_stream[(int) index++].kind = Token_switch;
+      return;
+    }
+      break;
+
+    case 'r':
+      if (*(cursor + 1) == 'e' &&
+      *(cursor + 2) == 't' &&
+      *(cursor + 3) == 'u' &&
+      *(cursor + 4) == 'r' &&
+      *(cursor + 5) == 'n')
+    {
+      token_stream[(int) index++].kind = Token_return;
+      return;
+    }
+      break;
+
+    case 't':
+      if (*(cursor + 1) == 'y' &&
+      *(cursor + 2) == 'p' &&
+      *(cursor + 3) == 'e' &&
+      *(cursor + 4) == 'i' &&
+      *(cursor + 5) == 'd')
+    {
+      token_stream[(int) index++].kind = Token_typeid;
+      return;
+    }
+      break;
+
+    case 'x':
+      if (*(cursor + 1) == 'o' &&
+      *(cursor + 2) == 'r' &&
+      *(cursor + 3) == '_' &&
+      *(cursor + 4) == 'e' &&
+      *(cursor + 5) == 'q')
+    {
+      token_stream[(int) index++].kind = Token_xor_eq;
+      return;
+    }
+      break;
+
+    case 'k':
+      if (*(cursor + 1) == '_' &&
+      *(cursor + 2) == 'd' &&
+      *(cursor + 3) == 'c' &&
+      *(cursor + 4) == 'o' &&
+      *(cursor + 5) == 'p')
+    {
+      token_stream[(int) index++].kind = Token_k_dcop;
+      return;
+    }
+      break;
+
+    }
+  token_stream[(int) index++].kind = Token_identifier;
+}
+
+void Lexer::scanKeyword7()
+{
+  switch (*cursor)
+    {
+    case 'd':
+      if (*(cursor + 1) == 'e' &&
+      *(cursor + 2) == 'f' &&
+      *(cursor + 3) == 'a' &&
+      *(cursor + 4) == 'u' &&
+      *(cursor + 5) == 'l' &&
+      *(cursor + 6) == 't')
+    {
+      token_stream[(int) index++].kind = Token_default;
+      return;
+    }
+      break;
+
+    case 'm':
+      if (*(cursor + 1) == 'u' &&
+      *(cursor + 2) == 't' &&
+      *(cursor + 3) == 'a' &&
+      *(cursor + 4) == 'b' &&
+      *(cursor + 5) == 'l' &&
+      *(cursor + 6) == 'e')
+    {
+      token_stream[(int) index++].kind = Token_mutable;
+      return;
+    }
+      break;
+
+    case 'p':
+      if (*(cursor + 1) == 'r' &&
+      *(cursor + 2) == 'i' &&
+      *(cursor + 3) == 'v' &&
+      *(cursor + 4) == 'a' &&
+      *(cursor + 5) == 't' &&
+      *(cursor + 6) == 'e')
+    {
+      token_stream[(int) index++].kind = Token_private;
+      return;
+    }
+      break;
+    case 's':
+      if (*(cursor + 1) == 'i' &&
+      *(cursor + 2) == 'g' &&
+      *(cursor + 3) == 'n' &&
+      *(cursor + 4) == 'a' &&
+      *(cursor + 5) == 'l' &&
+      *(cursor + 6) == 's')
+    {
+      token_stream[(int) index++].kind = Token_signals;
+      return;
+    }
+      break;
+    case 't':
+      if (*(cursor + 1) == 'y' &&
+      *(cursor + 2) == 'p' &&
+      *(cursor + 3) == 'e' &&
+      *(cursor + 4) == 'd' &&
+      *(cursor + 5) == 'e' &&
+      *(cursor + 6) == 'f')
+    {
+      token_stream[(int) index++].kind = Token_typedef;
+      return;
+    }
+      break;
+
+    case 'v':
+      if (*(cursor + 1) == 'i' &&
+      *(cursor + 2) == 'r' &&
+      *(cursor + 3) == 't' &&
+      *(cursor + 4) == 'u' &&
+      *(cursor + 5) == 'a' &&
+      *(cursor + 6) == 'l')
+    {
+      token_stream[(int) index++].kind = Token_virtual;
+      return;
+    }
+      break;
+
+    case 'Q':
+      if (*(cursor + 1) == '_' &&
+      *(cursor + 2) == 'E' &&
+      *(cursor + 3) == 'N' &&
+      *(cursor + 4) == 'U' &&
+      *(cursor + 5) == 'M' &&
+      *(cursor + 6) == 'S')
+      {
+        token_stream[(int) index++].kind = Token_Q_ENUMS;
+        return;
+      }
+        break;
+
+    }
+  token_stream[(int) index++].kind = Token_identifier;
+}
+
+void Lexer::scanKeyword8()
+{
+  switch (*cursor)
+    {
+    case '_':
+      if (*(cursor + 1) == '_' &&
+      *(cursor + 2) == 't' &&
+      *(cursor + 3) == 'y' &&
+      *(cursor + 4) == 'p' &&
+      *(cursor + 5) == 'e' &&
+      *(cursor + 6) == 'o' &&
+      *(cursor + 7) == 'f')
+    {
+      token_stream[(int) index++].kind = Token___typeof;
+      return;
+    }
+      break;
+
+    case 'c':
+      if (*(cursor + 1) == 'o' &&
+      *(cursor + 2) == 'n' &&
+      *(cursor + 3) == 't' &&
+      *(cursor + 4) == 'i' &&
+      *(cursor + 5) == 'n' &&
+      *(cursor + 6) == 'u' &&
+      *(cursor + 7) == 'e')
+    {
+      token_stream[(int) index++].kind = Token_continue;
+      return;
+    }
+      break;
+
+    case 'e':
+      if (*(cursor + 1) == 'x' &&
+      *(cursor + 2) == 'p' &&
+      *(cursor + 3) == 'l' &&
+      *(cursor + 4) == 'i' &&
+      *(cursor + 5) == 'c' &&
+      *(cursor + 6) == 'i' &&
+      *(cursor + 7) == 't')
+    {
+      token_stream[(int) index++].kind = Token_explicit;
+      return;
+    }
+      break;
+
+    case 'o':
+      if (*(cursor + 1) == 'p' &&
+      *(cursor + 2) == 'e' &&
+      *(cursor + 3) == 'r' &&
+      *(cursor + 4) == 'a' &&
+      *(cursor + 5) == 't' &&
+      *(cursor + 6) == 'o' &&
+      *(cursor + 7) == 'r')
+    {
+      token_stream[(int) index++].kind = Token_operator;
+      return;
+    }
+      break;
+
+    case 'Q':
+      if (*(cursor + 1) == '_' &&
+      *(cursor + 2) == 'O' &&
+      *(cursor + 3) == 'B' &&
+      *(cursor + 4) == 'J' &&
+      *(cursor + 5) == 'E' &&
+      *(cursor + 6) == 'C' &&
+      *(cursor + 7) == 'T')
+    {
+      token_stream[(int) index++].kind = Token_Q_OBJECT;
+      return;
+    }
+      break;
+
+    case 'r':
+      if (*(cursor + 1) == 'e' &&
+      *(cursor + 2) == 'g' &&
+      *(cursor + 3) == 'i' &&
+      *(cursor + 4) == 's' &&
+      *(cursor + 5) == 't' &&
+      *(cursor + 6) == 'e' &&
+      *(cursor + 7) == 'r')
+    {
+      token_stream[(int) index++].kind = Token_register;
+      return;
+    }
+      break;
+
+    case 'u':
+      if (*(cursor + 1) == 'n' &&
+      *(cursor + 2) == 's' &&
+      *(cursor + 3) == 'i' &&
+      *(cursor + 4) == 'g' &&
+      *(cursor + 5) == 'n' &&
+      *(cursor + 6) == 'e' &&
+      *(cursor + 7) == 'd')
+    {
+      token_stream[(int) index++].kind = Token_unsigned;
+      return;
+    }
+      break;
+
+    case 't':
+      if (*(cursor + 1) == 'e' &&
+      *(cursor + 2) == 'm' &&
+      *(cursor + 3) == 'p' &&
+      *(cursor + 4) == 'l' &&
+      *(cursor + 5) == 'a' &&
+      *(cursor + 6) == 't' &&
+      *(cursor + 7) == 'e')
+    {
+      token_stream[(int) index++].kind = Token_template;
+      return;
+    }
+      if (*(cursor + 1) == 'y' &&
+      *(cursor + 2) == 'p' &&
+      *(cursor + 3) == 'e' &&
+      *(cursor + 4) == 'n' &&
+      *(cursor + 5) == 'a' &&
+      *(cursor + 6) == 'm' &&
+      *(cursor + 7) == 'e')
+    {
+      token_stream[(int) index++].kind = Token_typename;
+      return;
+    }
+      break;
+
+    case 'v':
+      if (*(cursor + 1) == 'o' &&
+      *(cursor + 2) == 'l' &&
+      *(cursor + 3) == 'a' &&
+      *(cursor + 4) == 't' &&
+      *(cursor + 5) == 'i' &&
+      *(cursor + 6) == 'l' &&
+      *(cursor + 7) == 'e')
+    {
+      token_stream[(int) index++].kind = Token_volatile;
+      return;
+    }
+      break;
+
+    }
+  token_stream[(int) index++].kind = Token_identifier;
+}
+
+void Lexer::scanKeyword9()
+{
+  switch (*cursor)
+    {
+    case 'p':
+      if (*(cursor + 1) == 'r' &&
+      *(cursor + 2) == 'o' &&
+      *(cursor + 3) == 't' &&
+      *(cursor + 4) == 'e' &&
+      *(cursor + 5) == 'c' &&
+      *(cursor + 6) == 't' &&
+      *(cursor + 7) == 'e' &&
+      *(cursor + 8) == 'd')
+    {
+      token_stream[(int) index++].kind = Token_protected;
+      return;
+    }
+      break;
+
+    case 'n':
+      if (*(cursor + 1) == 'a' &&
+      *(cursor + 2) == 'm' &&
+      *(cursor + 3) == 'e' &&
+      *(cursor + 4) == 's' &&
+      *(cursor + 5) == 'p' &&
+      *(cursor + 6) == 'a' &&
+      *(cursor + 7) == 'c' &&
+      *(cursor + 8) == 'e')
+    {
+      token_stream[(int) index++].kind = Token_namespace;
+      return;
+    }
+      break;
+
+    }
+  token_stream[(int) index++].kind = Token_identifier;
+}
+
+void Lexer::scanKeyword10()
+{
+  switch (*cursor)
+    {
+    case 'c':
+      if (*(cursor + 1) == 'o' &&
+      *(cursor + 2) == 'n' &&
+      *(cursor + 3) == 's' &&
+      *(cursor + 4) == 't' &&
+      *(cursor + 5) == '_' &&
+      *(cursor + 6) == 'c' &&
+      *(cursor + 7) == 'a' &&
+      *(cursor + 8) == 's' &&
+      *(cursor + 9) == 't')
+    {
+      token_stream[(int) index++].kind = Token_const_cast;
+      return;
+    }
+      break;
+
+    case 'Q':
+        if (*(cursor + 1) == '_' &&
+            *(cursor + 2) == 'P' &&
+            *(cursor + 3) == 'R' &&
+            *(cursor + 4) == 'O' &&
+            *(cursor + 5) == 'P' &&
+            *(cursor + 6) == 'E' &&
+            *(cursor + 7) == 'R' &&
+            *(cursor + 8) == 'T' &&
+            *(cursor + 9) == 'Y')
+          {
+            token_stream[(int) index++].kind = Token_Q_PROPERTY;
+            return;
+          }
+
+        break;
+    }
+
+  token_stream[(int) index++].kind = Token_identifier;
+}
+
+void Lexer::scanKeyword11()
+{
+  switch (*cursor)
+    {
+    case 'Q':
+      if (*(cursor + 1) == '_' &&
+      *(cursor + 2) == 'I' &&
+      *(cursor + 3) == 'N' &&
+      *(cursor + 4) == 'V' &&
+      *(cursor + 5) == 'O' &&
+      *(cursor + 6) == 'K' &&
+      *(cursor + 7) == 'A' &&
+      *(cursor + 8) == 'B' &&
+      *(cursor + 9) == 'L' &&
+      *(cursor + 10) == 'E')
+    {
+      token_stream[(int) index++].kind = Token_Q_INVOKABLE;
+      return;
+    }
+      break;
+
+    case 's':
+      if (*(cursor + 1) == 't' &&
+      *(cursor + 2) == 'a' &&
+      *(cursor + 3) == 't' &&
+      *(cursor + 4) == 'i' &&
+      *(cursor + 5) == 'c' &&
+      *(cursor + 6) == '_' &&
+      *(cursor + 7) == 'c' &&
+      *(cursor + 8) == 'a' &&
+      *(cursor + 9) == 's' &&
+      *(cursor + 10) == 't')
+    {
+      token_stream[(int) index++].kind = Token_static_cast;
+      return;
+    }
+      break;
+
+    }
+  token_stream[(int) index++].kind = Token_identifier;
+}
+
+void Lexer::scanKeyword12()
+{
+  switch (*cursor)
+    {
+    case 'd':
+      if (*(cursor + 1) == 'y' &&
+      *(cursor + 2) == 'n' &&
+      *(cursor + 3) == 'a' &&
+      *(cursor + 4) == 'm' &&
+      *(cursor + 5) == 'i' &&
+      *(cursor + 6) == 'c' &&
+      *(cursor + 7) == '_' &&
+      *(cursor + 8) == 'c' &&
+      *(cursor + 9) == 'a' &&
+      *(cursor + 10) == 's' &&
+      *(cursor + 11) == 't')
+    {
+      token_stream[(int) index++].kind = Token_dynamic_cast;
+      return;
+    }
+      break;
+
+    }
+  token_stream[(int) index++].kind = Token_identifier;
+}
+
+void Lexer::scanKeyword13()
+{
+  switch (*cursor)
+    {
+    case '_':
+      if (*(cursor + 1) == '_' &&
+      *(cursor + 2) == 'a' &&
+      *(cursor + 3) == 't' &&
+      *(cursor + 4) == 't' &&
+      *(cursor + 5) == 'r' &&
+      *(cursor + 6) == 'i' &&
+      *(cursor + 7) == 'b' &&
+      *(cursor + 8) == 'u' &&
+      *(cursor + 9) == 't' &&
+      *(cursor + 10) == 'e' &&
+      *(cursor + 11) == '_' &&
+      *(cursor + 12) == '_')
+    {
+      token_stream[(int) index++].kind = Token___attribute__;
+      return;
+    }
+      break;
+    }
+  token_stream[(int) index++].kind = Token_identifier;
+}
+
+void Lexer::scanKeyword14()
+{
+  switch (*cursor)
+    {
+    case 'k':
+      if (*(cursor + 1) == '_' &&
+      *(cursor + 2) == 'd' &&
+      *(cursor + 3) == 'c' &&
+      *(cursor + 4) == 'o' &&
+      *(cursor + 5) == 'p' &&
+      *(cursor + 6) == '_' &&
+      *(cursor + 7) == 's' &&
+      *(cursor + 8) == 'i' &&
+      *(cursor + 9) == 'g' &&
+      *(cursor + 10) == 'n' &&
+      *(cursor + 11) == 'a' &&
+      *(cursor + 12) == 'l' &&
+      *(cursor + 13) == 's')
+    {
+      token_stream[(int) index++].kind = Token_k_dcop_signals;
+      return;
+    }
+      break;
+    }
+  token_stream[(int) index++].kind = Token_identifier;
+}
+
+void Lexer::scanKeyword16()
+{
+  switch (*cursor)
+    {
+    case 'r':
+      if (*(cursor + 1) == 'e' &&
+      *(cursor + 2) == 'i' &&
+      *(cursor + 3) == 'n' &&
+      *(cursor + 4) == 't' &&
+      *(cursor + 5) == 'e' &&
+      *(cursor + 6) == 'r' &&
+      *(cursor + 7) == 'p' &&
+      *(cursor + 8) == 'r' &&
+      *(cursor + 9) == 'e' &&
+      *(cursor + 10) == 't' &&
+      *(cursor + 11) == '_' &&
+      *(cursor + 12) == 'c' &&
+      *(cursor + 13) == 'a' &&
+      *(cursor + 14) == 's' &&
+      *(cursor + 15) == 't')
+    {
+      token_stream[(int) index++].kind = Token_reinterpret_cast;
+      return;
+    }
+      break;
+    }
+
+  token_stream[(int) index++].kind = Token_identifier;
+}
+
+// kate: space-indent on; indent-width 2; replace-tabs on;