]> git.saurik.com Git - cycript.git/blame - Cycript.l.in
Make protocol_copyPropertyList return an array of properties.
[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
175@begin E4X
cb02f8ae 176"::" L C return tk::ColonColon;
cb02f8ae 177".." L C return tk::PeriodPeriod;
cb02f8ae 178@end
ac9a5ce1 179
313708a9
JF
180@begin E4X ObjectiveC
181"@" L C return tk::At;
182@end
183
5befe15e
JF
184"&" L C return tk::Ampersand;
185"&&" L C return tk::AmpersandAmpersand;
186"&=" L C return tk::AmpersandEqual;
187"^" L C return tk::Carrot;
188"^=" L C return tk::CarrotEqual;
189"=" L C return tk::Equal;
190"==" L C return tk::EqualEqual;
191"===" L C return tk::EqualEqualEqual;
192"!" L C return tk::Exclamation;
193"!=" L C return tk::ExclamationEqual;
194"!==" L C return tk::ExclamationEqualEqual;
195"-" L C return tk::Hyphen;
196"-=" L C return tk::HyphenEqual;
197"--" L C return yylval->newline_ ? tk::HyphenHyphen_ : tk::HyphenHyphen;
198"->" L C return tk::HyphenRight;
199"<" L C return tk::Left;
200"<=" L C return tk::LeftEqual;
201"<<" L C return tk::LeftLeft;
202"<<=" L C return tk::LeftLeftEqual;
203"%" L C return tk::Percent;
204"%=" L C return tk::PercentEqual;
205"." L C return tk::Period;
206"|" L C return tk::Pipe;
207"|=" L C return tk::PipeEqual;
208"||" L C return tk::PipePipe;
209"+" L C return tk::Plus;
210"+=" L C return tk::PlusEqual;
211"++" L C return yylval->newline_ ? tk::PlusPlus_ : tk::PlusPlus;
212">" L C return tk::Right;
213">=" L C return tk::RightEqual;
214">>" L C return tk::RightRight;
215">>=" L C return tk::RightRightEqual;
216">>>" L C return tk::RightRightRight;
217">>>=" L C return tk::RightRightRightEqual;
5befe15e
JF
218"*" L C return tk::Star;
219"*=" L C return tk::StarEqual;
220"~" L C return tk::Tilde;
221
697d6fd2
JF
222<Div>"/" L C return tk::Slash;
223<Div>"/=" L C return tk::SlashEqual;
224
5befe15e
JF
225":" L C return tk::Colon;
226"," L C return tk::Comma;
227"?" L C return tk::Question;
228";" L C return tk::SemiColon;
229
230"(" L C return tk::OpenParen;
231")" L C return tk::CloseParen;
232
6c093cce 233"{" L C return yylval->newline_ ? tk::OpenBrace_ : tk::OpenBrace;
5befe15e
JF
234"}" L C return tk::CloseBrace;
235
236"[" L C return tk::OpenBracket;
237"]" L C return tk::CloseBracket;
238
1ba6903e
JF
239@begin Java
240"@class" L C return tk::AtClass;
241@end
242
cb02f8ae 243@begin ObjectiveC
1ba6903e
JF
244"@end" L C return tk::AtEnd;
245"@implementation" L C return tk::AtImplementation;
246"@import" L C return tk::AtImport;
247"@selector" L C return tk::AtSelector;
cb02f8ae 248@end
d35a3b07 249
2eb8215d
JF
250"false" L C I(false, False(), False);
251"null" L C I(null, Null(), Null);
252"true" L C I(true, True(), True);
253
254"break" L R I(word, Word("break"), Break);
255"case" L C I(word, Word("case"), Case);
256"catch" L C I(word, Word("catch"), Catch);
257"continue" L R I(word, Word("continue"), Continue);
258"default" L C I(word, Word("default"), Default);
259"delete" L C I(word, Word("delete"), Delete);
260"do" L C I(word, Word("do"), Do);
261"else" L C I(word, Word("else"), Else);
262"finally" L C I(word, Word("finally"), Finally);
263"for" L C I(word, Word("for"), For);
264"function" L C I(word, Word("function"), Function);
265"if" L C I(word, Word("if"), If);
266"in" L C I(word, Word("in"), In);
267"instanceof" L C I(word, Word("instanceof"), InstanceOf);
268"new" L C I(word, Word("new"), New);
269"return" L R I(word, Word("return"), Return);
270"switch" L C I(word, Word("switch"), Switch);
271"this" L C I(this, This(), This);
272"throw" L R I(word, Word("throw"), Throw);
273"try" L C I(word, Word("try"), Try);
274"typeof" L C I(word, Word("typeof"), TypeOf);
275"var" L C I(word, Word("var"), Var);
276"void" L C I(word, Word("void"), Void);
277"while" L C I(word, Word("while"), While);
278"with" L C I(word, Word("with"), With);
279
280"debugger" L C I(word, Word("debugger"), Debugger);
281
282"const" L C I(word, Word("const"), Const);
283
284"class" L C I(word, Word("class"), Class);
285"enum" L C I(word, Word("enum"), Enum);
286"export" L C I(word, Word("export"), Export);
287"extends" L C I(word, Word("extends"), Extends);
288"import" L C I(word, Word("import"), Import);
289"super" L C I(word, Word("super"), Super);
290
291"implements" L C I(identifier, Identifier("implements"), Implements);
292"interface" L C I(identifier, Identifier("interface"), Interface);
293"package" L C I(identifier, Identifier("package"), Package);
294"private" L C I(identifier, Identifier("private"), Private);
295"protected" L C I(identifier, Identifier("protected"), Protected);
296"public" L C I(identifier, Identifier("public"), Public);
297"static" L C I(identifier, Identifier("static"), Static);
298
299"abstract" L C I(identifier, Identifier("abstract"), Abstract);
300"boolean" L C I(identifier, Identifier("boolean"), Boolean);
301"byte" L C I(identifier, Identifier("byte"), Byte);
302"char" L C I(identifier, Identifier("char"), Char);
303"double" L C I(identifier, Identifier("double"), Double);
304"final" L C I(identifier, Identifier("final"), Final);
305"float" L C I(identifier, Identifier("float"), Float);
306"goto" L C I(identifier, Identifier("goto"), Goto);
307"int" L C I(identifier, Identifier("int"), Int);
308"long" L C I(identifier, Identifier("long"), Long);
309"native" L C I(identifier, Identifier("native"), Native);
310"short" L C I(identifier, Identifier("short"), Short);
311"synchronized" L C I(identifier, Identifier("synchronized"), Synchronized);
312"throws" L C I(identifier, Identifier("throws"), Throws);
313"transient" L C I(identifier, Identifier("transient"), Transient);
314"volatile" L C I(identifier, Identifier("volatile"), Volatile);
315
316"let" L C I(identifier, Identifier("let"), Let);
317"yield" L C I(identifier, Identifier("yield"), Yield);
318
319"each" L C I(identifier, Identifier("each"), Each);
5d646fb5 320
691e4717 321@begin E4X
2eb8215d
JF
322"namespace" L C I(identifier, Identifier("namespace"), Namespace);
323"xml" L C I(identifier, Identifier("xml"), XML);
691e4717
JF
324@end
325
2eb8215d 326{IdentifierStart}{IdentifierPart}* L C I(identifier, Identifier(Y), Identifier_);
5d646fb5 327
2eb8215d 328(\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?){Exponent}? L C I(number, Number(strtod(yytext, NULL)), NumericLiteral);
5d646fb5 329
2eb8215d
JF
3300[xX][0-9a-fA-F]+ L C I(number, Number(strtoull(yytext + 2, NULL, 16)), NumericLiteral);
3310[0-7]+ L C I(number, Number(strtoull(yytext + 1, NULL, 8)), NumericLiteral);
3320[bB][0-1]+ L C I(number, Number(strtoull(yytext + 2, NULL, 2)), NumericLiteral);
5befe15e 333
931b816a 334\"([^"\\\n]|{Escape})*\"|'([^'\\\n]|{Escape})*' L C {
2eb8215d 335 char *value(A char[yyleng]);
931b816a
JF
336 char *local(value);
337
66f8d960 338 for (yy_size_t i(1), e(yyleng - 1); i != e; ++i) {
931b816a
JF
339 char next(yytext[i]);
340
341 if (yytext[i] == '\\')
342 switch (next = yytext[++i]) {
367eebb1 343 case '\n': continue;
931b816a
JF
344 case '\\': next = '\\'; break;
345 case '\'': next = '\''; break;
346 case '"': next = '"'; break;
347 case 'b': next = '\b'; break;
348 case 'f': next = '\f'; break;
349 case 'n': next = '\n'; break;
350 case 'r': next = '\r'; break;
351 case 't': next = '\t'; break;
352 case 'v': next = '\v'; break;
353 case '0': next = '\0'; break;
354
355 case 'x':
356 next = H(yytext[i + 1]) << 4 | H(yytext[i + 2]);
357 i += 2;
358 break;
359 }
360
361 *local++ = next;
362 }
363
364 *local = '\0';
2eb8215d 365 I(string, String(value, local - value), StringLiteral);
931b816a 366}
5befe15e 367
b10bd496 368\r?\n yylloc->end.lines(); yylloc->step(); N
5befe15e
JF
369
370[ \t] L
7e5391fd 371
972c6054 372<<EOF>> if (yyextra->auto_) { yyextra->auto_ = false; return tk::AutoComplete; } L yyterminate();
94d55b5c 373
48e3be8a 374. L {
94d55b5c
JF
375 CYDriver::Error error;
376 error.location_ = *yylloc;
377 error.message_ = "syntax error, unknown token";
378 yyextra->errors_.push_back(error);
379 yyterminate();
380}
924f67b2
JF
381
382%%
383
5999c315 384void CYDriver::ScannerInit() {
924f67b2
JF
385 cylex_init(&scanner_);
386 cyset_extra(this, scanner_);
387}
388
5999c315 389void CYDriver::ScannerDestroy() {
924f67b2
JF
390 cylex_destroy(scanner_);
391}
63cd45c9 392
691e4717
JF
393CYDriver::Condition CYDriver::GetCondition() {
394 switch (yy_top_state(scanner_)) {
395 case RegExp:
396 return RegExpCondition;
397@begin E4X
398 case XMLContent:
399 return XMLContentCondition;
400 case XMLTag:
401 return XMLTagCondition;
402@end
403 default:
404 _assert(false);
405 }
406}
407
408void CYDriver::SetCondition(Condition condition) {
63cd45c9
JF
409 struct yyguts_t *yyg(reinterpret_cast<struct yyguts_t *>(scanner_));
410
411 switch (condition) {
697d6fd2
JF
412 case RegExpCondition:
413 BEGIN(RegExp);
63cd45c9 414 break;
691e4717
JF
415@begin E4X
416 case XMLContentCondition:
417 BEGIN(XMLContent);
418 break;
419 case XMLTagCondition:
420 BEGIN(XMLTag);
421 break;
422@end
63cd45c9
JF
423 default:
424 _assert(false);
425 }
426}
691e4717
JF
427
428void CYDriver::PushCondition(Condition condition) {
429 switch (condition) {
430 case RegExpCondition:
431 yy_push_state(RegExp, scanner_);
432 break;
433@begin E4X
434 case XMLContentCondition:
435 yy_push_state(XMLContent, scanner_);
436 break;
437 case XMLTagCondition:
438 yy_push_state(XMLTag, scanner_);
439 break;
440@end
441 default:
442 _assert(false);
443 }
444}
445
446void CYDriver::PopCondition() {
447 yy_pop_state(scanner_);
448}