]> git.saurik.com Git - cycript.git/blame - Cycript.l.in
Standardize grammar rule ordering: *_, *, *Opt.
[cycript.git] / Cycript.l.in
CommitLineData
b3378a02
JF
1/* Cycript - Optimizing JavaScript Compiler/Runtime
2 * Copyright (C) 2009-2010 Jay Freeman (saurik)
d15b59f5
JF
3*/
4
b3378a02 5/* GNU Lesser General Public License, Version 3 {{{ */
d15b59f5 6/*
b3378a02
JF
7 * Cycript is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
d15b59f5 11 *
b3378a02
JF
12 * Cycript is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 * License for more details.
d15b59f5 16 *
b3378a02
JF
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with Cycript. If not, see <http://www.gnu.org/licenses/>.
19**/
d15b59f5
JF
20/* }}} */
21
2155ab92 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 */
cb02f8ae 23
d15b59f5 24%{
cac61857 25#define YYLTYPE cy::location
63b4c5a8
JF
26#include "Cycript.tab.hh"
27typedef cy::parser::token tk;
693d501b 28
5999c315 29#define YY_EXTRA_TYPE CYDriver *
db5e2840 30
2eb8215d
JF
31#define A new($pool)
32#define Y apr_pstrmemdup($pool, yytext, yyleng)
33
34#define I(type, Type, Name) do { \
35 yylval->type ## _ = A CY ## Type; \
36 return tk::Name; \
37} while (false)
38
697d6fd2 39#define T yylval->newline_ = yyextra->state_ == CYNewLine; BEGIN(Div);
db5e2840
JF
40#define C T yyextra->state_ = CYClear;
41#define R T yyextra->state_ = CYRestricted;
5befe15e 42
e4676127 43#define E L C I(literal, RegEx(Y), RegularExpressionLiteral);
63cd45c9 44
5befe15e
JF
45#define N \
46 if (yyextra->state_ != CYNewLine) { \
2eb8215d
JF
47 if (yyextra->state_ != CYRestricted) \
48 yyextra->state_ = CYNewLine; \
49 else { \
5befe15e
JF
50 yyextra->state_ = CYClear; \
51 return tk::NewLine; \
2eb8215d 52 } \
5befe15e
JF
53 }
54
691e4717 55#define V(more) { \
cb02f8ae
JF
56 if (const char *nl = reinterpret_cast<const char *>(memchr(yytext, '\n', yyleng))) { \
57 unsigned lines(0); \
58 size_t left; \
59 do { \
60 ++lines; \
61 left = yyleng - (nl - yytext) - 1; \
62 nl = reinterpret_cast<const char *>(memchr(nl + 1, '\n', left)); \
63 } while (nl != NULL); \
64 yylloc->end.lines(lines); \
65 yylloc->end.columns(left); \
66 yylloc->step(); \
691e4717 67 more \
cb02f8ae
JF
68 } else L \
69}
70
5befe15e
JF
71#define L { \
72 yylloc->step(); \
73 yylloc->columns(yyleng); \
74}
e7ed5354 75
931b816a
JF
76int H(char c) {
77 if (c >= '0' && c <= '9')
78 return c - '0';
79 if (c >= 'a' && c <= 'f')
80 return c - 'a' + 10;
81 if (c >= 'A' && c <= 'F')
82 return c - 'A' + 10;
83 return -1;
84}
85
e7ed5354 86#define YY_INPUT(data, value, size) { \
48e3be8a
JF
87 if (yyextra->file_ != NULL) { \
88 size_t copy(fread(data, 1, size, yyextra->file_)); \
89 value = copy == 0 ? YY_NULL : copy; \
90 } else if (yyextra->size_ == 0) \
e7ed5354
JF
91 value = YY_NULL; \
92 else { \
7c6c5b0a
JF
93 size_t copy(size); \
94 copy = (std::min(copy, yyextra->size_)); \
e7ed5354
JF
95 memcpy(data, yyextra->data_, copy); \
96 yyextra->data_ += copy; \
97 yyextra->size_ -= copy; \
98 value = copy; \
99 } \
100}
101
e5332278
JF
102%}
103
104%option prefix="cy"
105%option bison-bridge
106%option bison-locations
107%option noyywrap
108%option yylineno
109%option nounput
110%option interactive
924f67b2 111%option reentrant
691e4717 112%option stack
e5332278 113
2bf24581 114Exponent [eE][+-]?[0-9]+
367eebb1 115Escape \\[\\'"bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|\\\n
e5332278 116
63cd45c9
JF
117IdentifierStart [a-zA-Z$_]
118IdentifierPart [a-zA-Z$_0-9]
119
120NonTerminator [^\n]
121BackslashSequence \\{NonTerminator}
122RegularExpressionFirstChar [^\n*\\/]|{BackslashSequence}
123RegularExpressionChar [^\n\\/]|{BackslashSequence}
124RegularExpressionFlags {IdentifierPart}*
125RegularExpressionChars {RegularExpressionChar}*
697d6fd2 126RegularExpressionBody {RegularExpressionFirstChar}{RegularExpressionChars}
63cd45c9 127
691e4717
JF
128@begin E4X
129XMLNameStart [a-zA-Z_:]
130XMLNamePart [a-zA-Z0-9.-_:]
131XMLName {XMLNameStart}{XMLNamePart}*
132@end
133
697d6fd2
JF
134%s Div
135%s RegExp
63cd45c9 136
691e4717
JF
137@begin E4X
138%x XMLContent
139%x XMLTag
140@end
141
e5332278
JF
142%%
143
e4676127 144<RegExp>\/{RegularExpressionBody}\/{RegularExpressionFlags} E
63cd45c9 145
66fb559f 146\/\/[^\n]* L
fe123f47
JF
147
148 /* http://ostermiller.org/findcomment.html */
149 /* XXX: unify these two rules using !? */
2eb8215d 150\/\*!([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/ V() C I(comment, Comment(Y), Comment);
fe123f47 151\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/ V(N)
66fb559f 152
cb02f8ae 153@begin E4X
691e4717
JF
154<RegExp>"<>" L return tk::LeftRight;
155<XMLContent>"</>" L return tk::LeftSlashRight;
156
157<RegExp,XMLContent>\<!\[CDATA\[(\n|[^[]|\[[^[]|\[\[[^>])*]]> V() return tk::XMLCDATA;
158<RegExp,XMLContent>\<!--(\n|[^-]|-[^-])*--> V() return tk::XMLComment;
159<RegExp,XMLContent>\<?(\n|[^?]|\?[^>])*?> V() return tk::XMLPI;
160
161<XMLTag>"=" L return tk::Equal;
162<XMLTag>">" L return tk::Right;
163<XMLTag>"/>" L return tk::SlashRight;
164<XMLTag>"{" L return tk::OpenBrace;
165
2eb8215d 166<XMLTag>\"(\n|[^"])*\"|'(\n|[^'])*' V() return tk::XMLAttributeValue;
691e4717
JF
167<XMLTag>{XMLName} L return tk::XMLName;
168<XMLTag>[ \t\r\n] V() return tk::XMLWhitespace;
db5e2840 169
691e4717
JF
170<XMLContent>"{" L return tk::OpenBrace;
171<XMLContent>"<" L return tk::Left;
172<XMLContent>"</" L return tk::LeftSlash;
173@end
174
c8a0500b
JF
175"..." L C return tk::PeriodPeriodPeriod;
176
691e4717 177@begin E4X
cb02f8ae 178"::" L C return tk::ColonColon;
cb02f8ae 179".." L C return tk::PeriodPeriod;
cb02f8ae 180@end
ac9a5ce1 181
313708a9
JF
182@begin E4X ObjectiveC
183"@" L C return tk::At;
184@end
185
5befe15e
JF
186"&" L C return tk::Ampersand;
187"&&" L C return tk::AmpersandAmpersand;
188"&=" L C return tk::AmpersandEqual;
189"^" L C return tk::Carrot;
190"^=" L C return tk::CarrotEqual;
191"=" L C return tk::Equal;
192"==" L C return tk::EqualEqual;
193"===" L C return tk::EqualEqualEqual;
194"!" L C return tk::Exclamation;
195"!=" L C return tk::ExclamationEqual;
196"!==" L C return tk::ExclamationEqualEqual;
197"-" L C return tk::Hyphen;
198"-=" L C return tk::HyphenEqual;
199"--" L C return yylval->newline_ ? tk::HyphenHyphen_ : tk::HyphenHyphen;
200"->" L C return tk::HyphenRight;
201"<" L C return tk::Left;
202"<=" L C return tk::LeftEqual;
203"<<" L C return tk::LeftLeft;
204"<<=" L C return tk::LeftLeftEqual;
205"%" L C return tk::Percent;
206"%=" L C return tk::PercentEqual;
207"." L C return tk::Period;
208"|" L C return tk::Pipe;
209"|=" L C return tk::PipeEqual;
210"||" L C return tk::PipePipe;
211"+" L C return tk::Plus;
212"+=" L C return tk::PlusEqual;
213"++" L C return yylval->newline_ ? tk::PlusPlus_ : tk::PlusPlus;
214">" L C return tk::Right;
215">=" L C return tk::RightEqual;
216">>" L C return tk::RightRight;
217">>=" L C return tk::RightRightEqual;
218">>>" L C return tk::RightRightRight;
219">>>=" L C return tk::RightRightRightEqual;
5befe15e
JF
220"*" L C return tk::Star;
221"*=" L C return tk::StarEqual;
222"~" L C return tk::Tilde;
223
697d6fd2
JF
224<Div>"/" L C return tk::Slash;
225<Div>"/=" L C return tk::SlashEqual;
226
5befe15e
JF
227":" L C return tk::Colon;
228"," L C return tk::Comma;
229"?" L C return tk::Question;
230";" L C return tk::SemiColon;
231
232"(" L C return tk::OpenParen;
233")" L C return tk::CloseParen;
234
6c093cce 235"{" L C return yylval->newline_ ? tk::OpenBrace_ : tk::OpenBrace;
5befe15e
JF
236"}" L C return tk::CloseBrace;
237
238"[" L C return tk::OpenBracket;
239"]" L C return tk::CloseBracket;
240
1ba6903e
JF
241@begin Java
242"@class" L C return tk::AtClass;
243@end
244
cb02f8ae 245@begin ObjectiveC
1ba6903e
JF
246"@end" L C return tk::AtEnd;
247"@implementation" L C return tk::AtImplementation;
248"@import" L C return tk::AtImport;
249"@selector" L C return tk::AtSelector;
cb02f8ae 250@end
d35a3b07 251
2eb8215d
JF
252"false" L C I(false, False(), False);
253"null" L C I(null, Null(), Null);
254"true" L C I(true, True(), True);
255
256"break" L R I(word, Word("break"), Break);
257"case" L C I(word, Word("case"), Case);
258"catch" L C I(word, Word("catch"), Catch);
259"continue" L R I(word, Word("continue"), Continue);
260"default" L C I(word, Word("default"), Default);
261"delete" L C I(word, Word("delete"), Delete);
262"do" L C I(word, Word("do"), Do);
263"else" L C I(word, Word("else"), Else);
264"finally" L C I(word, Word("finally"), Finally);
265"for" L C I(word, Word("for"), For);
266"function" L C I(word, Word("function"), Function);
267"if" L C I(word, Word("if"), If);
268"in" L C I(word, Word("in"), In);
269"instanceof" L C I(word, Word("instanceof"), InstanceOf);
270"new" L C I(word, Word("new"), New);
271"return" L R I(word, Word("return"), Return);
272"switch" L C I(word, Word("switch"), Switch);
273"this" L C I(this, This(), This);
274"throw" L R I(word, Word("throw"), Throw);
275"try" L C I(word, Word("try"), Try);
276"typeof" L C I(word, Word("typeof"), TypeOf);
277"var" L C I(word, Word("var"), Var);
278"void" L C I(word, Word("void"), Void);
279"while" L C I(word, Word("while"), While);
280"with" L C I(word, Word("with"), With);
281
282"debugger" L C I(word, Word("debugger"), Debugger);
283
284"const" L C I(word, Word("const"), Const);
285
286"class" L C I(word, Word("class"), Class);
287"enum" L C I(word, Word("enum"), Enum);
288"export" L C I(word, Word("export"), Export);
289"extends" L C I(word, Word("extends"), Extends);
290"import" L C I(word, Word("import"), Import);
291"super" L C I(word, Word("super"), Super);
292
293"implements" L C I(identifier, Identifier("implements"), Implements);
294"interface" L C I(identifier, Identifier("interface"), Interface);
295"package" L C I(identifier, Identifier("package"), Package);
296"private" L C I(identifier, Identifier("private"), Private);
297"protected" L C I(identifier, Identifier("protected"), Protected);
298"public" L C I(identifier, Identifier("public"), Public);
299"static" L C I(identifier, Identifier("static"), Static);
300
301"abstract" L C I(identifier, Identifier("abstract"), Abstract);
302"boolean" L C I(identifier, Identifier("boolean"), Boolean);
303"byte" L C I(identifier, Identifier("byte"), Byte);
304"char" L C I(identifier, Identifier("char"), Char);
305"double" L C I(identifier, Identifier("double"), Double);
306"final" L C I(identifier, Identifier("final"), Final);
307"float" L C I(identifier, Identifier("float"), Float);
308"goto" L C I(identifier, Identifier("goto"), Goto);
309"int" L C I(identifier, Identifier("int"), Int);
310"long" L C I(identifier, Identifier("long"), Long);
311"native" L C I(identifier, Identifier("native"), Native);
312"short" L C I(identifier, Identifier("short"), Short);
313"synchronized" L C I(identifier, Identifier("synchronized"), Synchronized);
314"throws" L C I(identifier, Identifier("throws"), Throws);
315"transient" L C I(identifier, Identifier("transient"), Transient);
316"volatile" L C I(identifier, Identifier("volatile"), Volatile);
317
318"let" L C I(identifier, Identifier("let"), Let);
319"yield" L C I(identifier, Identifier("yield"), Yield);
320
321"each" L C I(identifier, Identifier("each"), Each);
5d646fb5 322
691e4717 323@begin E4X
2eb8215d
JF
324"namespace" L C I(identifier, Identifier("namespace"), Namespace);
325"xml" L C I(identifier, Identifier("xml"), XML);
691e4717
JF
326@end
327
2eb8215d 328{IdentifierStart}{IdentifierPart}* L C I(identifier, Identifier(Y), Identifier_);
5d646fb5 329
2eb8215d 330(\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?){Exponent}? L C I(number, Number(strtod(yytext, NULL)), NumericLiteral);
5d646fb5 331
2eb8215d
JF
3320[xX][0-9a-fA-F]+ L C I(number, Number(strtoull(yytext + 2, NULL, 16)), NumericLiteral);
3330[0-7]+ L C I(number, Number(strtoull(yytext + 1, NULL, 8)), NumericLiteral);
3340[bB][0-1]+ L C I(number, Number(strtoull(yytext + 2, NULL, 2)), NumericLiteral);
5befe15e 335
931b816a 336\"([^"\\\n]|{Escape})*\"|'([^'\\\n]|{Escape})*' L C {
2eb8215d 337 char *value(A char[yyleng]);
931b816a
JF
338 char *local(value);
339
66f8d960 340 for (yy_size_t i(1), e(yyleng - 1); i != e; ++i) {
931b816a
JF
341 char next(yytext[i]);
342
343 if (yytext[i] == '\\')
344 switch (next = yytext[++i]) {
367eebb1 345 case '\n': continue;
931b816a
JF
346 case '\\': next = '\\'; break;
347 case '\'': next = '\''; break;
348 case '"': next = '"'; break;
349 case 'b': next = '\b'; break;
350 case 'f': next = '\f'; break;
351 case 'n': next = '\n'; break;
352 case 'r': next = '\r'; break;
353 case 't': next = '\t'; break;
354 case 'v': next = '\v'; break;
355 case '0': next = '\0'; break;
356
357 case 'x':
358 next = H(yytext[i + 1]) << 4 | H(yytext[i + 2]);
359 i += 2;
360 break;
361 }
362
363 *local++ = next;
364 }
365
366 *local = '\0';
2eb8215d 367 I(string, String(value, local - value), StringLiteral);
931b816a 368}
5befe15e 369
b10bd496 370\r?\n yylloc->end.lines(); yylloc->step(); N
5befe15e
JF
371
372[ \t] L
7e5391fd 373
972c6054 374<<EOF>> if (yyextra->auto_) { yyextra->auto_ = false; return tk::AutoComplete; } L yyterminate();
94d55b5c 375
48e3be8a 376. L {
94d55b5c
JF
377 CYDriver::Error error;
378 error.location_ = *yylloc;
379 error.message_ = "syntax error, unknown token";
380 yyextra->errors_.push_back(error);
381 yyterminate();
382}
924f67b2
JF
383
384%%
385
5999c315 386void CYDriver::ScannerInit() {
924f67b2
JF
387 cylex_init(&scanner_);
388 cyset_extra(this, scanner_);
389}
390
5999c315 391void CYDriver::ScannerDestroy() {
924f67b2
JF
392 cylex_destroy(scanner_);
393}
63cd45c9 394
691e4717
JF
395CYDriver::Condition CYDriver::GetCondition() {
396 switch (yy_top_state(scanner_)) {
397 case RegExp:
398 return RegExpCondition;
399@begin E4X
400 case XMLContent:
401 return XMLContentCondition;
402 case XMLTag:
403 return XMLTagCondition;
404@end
405 default:
406 _assert(false);
407 }
408}
409
410void CYDriver::SetCondition(Condition condition) {
63cd45c9
JF
411 struct yyguts_t *yyg(reinterpret_cast<struct yyguts_t *>(scanner_));
412
413 switch (condition) {
697d6fd2
JF
414 case RegExpCondition:
415 BEGIN(RegExp);
63cd45c9 416 break;
691e4717
JF
417@begin E4X
418 case XMLContentCondition:
419 BEGIN(XMLContent);
420 break;
421 case XMLTagCondition:
422 BEGIN(XMLTag);
423 break;
424@end
63cd45c9
JF
425 default:
426 _assert(false);
427 }
428}
691e4717
JF
429
430void CYDriver::PushCondition(Condition condition) {
431 switch (condition) {
432 case RegExpCondition:
433 yy_push_state(RegExp, scanner_);
434 break;
435@begin E4X
436 case XMLContentCondition:
437 yy_push_state(XMLContent, scanner_);
438 break;
439 case XMLTagCondition:
440 yy_push_state(XMLTag, scanner_);
441 break;
442@end
443 default:
444 _assert(false);
445 }
446}
447
448void CYDriver::PopCondition() {
449 yy_pop_state(scanner_);
450}