]> git.saurik.com Git - cycript.git/blame - Scanner.lpp.in
Sort-of improve multi-line editor when in vi mode.
[cycript.git] / Scanner.lpp.in
CommitLineData
b3378a02 1/* Cycript - Optimizing JavaScript Compiler/Runtime
c1d3e52e 2 * Copyright (C) 2009-2015 Jay Freeman (saurik)
d15b59f5
JF
3*/
4
f95d2598 5/* GNU Affero General Public License, Version 3 {{{ */
d15b59f5 6/*
f95d2598
JF
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.
11
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
c15969fd 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f95d2598
JF
15 * GNU Affero General Public License for more details.
16
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/>.
b3378a02 19**/
d15b59f5
JF
20/* }}} */
21
7c4c728d 22%top{
1771224f
JF
23#if defined(__clang__)
24#pragma clang diagnostic push
1771224f 25#pragma clang diagnostic ignored "-Wdeprecated-register"
b900e1a4
JF
26#pragma clang diagnostic ignored "-Wunused-function"
27#pragma clang diagnostic ignored "-Wunused-variable"
7c4c728d
JF
28#else
29#pragma GCC diagnostic push
30#pragma GCC diagnostic ignored "-Wsign-compare"
31#pragma GCC diagnostic ignored "-Wunused-function"
32#pragma GCC diagnostic ignored "-Wunused-variable"
1771224f 33#endif
7c4c728d
JF
34}
35
36%{
1771224f 37
58afc6aa 38#define YYLTYPE CYLocation
20052ff7 39#include "Parser.hpp"
63b4c5a8 40typedef cy::parser::token tk;
693d501b 41
82a02ede
JF
42#include "Highlight.hpp"
43
5999c315 44#define YY_EXTRA_TYPE CYDriver *
db5e2840 45
82a02ede 46#define F(value, highlight) do { \
442609f7
JF
47 yyextra->newline_ = yyextra->last_; \
48 yyextra->last_ = false; \
49 yyextra->next_ = false; \
50 BEGIN(yyextra->template_.top() ? DivOrTemplateTail : Div); \
82a02ede 51 yylval->highlight_ = highlight; \
442609f7 52 return value; \
3ea7eed0
JF
53} while (false)
54
79eea88e
JF
55#define S(stack) do { \
56 if (yyextra->stack.size() == 1) \
57 E("invalid brace") \
58 yyextra->stack.pop(); \
59} while (false)
60
2c1d569a
JF
61#define P yyextra->pool_
62#define A new(P)
63#define Y P.strmemdup(yytext, yyleng)
2eb8215d 64
82a02ede 65#define I(type, Type, value, highlight) do { \
a5662a53 66 yylval->semantic_.type ## _ = A CY ## Type; \
82a02ede 67 F(value, highlight); \
2eb8215d
JF
68} while (false)
69
5befe15e 70#define N \
442609f7 71 if (yyextra->last_ && yyextra->next_) { \
b900e1a4
JF
72 yyextra->last_ = false; \
73 F(tk::NewLine, hi::Nothing); \
74 }
5befe15e 75
691e4717 76#define V(more) { \
cb02f8ae
JF
77 if (const char *nl = reinterpret_cast<const char *>(memchr(yytext, '\n', yyleng))) { \
78 unsigned lines(0); \
79 size_t left; \
80 do { \
81 ++lines; \
82 left = yyleng - (nl - yytext) - 1; \
83 nl = reinterpret_cast<const char *>(memchr(nl + 1, '\n', left)); \
84 } while (nl != NULL); \
f89aaa11 85 yylloc->step(); \
51b2dc6b
JF
86 yylloc->end.Lines(lines); \
87 yylloc->end.Columns(left); \
691e4717 88 more \
cb02f8ae
JF
89 } else L \
90}
91
51b2dc6b 92#define R yylloc->end.Columns(yyleng);
b900e1a4 93#define L yylloc->step(); R
e7ed5354 94
b900e1a4
JF
95#define H(value, highlight) do { \
96 if (yyextra->highlight_) \
97 F(value, highlight); \
98} while (false)
99
100#define M \
101 H(tk::Comment, hi::Comment);
abc79d6e 102
e31ea496
JF
103#define E(message) { \
104 CYDriver::Error error; \
105 error.location_ = *yylloc; \
106 error.message_ = "syntax error, " message; \
107 yyextra->errors_.push_back(error); \
108 yyterminate(); \
109}
110
b900e1a4 111int X(char c) {
931b816a
JF
112 if (c >= '0' && c <= '9')
113 return c - '0';
114 if (c >= 'a' && c <= 'f')
115 return c - 'a' + 10;
116 if (c >= 'A' && c <= 'F')
117 return c - 'A' + 10;
118 return -1;
119}
120
b900e1a4
JF
121template <typename Type_>
122static void U(Type_ &local, unsigned point) {
ee6c04ef
JF
123 if (false) {
124 } else if (point < 0x000080) {
125 *local++ = point;
126 } else if (point < 0x000800) {
127 *local++ = 0xc0 | point >> 0x06 & 0x1f;
128 goto one;
129 } else if (point < 0x010000) {
130 *local++ = 0xe0 | point >> 0x0c & 0x0f;
131 goto two;
132 } else if (point < 0x110000) {
133 *local++ = 0xf0 | point >> 0x12 & 0x07;
134 *local++ = 0x80 | point >> 0x0c & 0x3f;
135 two:
136 *local++ = 0x80 | point >> 0x06 & 0x3f;
137 one:
138 *local++ = 0x80 | point >> 0x00 & 0x3f;
139 } else _assert(false);
140}
141
142static void U(char *&local, const char *text, yy_size_t &i) {
143 unsigned point;
144
145 char next(text[++i]);
146 if (next != '{') {
b900e1a4 147 point = X(text[i + 0]) << 12 | X(text[i + 1]) << 8 | X(text[i + 2]) << 4 | X(text[i + 3]);
ee6c04ef
JF
148 i += 3;
149 } else {
150 point = 0;
151 for (;;) {
152 next = text[++i];
153 if (next == '}')
154 break;
b900e1a4 155 point = (point << 4) | X(next);
ee6c04ef
JF
156 }
157 }
158
159 U(local, point);
160}
161
b900e1a4
JF
162#define CYLexBufferPoint(point) do { \
163 std::back_insert_iterator<std::vector<char> > inserter(yyextra->buffer_); \
164 U(inserter, point); \
165} while (false)
166
167#define CYLexBufferUnit(value) do { \
168 yyextra->buffer_.push_back(value); \
169} while (false)
170
171#define CYLexBufferUnits(data, size) do { \
172 yyextra->buffer_.insert(yyextra->buffer_.end(), data, data + size); \
173} while (false)
174
175#define CYLexBufferStart(condition) do { \
176 yyextra->buffer_.clear(); \
177 yy_push_state(condition, yyscanner); \
178} while (false)
179
180#define CYLexBufferEnd(type, Type, value, highlight) do { \
181 yy_pop_state(yyscanner); \
442609f7 182 I(type, Type(P.strmemdup(yyextra->buffer_.data(), yyextra->buffer_.size()), yyextra->buffer_.size()), value, highlight); \
b900e1a4
JF
183} while (false)
184
e7ed5354 185#define YY_INPUT(data, value, size) { \
d3b63265 186 if (yyextra->data_.eof()) \
e7ed5354
JF
187 value = YY_NULL; \
188 else { \
d3b63265
JF
189 yyextra->data_.read(data, size); \
190 size_t copy(yyextra->data_.gcount()); \
191 value = copy == 0 ? YY_NULL : copy; \
e7ed5354
JF
192 } \
193}
194
e5332278
JF
195%}
196
197%option prefix="cy"
198%option bison-bridge
199%option bison-locations
af340def 200%option nodefault
e5332278 201%option noyywrap
7b869615 202%option noyylineno
e5332278 203%option nounput
af340def
JF
204%option nounistd
205%option 8bit
206%option backup
6c962f8b
JF
207%option batch
208%option never-interactive
af340def 209%option pointer
924f67b2 210%option reentrant
691e4717 211%option stack
e5332278 212
ee6c04ef
JF
213U1 [\x00-\x7f]
214U0 [\x80-\xbf]
215U2 [\xc2-\xdf]
216U3 [\xe0-\xef]
217U4 [\xf0-\xf4]
b900e1a4 218UN [\xc0-\xc1\xf5-\xff]
e5332278 219
ee6c04ef
JF
220HexDigit [0-9a-fA-F]
221LineTerminatorSequence \r?\n|\r|\xe2\x80[\xa8\xa9]
222WhiteSpace [\x09\x0b\x0c\x20]|\xc2\xa0|\xef\xbb\xbf
223UnicodeEscape \\u({HexDigit}{4}|\{{HexDigit}+\})
224
b900e1a4 225@include NotLineTerminator.l
c8a2a786
JF
226NoneTerminatorCharacter [^\r\n\x80-\xff]|{NotLineTerminator}
227RegExCharacter [^/[\\]{-}[\r\n\x80-\xff]|{NotLineTerminator}
228RegClsCharacter [^]\\]{-}[\r\n\x80-\xff]|{NotLineTerminator}
b900e1a4
JF
229CommentCharacter [^*/]{-}[\r\n\x80-\xff]|{NotLineTerminator}
230SingleCharacter [^'\\]{-}[\r\n\x80-\xff]|{NotLineTerminator}
231DoubleCharacter [^"\\]{-}[\r\n\x80-\xff]|{NotLineTerminator}
232PlateCharacter [^$`\\]{-}[\r\n\x80-\xff]|{NotLineTerminator}
ee6c04ef
JF
233
234@include UnicodeIDStart.l
235@include UnicodeIDContinue.l
ee6c04ef
JF
236IdentifierMore [$_]
237
238UnicodeStart {IdentifierMore}|{UnicodeIDStart}
239UnicodePart {IdentifierMore}|\xe2\x80[\x8c\x8d]|{UnicodeIDContinue}
b900e1a4 240UnicodeFail {U2}|{U3}|{U3}{U0}|{U4}|{U4}{U0}|{U4}{U0}{U0}|{UN}|{U0}
ee6c04ef
JF
241UnicodeScrap {UnicodePart}*{UnicodeFail}?
242
243IdentifierStart {UnicodeStart}|{UnicodeEscape}
244IdentifierPart {UnicodePart}|{UnicodeEscape}
245IdentifierFail {UnicodeFail}|\\(u({HexDigit}{0,3}|\{{HexDigit}*))?
246IdentifierScrap {IdentifierPart}*{IdentifierFail}?
63cd45c9 247
c8a2a786
JF
248RegularExpressionBackslashSequence \\{NoneTerminatorCharacter}
249RegularExpressionClassChars ({RegClsCharacter}|{RegularExpressionBackslashSequence})*
63cd45c9 250
691e4717
JF
251@begin E4X
252XMLNameStart [a-zA-Z_:]
253XMLNamePart [a-zA-Z0-9.-_:]
254XMLName {XMLNameStart}{XMLNamePart}*
255@end
256
c8a2a786 257%x RegularExpression
b900e1a4
JF
258%x MultiLine
259
260%x LegacySingleString
261%x LegacyDoubleString
262
263%x StrictSingleString
264%x StrictDoubleString
265%x StrictAccentString
266
697d6fd2 267%s Div
b900e1a4 268%s DivOrTemplateTail
63cd45c9 269
691e4717
JF
270@begin E4X
271%x XMLContent
272%x XMLTag
273@end
274
e5332278
JF
275%%
276
aca28f96 277 /* RegEx {{{ */
c8a2a786
JF
278<RegularExpression>{
279 \/{UnicodePart}* R CYLexBufferUnits(yytext, yyleng); CYLexBufferEnd(literal, RegEx, tk::RegularExpressionLiteral, hi::Constant);
280 \/{UnicodePart}*{UnicodeFail} R E("invalid flags")
281
282 {RegExCharacter}+ R CYLexBufferUnits(yytext, yyleng);
283 {RegExCharacter}*{UnicodeFail} R E("invalid character");
284
285 {RegularExpressionBackslashSequence} R CYLexBufferUnits(yytext, yyleng);
286 \\{UnicodeFail}? R E("invalid escape")
287
288 "["{RegularExpressionClassChars}"]" R CYLexBufferUnits(yytext, yyleng);
289 "["{RegularExpressionClassChars}\\? R E("invalid class");
290 "["{RegularExpressionClassChars}\\?{UnicodeFail} R E("invalid character");
291 "["{RegularExpressionClassChars}\\?{LineTerminatorSequence} R E("invalid newline");
292
293 (\\|{RegExCharacter}+)?{LineTerminatorSequence} R E("invalid newline");
294 <<EOF>> R E("unterminated regex")
b900e1a4 295}
aca28f96
JF
296 /* }}} */
297 /* Comment {{{ */
fc44232b 298#![^\n]* L M
abc79d6e 299\/\/[^\n]* L M
fe123f47 300
b900e1a4
JF
301\/\* L yy_push_state(MultiLine, yyscanner);
302
303<MultiLine>{
304 \**\*\/ R yy_pop_state(yyscanner); M N
51b2dc6b 305 \**{LineTerminatorSequence} yylloc->end.Lines(); yyextra->last_ = true;
b900e1a4
JF
306 \**{CommentCharacter}|\/ R
307 \**({UnicodeFail}|\*) R E("invalid comment");
308 <<EOF>> R E("invalid comment")
309}
aca28f96
JF
310 /* }}} */
311 /* Element {{{ */
cb02f8ae 312@begin E4X
82a02ede
JF
313<RegExp>"<>" L F(tk::LeftRight, hi::Structure);
314<XMLContent>"</>" L F(tk::LeftSlashRight, hi::Structure);
691e4717 315
82a02ede
JF
316<RegExp,XMLContent>\<!\[CDATA\[(\n|[^[]|\[[^[]|\[\[[^>])*]]> V() F(tk::XMLCDATA, hi::Constant);
317<RegExp,XMLContent>\<!--(\n|[^-]|-[^-])*--> V() F(tk::XMLComment, hi::Comment);
318<RegExp,XMLContent>\<?(\n|[^?]|\?[^>])*?> V() F(tk::XMLPI, hi::Meta);
691e4717 319
82a02ede
JF
320<XMLTag>"=" L F(tk::Equal, hi::Structure);
321<XMLTag>">" L F(tk::Right, hi::Structure);
322<XMLTag>"/>" L F(tk::SlashRight, hi::Structure);
323<XMLTag>"{" L F(tk::OpenBrace, hi::Structure);
691e4717 324
82a02ede
JF
325<XMLTag>\"(\n|[^"])*\"|'(\n|[^'])*' V() F(tk::XMLAttributeValue, hi::Constant);
326<XMLTag>{XMLName} L F(tk::XMLName, hi::Identifier);
327<XMLTag>[ \t\r\n] V() F(tk::XMLWhitespace, hi::Nothing);
db5e2840 328
82a02ede
JF
329<XMLContent>"{" L F(tk::OpenBrace, hi::Structure);
330<XMLContent>"<" L F(tk::Left, hi::Structure);
331<XMLContent>"</" L F(tk::LeftSlash, hi::Structure);
691e4717 332@end
aca28f96
JF
333 /* }}} */
334 /* Operator {{{ */
442609f7 335"..." L F(tk::PeriodPeriodPeriod, hi::Meta);
e31ea496 336".." L E("invalid operator")
c8a0500b 337
691e4717 338@begin E4X
442609f7
JF
339"::" L F(tk::ColonColon, hi::Operator);
340".." L F(tk::PeriodPeriod, hi::Operator);
cb02f8ae 341@end
ac9a5ce1 342
313708a9 343@begin E4X ObjectiveC
442609f7
JF
344"@" L F(tk::At, hi::Operator);
345"#" L F(tk::Pound, hi::Operator);
313708a9
JF
346@end
347
442609f7
JF
348"&" L F(tk::Ampersand, hi::Operator);
349"&&" L F(tk::AmpersandAmpersand, hi::Operator);
350"&=" L F(tk::AmpersandEqual, hi::Operator);
351"^" L F(tk::Carrot, hi::Operator);
352"^=" L F(tk::CarrotEqual, hi::Operator);
353"=" L F(tk::Equal, hi::Operator);
354"==" L F(tk::EqualEqual, hi::Operator);
355"===" L F(tk::EqualEqualEqual, hi::Operator);
356"=>" L F(yyextra->newline_ ? tk::EqualRight_ : tk::EqualRight, hi::Operator);
357"!" L F(tk::Exclamation, hi::Operator);
358"!=" L F(tk::ExclamationEqual, hi::Operator);
359"!==" L F(tk::ExclamationEqualEqual, hi::Operator);
360"-" L F(tk::Hyphen, hi::Operator);
361"-=" L F(tk::HyphenEqual, hi::Operator);
362"--" L F(yyextra->newline_ ? tk::HyphenHyphen_ : tk::HyphenHyphen, hi::Operator);
363"->" L F(tk::HyphenRight, hi::Operator);
364"<" L F(tk::Left, hi::Operator);
365"<=" L F(tk::LeftEqual, hi::Operator);
366"<<" L F(tk::LeftLeft, hi::Operator);
367"<<=" L F(tk::LeftLeftEqual, hi::Operator);
368"%" L F(tk::Percent, hi::Operator);
369"%=" L F(tk::PercentEqual, hi::Operator);
370"." L F(tk::Period, hi::Operator);
371"|" L F(tk::Pipe, hi::Operator);
372"|=" L F(tk::PipeEqual, hi::Operator);
373"||" L F(tk::PipePipe, hi::Operator);
374"+" L F(tk::Plus, hi::Operator);
375"+=" L F(tk::PlusEqual, hi::Operator);
376"++" L F(yyextra->newline_ ? tk::PlusPlus_ : tk::PlusPlus, hi::Operator);
377">" L F(tk::Right, hi::Operator);
378">=" L F(tk::RightEqual, hi::Operator);
379">>" L F(tk::RightRight, hi::Operator);
380">>=" L F(tk::RightRightEqual, hi::Operator);
381">>>" L F(tk::RightRightRight, hi::Operator);
382">>>=" L F(tk::RightRightRightEqual, hi::Operator);
383"*" L F(tk::Star, hi::Operator);
384"*=" L F(tk::StarEqual, hi::Operator);
385"~" L F(tk::Tilde, hi::Operator);
386
98711170
JF
387"/" L F(tk::Slash, hi::Operator);
388"/=" L F(tk::SlashEqual, hi::Operator);
442609f7
JF
389
390":" L F(tk::Colon, hi::Structure);
391"," L F(tk::Comma, hi::Structure);
392"?" L F(tk::Question, hi::Structure);
393";" L F(tk::SemiColon, hi::Structure);
394
395"(" L F(tk::OpenParen, hi::Structure);
396")" L F(tk::CloseParen, hi::Structure);
397
398"{" L yyextra->template_.push(false); F(yyextra->newline_ ? tk::OpenBrace_ : tk::OpenBrace, hi::Structure);
98711170 399<Div>"}" L S(template_); F(tk::CloseBrace, hi::Structure);
442609f7
JF
400
401"[" L F(tk::OpenBracket, hi::Structure);
402"]" L F(tk::CloseBracket, hi::Structure);
aca28f96
JF
403 /* }}} */
404 /* Keyword {{{ */
442609f7 405"@error" L F(tk::At_error_, hi::Error);
dc5d7cf4 406
1ba6903e 407@begin Java
442609f7 408"@class" L F(tk::At_class_, hi::Meta);
1ba6903e
JF
409@end
410
8a2eb1be 411@begin C
442609f7 412"@encode" L F(tk::At_encode_, hi::Meta);
8a2eb1be
JF
413@end
414
415@begin ObjectiveC
442609f7
JF
416"@end" L F(tk::At_end_, hi::Meta);
417"@false" L F(tk::At_false_, hi::Constant);
418"@implementation" L F(tk::At_implementation_, hi::Meta);
419"@import" L F(tk::At_import_, hi::Special);
420"@NO" L F(tk::At_NO_, hi::Constant);
421"@null" L F(tk::At_null_, hi::Constant);
422"@selector" L F(tk::At_selector_, hi::Meta);
423"@true" L F(tk::At_true_, hi::Constant);
424"@YES" L F(tk::At_YES_, hi::Constant);
aca28f96 425@end
4ea461c0 426
aca28f96
JF
427@({UnicodeStart}{UnicodeScrap}|{UnicodeFail}) L E("invalid keyword")
428 /* }}} */
429 /* Highlight {{{ */
442609f7 430"undefined" L F(tk::_undefined_, hi::Operator);
8b820c00 431
aca28f96 432@begin ObjectiveC
442609f7
JF
433"bool" L F(tk::_bool_, hi::Type);
434"BOOL" L F(tk::_BOOL_, hi::Type);
435"id" L F(tk::_id_, hi::Type);
436"nil" L F(tk::_nil_, hi::Constant);
437"NULL" L F(tk::_NULL_, hi::Constant);
438"SEL" L F(tk::_SEL_, hi::Type);
cb02f8ae 439@end
aca28f96
JF
440 /* }}} */
441 /* Reserved {{{ */
442609f7
JF
442"abstract" L /*FII*/ F(tk::_abstract_, hi::Meta);
443"await" L /*II?*/ F(tk::_await_, hi::Meta);
444"boolean" L /*FII*/ F(tk::_boolean_, hi::Type);
445"break" L /*KKK*/ F(tk::_break_, hi::Control);
446"byte" L /*FII*/ F(tk::_byte_, hi::Type);
447"case" L /*KKK*/ F(tk::_case_, hi::Control);
448"catch" L /*KKK*/ F(tk::_catch_, hi::Control);
449"char" L /*FII*/ F(tk::_char_, hi::Type);
450"class" L /*FFK*/ F(tk::_class_, hi::Meta);
451"const" L /*FFK*/ F(tk::_const_, hi::Meta);
c5b15840 452"constructor" L /*III*/ F(tk::_constructor_, hi::Special);
442609f7
JF
453"continue" L /*KKK*/ F(tk::_continue_, hi::Control);
454"debugger" L /*FKK*/ F(tk::_debugger_, hi::Meta);
455"default" L /*KKK*/ F(tk::_default_, hi::Control);
456"delete" L /*KKK*/ F(tk::_delete_, hi::Operator);
457"do" L /*KKK*/ F(tk::_do_, hi::Control);
458"double" L /*FII*/ F(tk::_double_, hi::Type);
459"else" L /*KKK*/ F(tk::_else_, hi::Control);
460"enum" L /*FFF*/ F(tk::_enum_, hi::Meta);
461"export" L /*FFK*/ F(tk::_export_, hi::Meta);
462"extends" L /*FFK*/ F(tk::_extends_, hi::Meta);
463"false" L /*LLL*/ F(tk::_false_, hi::Constant);
464"final" L /*FII*/ F(tk::_final_, hi::Meta);
465"finally" L /*KKK*/ F(tk::_finally_, hi::Control);
466"float" L /*FII*/ F(tk::_float_, hi::Type);
467"for" L /*KKK*/ F(tk::_for_, hi::Control);
9d2b125d 468"from" L /*III*/ F(tk::_from_, hi::Meta);
442609f7
JF
469"function" L /*KKK*/ F(tk::_function_, hi::Meta);
470"goto" L /*FII*/ F(tk::_goto_, hi::Control);
9d2b125d 471"get" L /*III*/ F(tk::_get_, hi::Meta);
442609f7
JF
472"if" L /*KKK*/ F(tk::_if_, hi::Control);
473"implements" L /*FSS*/ F(tk::_implements_, hi::Meta);
474"import" L /*FFK*/ F(tk::_import_, hi::Meta);
475"in" L /*KKK*/ F(yyextra->in_.top() ? tk::_in__ : tk::_in_, hi::Operator);
476"instanceof" L /*KKK*/ F(tk::_instanceof_, hi::Operator);
477"int" L /*FII*/ F(tk::_int_, hi::Type);
478"interface" L /*FSS*/ F(tk::_interface_, hi::Meta);
479"let" L /*IS?*/ F(tk::_let_, hi::Meta);
480"long" L /*FII*/ F(tk::_long_, hi::Type);
481"native" L /*FII*/ F(tk::_native_, hi::Meta);
482"new" L /*KKK*/ F(tk::_new_, hi::Operator);
483"null" L /*LLL*/ F(tk::_null_, hi::Constant);
484"package" L /*FSS*/ F(tk::_package_, hi::Meta);
485"private" L /*FSS*/ F(tk::_private_, hi::Meta);
486"protected" L /*FSS*/ F(tk::_protected_, hi::Meta);
c5b15840 487"prototype" L /*III*/ F(tk::_prototype_, hi::Special);
442609f7 488"public" L /*FSS*/ F(tk::_public_, hi::Meta);
9d2b125d
JF
489"return" L /*KKK*/ F(yyextra->return_.top() ? tk::_return__ : tk::_return_, hi::Control);
490"set" L /*III*/ F(tk::_set_, hi::Meta);
442609f7
JF
491"short" L /*FII*/ F(tk::_short_, hi::Type);
492"static" L /*FS?*/ F(tk::_static_, hi::Meta);
c5b15840 493"super" L /*FFK*/ F(yyextra->super_.top() ? tk::_super__ : tk::_super_, hi::Constant);
442609f7
JF
494"switch" L /*KKK*/ F(tk::_switch_, hi::Control);
495"synchronized" L /*FII*/ F(tk::_synchronized_, hi::Meta);
496"this" L /*KKK*/ F(tk::_this_, hi::Constant);
497"throw" L /*KKK*/ F(tk::_throw_, hi::Control);
498"throws" L /*FII*/ F(tk::_throws_, hi::Meta);
499"transient" L /*FII*/ F(tk::_transient_, hi::Meta);
500"true" L /*LLL*/ F(tk::_true_, hi::Constant);
501"try" L /*KKK*/ F(tk::_try_, hi::Control);
502"typeof" L /*KKK*/ F(tk::_typeof_, hi::Operator);
503"var" L /*KKK*/ F(tk::_var_, hi::Meta);
504"void" L /*KKK*/ F(tk::_void_, hi::Operator);
505"volatile" L /*FII*/ F(tk::_volatile_, hi::Meta);
506"while" L /*KKK*/ F(tk::_while_, hi::Control);
507"with" L /*KKK*/ F(tk::_with_, hi::Control);
9d2b125d 508"yield" L /*IS?*/ F(yyextra->yield_.top() ? tk::_yield__ : tk::_yield_, hi::Control);
442609f7
JF
509
510"auto" L F(tk::_auto_, hi::Meta);
511"each" L F(tk::_each_, hi::Control);
512"of" L F(tk::_of_, hi::Operator);
d35a3b07 513
aca28f96 514@begin C
442609f7
JF
515"extern" L F(tk::_extern_, hi::Type);
516"signed" L F(tk::_signed_, hi::Type);
517"typedef" L F(tk::_typedef_, hi::Meta);
518"unsigned" L F(tk::_unsigned_, hi::Type);
aca28f96 519@end
5d646fb5 520
aca28f96 521@begin ObjectiveC
442609f7
JF
522"NO" L F(tk::_NO_, hi::Constant);
523"YES" L F(tk::_YES_, hi::Constant);
691e4717
JF
524@end
525
aca28f96 526@begin E4X
442609f7
JF
527"namespace" L F(tk::_namespace_, hi::Meta);
528"xml" L F(tk::_xml_, hi::Meta);
aca28f96
JF
529@end
530 /* }}} */
531 /* Identifier {{{ */
442609f7 532{UnicodeStart}{UnicodePart}* L I(identifier, Identifier(Y), tk::Identifier_, hi::Identifier);
ee6c04ef 533
442609f7 534{IdentifierStart}{IdentifierPart}* L {
ee6c04ef
JF
535 char *value(A char[yyleng + 1]);
536 char *local(value);
537
538 for (yy_size_t i(0), e(yyleng); i != e; ++i) {
539 char next(yytext[i]);
540 if (next != '\\')
541 *local++ = next;
542 else
543 U(local, yytext, ++i);
544 }
545
546 *local = '\0';
547 I(identifier, Identifier(value), tk::Identifier_, hi::Identifier);
548}
549
550({IdentifierStart}{IdentifierPart}*)?{IdentifierFail} L E("invalid identifier")
aca28f96
JF
551 /* }}} */
552 /* Number {{{ */
442609f7
JF
5530[0-7]+ L I(number, Number(strtoull(yytext + 1, NULL, 8)), tk::NumericLiteral, hi::Constant);
5540[0-9]+ L I(number, Number(strtoull(yytext + 1, NULL, 10)), tk::NumericLiteral, hi::Constant);
5d646fb5 555
442609f7
JF
5560[xX][0-9a-fA-F]+ L I(number, Number(strtoull(yytext + 2, NULL, 16)), tk::NumericLiteral, hi::Constant);
5570[oO][0-7]+ L I(number, Number(strtoull(yytext + 2, NULL, 8)), tk::NumericLiteral, hi::Constant);
5580[bB][0-1]+ L I(number, Number(strtoull(yytext + 2, NULL, 2)), tk::NumericLiteral, hi::Constant);
5befe15e 559
442609f7 560(\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?)([eE][+-]?[0-9]+)? L I(number, Number(strtod(yytext, NULL)), tk::NumericLiteral, hi::Constant);
ee6c04ef
JF
561(\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?)[eE][+-]?{IdentifierScrap} L E("invalid exponent")
562(\.?[0-9]|(0|[1-9][0-9]*)\.){IdentifierScrap} L E("invalid number")
aca28f96
JF
563 /* }}} */
564 /* String {{{ */
b900e1a4
JF
565\' L CYLexBufferStart(LegacySingleString);
566<LegacySingleString,StrictSingleString>{
567 \' R CYLexBufferEnd(string, String, tk::StringLiteral, hi::Constant);
568 {SingleCharacter}+ R CYLexBufferUnits(yytext, yyleng);
569 {SingleCharacter}*{UnicodeFail} R E("invalid character");
570 {LineTerminatorSequence} R E("invalid newline");
571}
931b816a 572
b900e1a4
JF
573\" L CYLexBufferStart(LegacyDoubleString);
574<LegacyDoubleString,StrictDoubleString>{
575 \" R CYLexBufferEnd(string, String, tk::StringLiteral, hi::Constant);
576 {DoubleCharacter}+ R CYLexBufferUnits(yytext, yyleng);
577 {DoubleCharacter}*{UnicodeFail} R E("invalid character");
578 {LineTerminatorSequence} R E("invalid newline");
579}
580 /* }}} */
581 /* Template {{{ */
582"`" L yyextra->tail_ = false; CYLexBufferStart(StrictAccentString);
98711170 583<DivOrTemplateTail>"}" L yyextra->tail_ = true; S(template_); CYLexBufferStart(StrictAccentString);
931b816a 584
b900e1a4
JF
585<StrictAccentString>{
586 "`" R CYLexBufferEnd(string, String, yyextra->tail_ ? tk::TemplateTail : tk::NoSubstitutionTemplate, hi::Constant);
587 "${" R yyextra->template_.push(true); CYLexBufferEnd(string, String, yyextra->tail_ ? tk::TemplateMiddle : tk::TemplateHead, hi::Constant);
a703494a 588
b900e1a4
JF
589 "$" R CYLexBufferUnit('$');
590
591 {PlateCharacter}+ R CYLexBufferUnits(yytext, yyleng);
592 {PlateCharacter}*{UnicodeFail} R E("invalid character");
593 {LineTerminatorSequence} R E("invalid newline");
594}
595 /* }}} */
596 /* Escapes {{{ */
597<LegacySingleString,LegacyDoubleString>{
598 \\[0-3][0-7][0-7] R CYLexBufferPoint(X(yytext[1]) << 6 | X(yytext[2]) << 3 | X(yytext[3]));
599 \\[0-7][0-7] R CYLexBufferUnit(X(yytext[1]) << 3 | X(yytext[2]));
600 \\[0-7] R CYLexBufferUnit(X(yytext[1]));
601}
931b816a 602
b900e1a4
JF
603<StrictSingleString,StrictDoubleString,StrictAccentString>{
604 \\0[0-7] R E("legacy escape");
605 \\0 R CYLexBufferUnit('\0');
606}
ee6c04ef 607
b900e1a4
JF
608<LegacySingleString,LegacyDoubleString,StrictSingleString,StrictDoubleString,StrictAccentString>{
609 \\b R CYLexBufferUnit('\b');
610 \\f R CYLexBufferUnit('\f');
611 \\n R CYLexBufferUnit('\n');
612 \\r R CYLexBufferUnit('\r');
613 \\t R CYLexBufferUnit('\t');
614 \\v R CYLexBufferUnit('\v');
931b816a 615
b900e1a4
JF
616 \\x{HexDigit}{2} R CYLexBufferPoint(X(yytext[2]) << 4 | X(yytext[3]));
617
618 \\u{HexDigit}{4} R CYLexBufferPoint(X(yytext[2]) << 12 | X(yytext[3]) << 8 | X(yytext[4]) << 4 | X(yytext[5]));
619
620 \\u\{{HexDigit}+\} R {
621 unsigned point(0);
622 for (yy_size_t i(3); i != yyleng - 1; ++i)
623 point = point << 4 | X(yytext[i]);
624 CYLexBufferPoint(point);
931b816a
JF
625 }
626
51b2dc6b 627 \\{LineTerminatorSequence} yylloc->end.Lines();
b900e1a4 628 \\(.|{NotLineTerminator}) R CYLexBufferUnits(yytext + 1, yyleng - 1);
5befe15e 629
b900e1a4
JF
630 \\(x{HexDigit}{0,1}|u({HexDigit}{0,3}|\{{HexDigit}*)|{UnicodeFail})? R E("invalid escape");
631 <<EOF>> R E("invalid string");
632}
aca28f96 633 /* }}} */
e31ea496 634
51b2dc6b 635{LineTerminatorSequence} yylloc->step(); yylloc->end.Lines(); yyextra->last_ = true; N
ee6c04ef 636{WhiteSpace} L
7e5391fd 637
82a02ede 638<<EOF>> if (yyextra->auto_) { yyextra->auto_ = false; F(tk::AutoComplete, hi::Nothing); } L yyterminate();
94d55b5c 639
ee6c04ef 640. L E("invalid character")
924f67b2
JF
641
642%%
643
98711170
JF
644#undef yyextra
645#define yyextra this
646#define yyscanner scanner_
647
5999c315 648void CYDriver::ScannerInit() {
924f67b2
JF
649 cylex_init(&scanner_);
650 cyset_extra(this, scanner_);
651}
652
5999c315 653void CYDriver::ScannerDestroy() {
924f67b2
JF
654 cylex_destroy(scanner_);
655}
63cd45c9 656
98711170
JF
657void CYDriver::SetRegEx(bool equal) {
658 CYLexBufferStart(RegularExpression);
659 CYLexBufferUnit('/');
660 if (equal)
661 CYLexBufferUnit('=');
662}
663
691e4717 664void CYDriver::SetCondition(Condition condition) {
63cd45c9
JF
665 struct yyguts_t *yyg(reinterpret_cast<struct yyguts_t *>(scanner_));
666
667 switch (condition) {
691e4717
JF
668@begin E4X
669 case XMLContentCondition:
670 BEGIN(XMLContent);
671 break;
672 case XMLTagCondition:
673 BEGIN(XMLTag);
674 break;
675@end
63cd45c9
JF
676 default:
677 _assert(false);
678 }
679}
691e4717
JF
680
681void CYDriver::PushCondition(Condition condition) {
682 switch (condition) {
691e4717
JF
683@begin E4X
684 case XMLContentCondition:
685 yy_push_state(XMLContent, scanner_);
686 break;
687 case XMLTagCondition:
688 yy_push_state(XMLTag, scanner_);
689 break;
690@end
691 default:
692 _assert(false);
693 }
694}
695
696void CYDriver::PopCondition() {
697 yy_pop_state(scanner_);
698}
1771224f 699
8a392978
JF
700bool CYLexerHighlight(hi::Value &highlight, CYLocation &location, void *scanner) {
701 YYSTYPE value;
702 if (cylex(&value, &location, scanner) == 0)
703 return false;
704 highlight = value.highlight_;
705 return true;
706}
707
1771224f
JF
708#if defined(__clang__)
709#pragma clang diagnostic pop
7c4c728d
JF
710#else
711// must not pop -Wunused-function
712//#pragma GCC diagnostic pop
1771224f 713#endif