1 /* Cycript - Optimizing JavaScript Compiler/Runtime
 
   2  * Copyright (C) 2009-2015  Jay Freeman (saurik)
 
   5 /* GNU Affero General Public License, Version 3 {{{ */
 
   7  * This program is free software: you can redistribute it and/or modify
 
   8  * it under the terms of the GNU Affero General Public License as published by
 
   9  * the Free Software Foundation, either version 3 of the License, or
 
  10  * (at your option) any later version.
 
  12  * This program is distributed in the hope that it will be useful,
 
  13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  15  * GNU Affero General Public License for more details.
 
  17  * You should have received a copy of the GNU Affero General Public License
 
  18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
  22 /* XXX: supposedly I will be screwed on very very long multi-line comments and need to replace these with a manual lexer. http://websrv.cs.fsu.edu/~engelen/courses/COP5621/Pr2.pdf */
 
  25 #if defined(__clang__)
 
  26 #pragma clang diagnostic push
 
  27 #pragma clang diagnostic ignored "-Wunused-variable"
 
  28 #pragma clang diagnostic ignored "-Wdeprecated-register"
 
  30 #pragma GCC diagnostic push
 
  31 #pragma GCC diagnostic ignored "-Wsign-compare"
 
  32 #pragma GCC diagnostic ignored "-Wunused-function"
 
  33 #pragma GCC diagnostic ignored "-Wunused-variable"
 
  39 #define YYLTYPE CYLocation
 
  40 #include "Cycript.tab.hh"
 
  41 typedef cy::parser::token tk;
 
  43 #include "Highlight.hpp"
 
  45 #define YY_EXTRA_TYPE CYDriver *
 
  47 // do /not/ fold token to the return: this is a macro and the ordering is dependent
 
  48 #define F(value, highlight) do { \
 
  51     yyextra->no_.AtImplementation = false; \
 
  53     yyextra->no_.Function = false; \
 
  54     yyextra->no_.OpenBrace = false; \
 
  55     yylval->highlight_ = highlight; \
 
  59 #define P yyextra->pool_
 
  61 #define Y P.strmemdup(yytext, yyleng)
 
  63 #define I(type, Type, value, highlight) do { \
 
  64     yylval->type ## _ = A CY ## Type; \
 
  65     F(value, highlight); \
 
  68 #define T yylval->newline_ = yyextra->state_ == CYNewLine; BEGIN(Div);
 
  69 #define C T yyextra->state_ = CYClear;
 
  70 #define R T yyextra->state_ = CYRestricted;
 
  73     if (yyextra->state_ != CYNewLine) { \
 
  74         if (yyextra->state_ != CYRestricted) \
 
  75             yyextra->state_ = CYNewLine; \
 
  77             yyextra->state_ = CYClear; \
 
  78             F(tk::NewLine, hi::Nothing); \
 
  83     if (const char *nl = reinterpret_cast<const char *>(memchr(yytext, '\n', yyleng))) { \
 
  88             left = yyleng - (nl - yytext) - 1; \
 
  89             nl = reinterpret_cast<const char *>(memchr(nl + 1, '\n', left)); \
 
  90         } while (nl != NULL); \
 
  92         yylloc->end.lines(lines); \
 
  93         yylloc->end.columns(left); \
 
 100     yylloc->end.columns(yyleng); \
 
 104     if (yyextra->commented_) { \
 
 105         I(comment, Comment(Y), tk::Comment, hi::Comment); \
 
 109 #define E(message) { \
 
 110     CYDriver::Error error; \
 
 111     error.location_ = *yylloc; \
 
 112     error.message_ = "syntax error, " message; \
 
 113     yyextra->errors_.push_back(error); \
 
 118     if (c >= '0' && c <= '9')
 
 120     if (c >= 'a' && c <= 'f')
 
 122     if (c >= 'A' && c <= 'F')
 
 127 static void U(char *&local, unsigned point) {
 
 129     } else if (point < 0x000080) {
 
 131     } else if (point < 0x000800) {
 
 132         *local++ = 0xc0 | point >> 0x06 & 0x1f;
 
 134     } else if (point < 0x010000) {
 
 135         *local++ = 0xe0 | point >> 0x0c & 0x0f;
 
 137     } else if (point < 0x110000) {
 
 138         *local++ = 0xf0 | point >> 0x12 & 0x07;
 
 139         *local++ = 0x80 | point >> 0x0c & 0x3f;
 
 141         *local++ = 0x80 | point >> 0x06 & 0x3f;
 
 143         *local++ = 0x80 | point >> 0x00 & 0x3f;
 
 144     } else _assert(false);
 
 147 static void U(char *&local, const char *text, yy_size_t &i) {
 
 150     char next(text[++i]);
 
 152         point = H(text[i + 0]) << 12 | H(text[i + 1]) << 8 | H(text[i + 2]) << 4 | H(text[i + 3]);
 
 160             point = (point << 4) | H(next);
 
 167 #define YY_INPUT(data, value, size) { \
 
 168     if (yyextra->data_.eof()) \
 
 171         yyextra->data_.read(data, size); \
 
 172         size_t copy(yyextra->data_.gcount()); \
 
 173         value = copy == 0 ? YY_NULL : copy; \
 
 181 %option bison-locations
 
 190 %option never-interactive
 
 205 LineTerminatorSequence \r?\n|\r|\xe2\x80[\xa8\xa9]
 
 206 WhiteSpace [\x09\x0b\x0c\x20]|\xc2\xa0|\xef\xbb\xbf
 
 207 UnicodeEscape \\u({HexDigit}{4}|\{{HexDigit}+\})
 
 209 OctalEscape \\[1-7]|\\[4-7][0-7]|\\[0-3][0-7][0-7]?
 
 210 StringEscape \\['"\\bfnrtv]|\\0|{OctalEscape}|\\x{HexDigit}{2}|{UnicodeEscape}
 
 211 StringExtra {StringEscape}|\\{LineTerminatorSequence}
 
 212 SingleString ([^'\\\n]|{StringExtra})*
 
 213 DoubleString ([^"\\\n]|{StringExtra})*
 
 214 StringPrefix '{SingleString}|\"{DoubleString}
 
 216 @include UnicodeIDStart.l
 
 217 @include UnicodeIDContinue.l
 
 221 UnicodeStart {IdentifierMore}|{UnicodeIDStart}
 
 222 UnicodePart {IdentifierMore}|\xe2\x80[\x8c\x8d]|{UnicodeIDContinue}
 
 223 UnicodeFail {U2}|{U3}|{U3}{U0}|{U4}|{U4}{U0}|{U4}{U0}{U0}
 
 224 UnicodeScrap {UnicodePart}*{UnicodeFail}?
 
 226 IdentifierStart {UnicodeStart}|{UnicodeEscape}
 
 227 IdentifierPart {UnicodePart}|{UnicodeEscape}
 
 228 IdentifierFail {UnicodeFail}|\\(u({HexDigit}{0,3}|\{{HexDigit}*))?
 
 229 IdentifierScrap {IdentifierPart}*{IdentifierFail}?
 
 232 BackslashSequence \\{NonTerminator}
 
 233 RegularExpressionFirstChar [^\n*\\/]|{BackslashSequence}
 
 234 RegularExpressionChar [^\n\\/]|{BackslashSequence}
 
 235 RegularExpressionFlags {UnicodePart}*
 
 236 RegularExpressionChars {RegularExpressionChar}*
 
 237 RegularExpressionBody {RegularExpressionFirstChar}{RegularExpressionChars}
 
 240 XMLNameStart [a-zA-Z_:]
 
 241 XMLNamePart [a-zA-Z0-9.-_:]
 
 242 XMLName {XMLNameStart}{XMLNamePart}*
 
 256 <RegExp>\/{RegularExpressionBody}\/{RegularExpressionFlags} L C I(literal, RegEx(Y), tk::RegularExpressionLiteral, hi::Constant);
 
 257 <RegExp>\/{RegularExpressionBody}\/{RegularExpressionFlags}{UnicodeFail} L E("invalid flags")
 
 258 <RegExp>\/{RegularExpressionBody}?\\? L E("unterminated regex")
 
 264     /* http://ostermiller.org/findcomment.html */
 
 265     /* XXX: unify these two rules using !? */
 
 266 \/\*!([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/ V() C I(comment, Comment(Y), tk::Comment, hi::Comment);
 
 267 \/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/ V(N) M
 
 268 \/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\** V() E("invalid comment")
 
 272 <RegExp>"<>"      L F(tk::LeftRight, hi::Structure);
 
 273 <XMLContent>"</>" L F(tk::LeftSlashRight, hi::Structure);
 
 275 <RegExp,XMLContent>\<!\[CDATA\[(\n|[^[]|\[[^[]|\[\[[^>])*]]> V() F(tk::XMLCDATA, hi::Constant);
 
 276 <RegExp,XMLContent>\<!--(\n|[^-]|-[^-])*--> V() F(tk::XMLComment, hi::Comment);
 
 277 <RegExp,XMLContent>\<?(\n|[^?]|\?[^>])*?> V() F(tk::XMLPI, hi::Meta);
 
 279 <XMLTag>"="  L F(tk::Equal, hi::Structure);
 
 280 <XMLTag>">"  L F(tk::Right, hi::Structure);
 
 281 <XMLTag>"/>" L F(tk::SlashRight, hi::Structure);
 
 282 <XMLTag>"{"  L F(tk::OpenBrace, hi::Structure);
 
 284 <XMLTag>\"(\n|[^"])*\"|'(\n|[^'])*' V() F(tk::XMLAttributeValue, hi::Constant);
 
 285 <XMLTag>{XMLName} L F(tk::XMLName, hi::Identifier);
 
 286 <XMLTag>[ \t\r\n] V() F(tk::XMLWhitespace, hi::Nothing);
 
 288 <XMLContent>"{"  L F(tk::OpenBrace, hi::Structure);
 
 289 <XMLContent>"<"  L F(tk::Left, hi::Structure);
 
 290 <XMLContent>"</" L F(tk::LeftSlash, hi::Structure);
 
 294 "..."  L C F(tk::PeriodPeriodPeriod, hi::Meta);
 
 295 ".."   L E("invalid operator")
 
 298 "::"   L C F(tk::ColonColon, hi::Operator);
 
 299 ".."   L C F(tk::PeriodPeriod, hi::Operator);
 
 302 @begin E4X ObjectiveC
 
 303 "@"    L C F(tk::At, hi::Operator);
 
 304 "#"    L C F(tk::Pound, hi::Operator);
 
 307 "&"    L C F(tk::Ampersand, hi::Operator);
 
 308 "&&"   L C F(tk::AmpersandAmpersand, hi::Operator);
 
 309 "&="   L C F(tk::AmpersandEqual, hi::Operator);
 
 310 "^"    L C F(tk::Carrot, hi::Operator);
 
 311 "^="   L C F(tk::CarrotEqual, hi::Operator);
 
 312 "="    L C F(tk::Equal, hi::Operator);
 
 313 "=="   L C F(tk::EqualEqual, hi::Operator);
 
 314 "==="  L C F(tk::EqualEqualEqual, hi::Operator);
 
 315 "=>"   L C F(yylval->newline_ ? tk::EqualRight_ : tk::EqualRight, hi::Operator);
 
 316 "!"    L C F(tk::Exclamation, hi::Operator);
 
 317 "!="   L C F(tk::ExclamationEqual, hi::Operator);
 
 318 "!=="  L C F(tk::ExclamationEqualEqual, hi::Operator);
 
 319 "-"    L C F(tk::Hyphen, hi::Operator);
 
 320 "-="   L C F(tk::HyphenEqual, hi::Operator);
 
 321 "--"   L C F(yylval->newline_ ? tk::HyphenHyphen_ : tk::HyphenHyphen, hi::Operator);
 
 322 "->"   L C F(tk::HyphenRight, hi::Operator);
 
 323 "<"    L C F(tk::Left, hi::Operator);
 
 324 "<="   L C F(tk::LeftEqual, hi::Operator);
 
 325 "<<"   L C F(tk::LeftLeft, hi::Operator);
 
 326 "<<="  L C F(tk::LeftLeftEqual, hi::Operator);
 
 327 "%"    L C F(tk::Percent, hi::Operator);
 
 328 "%="   L C F(tk::PercentEqual, hi::Operator);
 
 329 "."    L C F(tk::Period, hi::Operator);
 
 330 "|"    L C F(tk::Pipe, hi::Operator);
 
 331 "|="   L C F(tk::PipeEqual, hi::Operator);
 
 332 "||"   L C F(tk::PipePipe, hi::Operator);
 
 333 "+"    L C F(tk::Plus, hi::Operator);
 
 334 "+="   L C F(tk::PlusEqual, hi::Operator);
 
 335 "++"   L C F(yylval->newline_ ? tk::PlusPlus_ : tk::PlusPlus, hi::Operator);
 
 336 ">"    L C F(tk::Right, hi::Operator);
 
 337 ">="   L C F(tk::RightEqual, hi::Operator);
 
 338 ">>"   L C F(tk::RightRight, hi::Operator);
 
 339 ">>="  L C F(tk::RightRightEqual, hi::Operator);
 
 340 ">>>"  L C F(tk::RightRightRight, hi::Operator);
 
 341 ">>>=" L C F(tk::RightRightRightEqual, hi::Operator);
 
 342 "*"    L C F(tk::Star, hi::Operator);
 
 343 "*="   L C F(tk::StarEqual, hi::Operator);
 
 344 "~"    L C F(tk::Tilde, hi::Operator);
 
 346 <Div>"/"  L C F(tk::Slash, hi::Operator);
 
 347 <Div>"/=" L C F(tk::SlashEqual, hi::Operator);
 
 349 ":"    L C F(tk::Colon, hi::Structure);
 
 350 ","    L C F(tk::Comma, hi::Structure);
 
 351 "?"    L C F(tk::Question, hi::Structure);
 
 352 ";"    L C F(tk::SemiColon, hi::Structure);
 
 354 "("    L C F(tk::OpenParen, hi::Structure);
 
 355 ")"    L C F(tk::CloseParen, hi::Structure);
 
 357 "{"    L C F(yyextra->no_.OpenBrace ? tk::OpenBrace__ : yylval->newline_ ? tk::OpenBrace_ : tk::OpenBrace, hi::Structure);
 
 358 "}"    L C F(tk::CloseBrace, hi::Structure);
 
 360 "["    L C F(tk::OpenBracket, hi::Structure);
 
 361 "]"    L C F(tk::CloseBracket, hi::Structure);
 
 364 "@error"          L C F(tk::At_error_, hi::Error);
 
 367 "@class"          L C F(tk::At_class_, hi::Meta);
 
 371 "@encode"         L C F(tk::At_encode_, hi::Meta);
 
 375 "@end"            L C F(tk::At_end_, hi::Meta);
 
 376 "@false"          L C F(tk::At_false_, hi::Constant);
 
 377 "@implementation" L C F(yyextra->no_.AtImplementation ? tk::At_implementation__ : tk::At_implementation_, hi::Meta);
 
 378 "@import"         L C F(tk::At_import_, hi::Special);
 
 379 "@NO"             L C F(tk::At_NO_, hi::Constant);
 
 380 "@null"           L C F(tk::At_null_, hi::Constant);
 
 381 "@selector"       L C F(tk::At_selector_, hi::Meta);
 
 382 "@true"           L C F(tk::At_true_, hi::Constant);
 
 383 "@YES"            L C F(tk::At_YES_, hi::Constant);
 
 386 @({UnicodeStart}{UnicodeScrap}|{UnicodeFail}) L E("invalid keyword")
 
 389 "undefined"       L C F(tk::_undefined_, hi::Operator);
 
 392 "bool"            L C F(tk::_bool_, hi::Type);
 
 393 "BOOL"            L C F(tk::_BOOL_, hi::Type);
 
 394 "id"              L C F(tk::_id_, hi::Type);
 
 395 "nil"             L C F(tk::_nil_, hi::Constant);
 
 396 "NULL"            L C F(tk::_NULL_, hi::Constant);
 
 397 "SEL"             L C F(tk::_SEL_, hi::Type);
 
 401 "abstract"        L C /*FII*/ F(tk::_abstract_, hi::Meta);
 
 402 "await"           L C /*II?*/ F(tk::_await_, hi::Meta);
 
 403 "boolean"         L C /*FII*/ F(tk::_boolean_, hi::Type);
 
 404 "break"           L R /*KKK*/ F(tk::_break_, hi::Control);
 
 405 "byte"            L C /*FII*/ F(tk::_byte_, hi::Type);
 
 406 "case"            L C /*KKK*/ F(tk::_case_, hi::Control);
 
 407 "catch"           L C /*KKK*/ F(tk::_catch_, hi::Control);
 
 408 "char"            L C /*FII*/ F(tk::_char_, hi::Type);
 
 409 "class"           L C /*FFK*/ F(tk::_class_, hi::Meta);
 
 410 "const"           L C /*FFK*/ F(tk::_const_, hi::Meta);
 
 411 "continue"        L R /*KKK*/ F(tk::_continue_, hi::Control);
 
 412 "debugger"        L C /*FKK*/ F(tk::_debugger_, hi::Meta);
 
 413 "default"         L C /*KKK*/ F(tk::_default_, hi::Control);
 
 414 "delete"          L C /*KKK*/ F(tk::_delete_, hi::Operator);
 
 415 "do"              L C /*KKK*/ F(tk::_do_, hi::Control);
 
 416 "double"          L C /*FII*/ F(tk::_double_, hi::Type);
 
 417 "else"            L C /*KKK*/ F(tk::_else_, hi::Control);
 
 418 "enum"            L C /*FFF*/ F(tk::_enum_, hi::Meta);
 
 419 "export"          L C /*FFK*/ F(tk::_export_, hi::Meta);
 
 420 "extends"         L C /*FFK*/ F(tk::_extends_, hi::Meta);
 
 421 "false"           L C /*LLL*/ F(tk::_false_, hi::Constant);
 
 422 "final"           L C /*FII*/ F(tk::_final_, hi::Meta);
 
 423 "finally"         L C /*KKK*/ F(tk::_finally_, hi::Control);
 
 424 "float"           L C /*FII*/ F(tk::_float_, hi::Type);
 
 425 "for"             L C /*KKK*/ F(tk::_for_, hi::Control);
 
 426 "function"        L C /*KKK*/ F(yyextra->no_.Function ? tk::_function__ : tk::_function_, hi::Meta);
 
 427 "goto"            L C /*FII*/ F(tk::_goto_, hi::Control);
 
 428 "if"              L C /*KKK*/ F(tk::_if_, hi::Control);
 
 429 "implements"      L C /*FSS*/ F(tk::_implements_, hi::Meta);
 
 430 "import"          L C /*FFK*/ F(tk::_import_, hi::Meta);
 
 431 "in"              L C /*KKK*/ F(yyextra->in_.top() ? tk::_in__ : tk::_in_, hi::Operator);
 
 432 "instanceof"      L C /*KKK*/ F(tk::_instanceof_, hi::Operator);
 
 433 "int"             L C /*FII*/ F(tk::_int_, hi::Type);
 
 434 "interface"       L C /*FSS*/ F(tk::_interface_, hi::Meta);
 
 435 "let"             L C /*IS?*/ F(tk::_let_, hi::Meta);
 
 436 "long"            L C /*FII*/ F(tk::_long_, hi::Type);
 
 437 "native"          L C /*FII*/ F(tk::_native_, hi::Meta);
 
 438 "new"             L C /*KKK*/ F(tk::_new_, hi::Operator);
 
 439 "null"            L C /*LLL*/ F(tk::_null_, hi::Constant);
 
 440 "package"         L C /*FSS*/ F(tk::_package_, hi::Meta);
 
 441 "private"         L C /*FSS*/ F(tk::_private_, hi::Meta);
 
 442 "protected"       L C /*FSS*/ F(tk::_protected_, hi::Meta);
 
 443 "public"          L C /*FSS*/ F(tk::_public_, hi::Meta);
 
 444 "return"          L R /*KKK*/ F(tk::_return_, hi::Control);
 
 445 "short"           L C /*FII*/ F(tk::_short_, hi::Type);
 
 446 "static"          L C /*FS?*/ F(tk::_static_, hi::Meta);
 
 447 "super"           L C /*FFK*/ F(tk::_super_, hi::Constant);
 
 448 "switch"          L C /*KKK*/ F(tk::_switch_, hi::Control);
 
 449 "synchronized"    L C /*FII*/ F(tk::_synchronized_, hi::Meta);
 
 450 "this"            L C /*KKK*/ F(tk::_this_, hi::Constant);
 
 451 "throw"           L R /*KKK*/ F(tk::_throw_, hi::Control);
 
 452 "throws"          L C /*FII*/ F(tk::_throws_, hi::Meta);
 
 453 "transient"       L C /*FII*/ F(tk::_transient_, hi::Meta);
 
 454 "true"            L C /*LLL*/ F(tk::_true_, hi::Constant);
 
 455 "try"             L C /*KKK*/ F(tk::_try_, hi::Control);
 
 456 "typeof"          L C /*KKK*/ F(tk::_typeof_, hi::Operator);
 
 457 "var"             L C /*KKK*/ F(tk::_var_, hi::Meta);
 
 458 "void"            L C /*KKK*/ F(tk::_void_, hi::Operator);
 
 459 "volatile"        L C /*FII*/ F(tk::_volatile_, hi::Meta);
 
 460 "while"           L C /*KKK*/ F(tk::_while_, hi::Control);
 
 461 "with"            L C /*KKK*/ F(tk::_with_, hi::Control);
 
 462 "yield"           L R /*IS?*/ F(tk::_yield_, hi::Control);
 
 464 "auto"            L C F(tk::_auto_, hi::Meta);
 
 465 "each"            L C F(tk::_each_, hi::Control);
 
 466 "of"              L C F(tk::_of_, hi::Operator);
 
 469 "extern"          L C F(tk::_extern_, hi::Type);
 
 470 "signed"          L C F(tk::_signed_, hi::Type);
 
 471 "typedef"         L C F(tk::_typedef_, hi::Meta);
 
 472 "unsigned"        L C F(tk::_unsigned_, hi::Type);
 
 476 "NO"              L C F(tk::_NO_, hi::Constant);
 
 477 "YES"             L C F(tk::_YES_, hi::Constant);
 
 481 "namespace"       L C F(tk::_namespace_, hi::Meta);
 
 482 "xml"             L C F(tk::_xml_, hi::Meta);
 
 486 {UnicodeStart}{UnicodePart}* L C I(identifier, Identifier(Y), tk::Identifier_, hi::Identifier);
 
 488 {IdentifierStart}{IdentifierPart}* L C {
 
 489     char *value(A char[yyleng + 1]);
 
 492     for (yy_size_t i(0), e(yyleng); i != e; ++i) {
 
 493         char next(yytext[i]);
 
 497             U(local, yytext, ++i);
 
 501     I(identifier, Identifier(value), tk::Identifier_, hi::Identifier);
 
 504 ({IdentifierStart}{IdentifierPart}*)?{IdentifierFail} L E("invalid identifier")
 
 507 0[0-7]+ L C I(number, Number(strtoull(yytext + 1, NULL, 8)), tk::NumericLiteral, hi::Constant);
 
 508 0[0-9]+ L C I(number, Number(strtoull(yytext + 1, NULL, 10)), tk::NumericLiteral, hi::Constant);
 
 510 0[xX][0-9a-fA-F]+ L C I(number, Number(strtoull(yytext + 2, NULL, 16)), tk::NumericLiteral, hi::Constant);
 
 511 0[oO][0-7]+ L C I(number, Number(strtoull(yytext + 2, NULL, 8)), tk::NumericLiteral, hi::Constant);
 
 512 0[bB][0-1]+ L C I(number, Number(strtoull(yytext + 2, NULL, 2)), tk::NumericLiteral, hi::Constant);
 
 514 (\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?)([eE][+-]?[0-9]+)? L C I(number, Number(strtod(yytext, NULL)), tk::NumericLiteral, hi::Constant);
 
 515 (\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?)[eE][+-]?{IdentifierScrap} L E("invalid exponent")
 
 516 (\.?[0-9]|(0|[1-9][0-9]*)\.){IdentifierScrap} L E("invalid number")
 
 519 '{SingleString}'|\"{DoubleString}\" L C {
 
 520     char *value(A char[yyleng]);
 
 523     for (yy_size_t i(1), e(yyleng - 1); i != e; ++i) {
 
 524         char next(yytext[i]);
 
 526         if (yytext[i] == '\\')
 
 527             // XXX: support more line continuation characters
 
 529                 yylloc->end.lines(1);
 
 530                 yylloc->end.columns(yyleng - i);
 
 531             } else switch (next = yytext[++i]) {
 
 532                 case '\n': goto line;
 
 534                 case '\\': next = '\\'; break;
 
 535                 case '\'': next = '\''; break;
 
 536                 case '"': next = '"'; break;
 
 537                 case 'b': next = '\b'; break;
 
 538                 case 'f': next = '\f'; break;
 
 539                 case 'n': next = '\n'; break;
 
 540                 case 'r': next = '\r'; break;
 
 541                 case 't': next = '\t'; break;
 
 542                 case 'v': next = '\v'; break;
 
 544                 case '0': case '1': case '2': case '3':
 
 545                     if (yytext[i + 1] < '0' || yytext[i + 1] > '7')
 
 546                         next = H(yytext[i]), i += 0;
 
 547                     else if (yytext[i + 2] < '0' || yytext[i + 2] > '7')
 
 548                         next = H(yytext[i]) << 3 | H(yytext[i + 1]), i += 1;
 
 550                         next = H(yytext[i]) << 6 | H(yytext[i + 1]) << 3 | H(yytext[i + 2]), i += 2;
 
 553                 case '4': case '5': case '6': case '7':
 
 554                     if (yytext[i + 1] < '0' || yytext[i + 1] > '7')
 
 555                         next = H(yytext[i]), i += 0;
 
 557                         next = H(yytext[i]) << 3 | H(yytext[i + 1]), i += 1;
 
 561                     U(local, H(yytext[i + 1]) << 4 | H(yytext[i + 2]));
 
 574     I(string, String(value, local - value), tk::StringLiteral, hi::Constant);
 
 577 {StringPrefix}\\(x.{0,2}|u([^{].{0,3}|\{[^}]*)?|{UnicodeFail})? L E("invalid escape")
 
 578 {StringPrefix} L E("invalid string")
 
 581 {LineTerminatorSequence} yylloc->step(); yylloc->end.lines(); N
 
 584 <<EOF>> if (yyextra->auto_) { yyextra->auto_ = false; F(tk::AutoComplete, hi::Nothing); } L yyterminate();
 
 586 . L E("invalid character")
 
 590 void CYDriver::ScannerInit() {
 
 591     cylex_init(&scanner_);
 
 592     cyset_extra(this, scanner_);
 
 595 void CYDriver::ScannerDestroy() {
 
 596     cylex_destroy(scanner_);
 
 599 CYDriver::Condition CYDriver::GetCondition() {
 
 600     switch (yy_top_state(scanner_)) {
 
 602             return RegExpCondition;
 
 605             return XMLContentCondition;
 
 607             return XMLTagCondition;
 
 614 void CYDriver::SetCondition(Condition condition) {
 
 615     struct yyguts_t *yyg(reinterpret_cast<struct yyguts_t *>(scanner_));
 
 618         case RegExpCondition:
 
 622         case XMLContentCondition:
 
 625         case XMLTagCondition:
 
 634 void CYDriver::PushCondition(Condition condition) {
 
 636         case RegExpCondition:
 
 637             yy_push_state(RegExp, scanner_);
 
 640         case XMLContentCondition:
 
 641             yy_push_state(XMLContent, scanner_);
 
 643         case XMLTagCondition:
 
 644             yy_push_state(XMLTag, scanner_);
 
 652 void CYDriver::PopCondition() {
 
 653     yy_pop_state(scanner_);
 
 656 #if defined(__clang__)
 
 657 #pragma clang diagnostic pop
 
 659 // must not pop -Wunused-function
 
 660 //#pragma GCC diagnostic pop