jejune 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+ #--
4
+ # Copyright (c) 2010-2011 Kyle C. Yetter
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining
7
+ # a copy of this software and associated documentation files (the
8
+ # "Software"), to deal in the Software without restriction, including
9
+ # without limitation the rights to use, copy, modify, merge, publish,
10
+ # distribute, sublicense, and/or sell copies of the Software, and to
11
+ # permit persons to whom the Software is furnished to do so, subject to
12
+ # the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be
15
+ # included in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ #++
25
+
26
+ class Exception
27
+ def jejune_trace
28
+ @jejune_trace ||= []
29
+ end
30
+ end
31
+
32
+ module Jejune
33
+
34
+ TranslationError = Class.new( StandardError )
35
+
36
+ class MacroNotFound < TranslationError
37
+ attr_accessor :name
38
+
39
+ def initialize( name, *args )
40
+ @name = name
41
+ super( "Call to unknown macro name `#{ name }'", *args )
42
+ end
43
+
44
+ end
45
+
46
+ class TokenError < StandardError
47
+ attr_reader :token
48
+ def initialize( message, token )
49
+ super( message )
50
+ @token = token
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+ #--
4
+ # Copyright (c) 2010-2011 Kyle C. Yetter
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining
7
+ # a copy of this software and associated documentation files (the
8
+ # "Software"), to deal in the Software without restriction, including
9
+ # without limitation the rights to use, copy, modify, merge, publish,
10
+ # distribute, sublicense, and/or sell copies of the Software, and to
11
+ # permit persons to whom the Software is furnished to do so, subject to
12
+ # the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be
15
+ # included in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ #++
25
+
26
+ require 'jejune/grammar/lexer'
27
+ require 'jejune/grammar/parser'
28
+ #require 'jejune/grammar/tree'
29
+
30
+ if $0 == __FILE__
31
+ Jejune::Parser.main( ARGV )
32
+ end
@@ -0,0 +1,668 @@
1
+ grammar JavaScript;
2
+
3
+ options {
4
+ language = Ruby;
5
+ output = AST;
6
+ }
7
+
8
+ tokens {
9
+ AMP='&'; GREATER='>'; POST_INCR;
10
+ AMP_ASGN='&='; HAT='^'; PROGRAM;
11
+ AND='&&'; HAT_ASGN='^='; QMARK='?';
12
+ AREF; IF='if'; RBRACE='}';
13
+ ARGUMENTS; IN='in'; RBRACK=']';
14
+ ARRAY; INCR='++'; REGEX;
15
+ ASGN='='; INSTANCEOF='instanceof'; RETURN='return';
16
+ BLOCK; LABEL; RPAREN=')';
17
+ BREAK='break'; LBRACE='{'; RSHIFT='>>';
18
+ CALL; LBRACK='['; RSHIFT3='>>>';
19
+ CASE='case'; LEQ='<='; RSHIFT3_ASGN='>>>=';
20
+ CATCH='catch'; LESS='<'; RSHIFT_ASGN='>>=';
21
+ COLON=':'; LET='let'; SEMI=';';
22
+ COMMA=','; LINE_COMMENT; SET='set';
23
+ COMMENT; LPAREN='('; SLASH;
24
+ CONST='const'; LSHIFT='<<'; SLASH_ASGN;
25
+ CONTINUE='continue'; LSHIFT_ASGN='<<='; STAR='*';
26
+ DECR='--'; MINUS='-'; STAR_ASGN='*=';
27
+ DEFAULT='default'; MINUS_ASGN='-='; SWITCH='switch';
28
+ DELETE='delete'; MOD='%'; THIS='this';
29
+ DO='do'; MOD_ASGN='%='; THROW='throw';
30
+ DOT='.'; NEQ='!='; TILDE='~';
31
+ DO_WHILE; NEQQ='!=='; TRUE='true';
32
+ EACH='each'; NEW='new'; TRY='try';
33
+ ELSE='else'; NOT='!'; TYPEOF='typeof';
34
+ EQ='=='; NULL='null'; UMINUS;
35
+ EQQ='==='; OBJECT; UNDEFINED='undefined';
36
+ FALSE='false'; OR='||'; UPLUS;
37
+ FINALLY='finally'; PARAMS; VAR='var';
38
+ FOR='for'; PIPE='|'; VOID='void';
39
+ FOR_IN; PIPE_ASGN='|='; WHILE='while';
40
+ FUNCTION='function'; PLUS='+'; WITH='with';
41
+ GEQ='>='; PLUS_ASGN='+='; YIELD='yield';
42
+ GET='get'; POST_DECR;
43
+ }
44
+
45
+ scope InFor { active; }
46
+
47
+ @all::header {
48
+ module Jejune
49
+ }
50
+ @all::footer {
51
+ end
52
+ }
53
+
54
+ @parser::members {
55
+
56
+ RESERVED = Set[
57
+ BREAK, DO, FUNCTION, NEW, THROW, CASE, EACH, GET,
58
+ NULL, TRUE, VAR, CATCH, ELSE, IF, RETURN, TRY, VOID,
59
+ CONTINUE, FALSE, IN, SET, TYPEOF, WHILE, DEFAULT, FINALLY,
60
+ INSTANCEOF, SWITCH, UNDEFINED, WITH, DELETE, FOR, LET, THIS,
61
+ YIELD
62
+ ]
63
+
64
+ def auto_semicolon?( error )
65
+ if NoViableAlternative === error
66
+ return( @auto_semicolon = error ) unless same_line?
67
+ end
68
+ return false
69
+ end
70
+
71
+ def recover( error = $! )
72
+ @auto_semicolon == error and return( @auto_semicolon = nil )
73
+ super
74
+ end
75
+
76
+ def report_error( error = $! )
77
+ auto_semicolon?( error ) and return
78
+ super
79
+ end
80
+
81
+ def newline?( from = 1 )
82
+ to = from == -1 ? 1 : from + 1
83
+ start = @input.future?( from )
84
+ stop = @input.future?( to )
85
+
86
+ start.upto( stop ) do | i |
87
+ @input.at( i ).type == NEWLINE and return( true )
88
+ end
89
+
90
+ return( false )
91
+ end
92
+
93
+ def same_line?
94
+ stop = @input.future? || @input.length
95
+ start = @input.past? || 0
96
+
97
+ start.upto( stop ) do | i |
98
+ @input.at( i ).type == NEWLINE and return( false )
99
+ end
100
+
101
+ return( true )
102
+ end
103
+
104
+ def property_definition?
105
+ type = @input.peek
106
+ RESERVED.include?( type ) and type = ID
107
+
108
+ case @input.peek
109
+ when GET, SET then return true
110
+ when ID
111
+ case @input.peek( 2 )
112
+ when COLON then return true
113
+ else return false
114
+ end
115
+ end
116
+ end
117
+
118
+ def prepend_tree( root, child )
119
+ child = @adaptor.rule_post_processing( child )
120
+ root.unshift( child )
121
+ root.start_index > child.start_index and root.start_index = child.start_index
122
+ root.stop_index < child.stop_index and root.stop_index = child.stop_index
123
+ return @adaptor.rule_post_processing( root )
124
+ end
125
+ }
126
+
127
+ @lexer::members {
128
+ attr_accessor :value_expected
129
+
130
+ NO_VALUE_FOLLOWS = Set[
131
+ ID, REGEX, STRING, NUMBER, THIS,
132
+ TRUE, FALSE, NULL, UNDEFINED,
133
+ RPAREN, RBRACK, RBRACE
134
+ ]
135
+
136
+ def next_token
137
+ token = super
138
+ unless token.hidden?
139
+ @value_expected =
140
+ NO_VALUE_FOLLOWS.include?( token.type ) ? false : true
141
+ end
142
+ return( token )
143
+ end
144
+ }
145
+
146
+ @lexer::init { @value_expected = true }
147
+
148
+ /********************************************************************************
149
+ **************************** Top-Level Structure *****************************
150
+ ********************************************************************************/
151
+
152
+ program
153
+ : source_elements -> source_elements
154
+ | -> ^( UNDEFINED )
155
+ ;
156
+
157
+ source_elements
158
+ : statement ( statement )*
159
+ ;
160
+
161
+ block
162
+ : ( '{' )=> statement_block
163
+ | statement
164
+ ;
165
+
166
+ statement_block
167
+ : '{' statement_list? '}' -> ^( BLOCK statement_list? )
168
+ ;
169
+
170
+ statement_list
171
+ : statement+ -> statement+
172
+ ;
173
+
174
+ clause
175
+ : '(' expression_list ')' -> expression_list
176
+ ;
177
+
178
+ /********************************************************************************
179
+ ******************************** Statements **********************************
180
+ ********************************************************************************/
181
+
182
+ statement
183
+ : variable_statement
184
+ | const_statement
185
+ | empty_statement
186
+ | ( 'function' )=> function
187
+ | ( ID ':' )=> labelled_statement
188
+ | ( 'let' )=> let_statement
189
+ | expression_statement
190
+ | if_statement
191
+ | while_statement
192
+ | do_while_statement
193
+ | for_loop
194
+ | continue_statement
195
+ | break_statement
196
+ | yield_statement
197
+ | return_statement
198
+ | with_statement
199
+ | switch_statement
200
+ | throw_statement
201
+ | try_statement
202
+ ;
203
+
204
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
205
+ // Simple Statements
206
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
207
+
208
+ empty_statement
209
+ : ';' ->
210
+ ;
211
+
212
+ expression_statement
213
+ : expression_list statement_end!
214
+ ;
215
+
216
+ labelled_statement
217
+ : ID ':' block
218
+ -> ^( LABEL ID block )
219
+ ;
220
+
221
+ statement_end
222
+ : ';'
223
+ | ( '}' )=>
224
+ | EOF
225
+ ;
226
+
227
+ blank
228
+ : -> ^( UNDEFINED )
229
+ ;
230
+
231
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
232
+ // Block-ish Statements
233
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
234
+
235
+ try_statement
236
+ : 'try'
237
+ ( statement_block -> statement_block )
238
+ ( f=finally_clause -> { prepend_tree( $f.tree, $tree ) }
239
+ | ( catch_clause -> { prepend_tree( $catch_clause.tree, $tree ) } )
240
+ ( f2=finally_clause -> { prepend_tree( $f2.tree, $tree ) } )?
241
+ )
242
+ ;
243
+
244
+ catch_clause
245
+ : 'catch' '(' ID ')' statement_block
246
+ -> ^( 'catch' ID statement_block )
247
+ ;
248
+
249
+ finally_clause
250
+ : 'finally' statement_block
251
+ -> ^( 'finally' statement_block )
252
+ ;
253
+
254
+ with_statement
255
+ : 'with' clause block -> ^( 'with' clause block )
256
+ ;
257
+
258
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
259
+ // Variable Declarations
260
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
261
+
262
+ variable_statement
263
+ : 'var'^ variable_declaration_list statement_end!
264
+ ;
265
+
266
+ const_statement
267
+ : 'const'^ variable_declaration_list statement_end!
268
+ ;
269
+
270
+ let_statement
271
+ : 'let'^ '('! variable_declaration_list ')'! block
272
+ ;
273
+
274
+ variable_declaration_list
275
+ : variable_declaration ( ','! variable_declaration )*
276
+ ;
277
+
278
+ variable_declaration
279
+ : declaration_target ( '='^ expression )?
280
+ ;
281
+
282
+ declaration_target
283
+ : '[' declaration_target ( ',' declaration_target )* ']' -> ^( ARRAY declaration_target+ )
284
+ | '{' declaration_key ( ',' declaration_key )* '}' -> ^( OBJECT declaration_key+ )
285
+ | variable_name -> variable_name
286
+ ;
287
+
288
+ declaration_key
289
+ : property_name ':'^ declaration_target
290
+ ;
291
+
292
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
293
+ // Branching Statements
294
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
295
+
296
+ if_statement
297
+ : 'if'^ clause block ( 'else'! block )?
298
+ ;
299
+
300
+ switch_statement
301
+ : 'switch' '(' expression_list ')'
302
+ '{'
303
+ ( case_clause )*
304
+ ( default_clause ( case_clause )* )?
305
+ '}'
306
+ -> ^( 'switch' expression_list case_clause* default_clause? )
307
+ ;
308
+
309
+ case_clause
310
+ : 'case'^ expression_list ':'! statement_list?
311
+ ;
312
+
313
+ default_clause
314
+ : 'default'^ ':'! statement_list?
315
+ ;
316
+
317
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
318
+ // While Loops
319
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
320
+
321
+ do_while_statement
322
+ : 'do' block ( 'while' clause statement_end -> ^( 'while' clause block ) )
323
+ -> ^( 'do' $do_while_statement )
324
+ ;
325
+
326
+ while_statement
327
+ : 'while'^ clause block
328
+ ;
329
+
330
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
331
+ // For Loops
332
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
333
+
334
+ for_loop
335
+ : { @input.peek( 2 ) == EACH }?=> for_each_in_statement
336
+ | ( 'for' '(' ~( ')' | ';' | 'in' )* 'in' )=> for_in_statement
337
+ | for_statement
338
+ ;
339
+
340
+ for_statement
341
+ : 'for'^
342
+ '('!
343
+ ( for_statement_initialiser_part | blank ) ';'!
344
+ ( expression_list | blank ) ';'!
345
+ ( expression_list | blank )
346
+ ')'!
347
+ block
348
+ ;
349
+
350
+ for_statement_initialiser_part
351
+ scope InFor;
352
+ @before { $InFor::active = true }
353
+ @after { $InFor::active = false }
354
+ : expression_list
355
+ | 'var'^ variable_declaration_list
356
+ ;
357
+
358
+ for_each_in_statement
359
+ : 'for' 'each' '(' for_in_statement_initialiser_part 'in' expression ')' block
360
+ -> ^( 'each' for_in_statement_initialiser_part expression block )
361
+ ;
362
+
363
+ for_in_statement
364
+ : f='for' '(' for_in_statement_initialiser_part 'in' expression ')' block
365
+ -> ^( FOR_IN[ $f ] for_in_statement_initialiser_part expression block )
366
+ ;
367
+
368
+ for_in_statement_initialiser_part
369
+ scope InFor;
370
+ @before { $InFor::active = true }
371
+ @after { $InFor::active = false }
372
+ : 'var'^ variable_declaration
373
+ | member
374
+ ;
375
+
376
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
377
+ // Flow Control
378
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
379
+
380
+ continue_statement
381
+ : 'continue'^ ( { same_line? }?=> ID )? statement_end!
382
+ ;
383
+
384
+ break_statement
385
+ : 'break'^ ( { same_line? }?=> ID )? statement_end!
386
+ ;
387
+
388
+ return_statement
389
+ : 'return'^ ( { same_line? }?=> expression_list )? statement_end!
390
+ ;
391
+
392
+ yield_statement
393
+ : 'yield'^ ( { same_line? }?=> expression_list )? statement_end!
394
+ ;
395
+
396
+ throw_statement
397
+ : 'throw'^ ( { same_line? }?=> expression_list )? statement_end!
398
+ ;
399
+
400
+ /********************************************************************************
401
+ ******************************** Expression **********************************
402
+ ********************************************************************************/
403
+
404
+ expression_list
405
+ : expression ( ','^ expression )*
406
+ ;
407
+
408
+ expression
409
+ : ( member assignment_op )=> member assignment_op^ expression
410
+ | conditional
411
+ ;
412
+
413
+ assignment_op
414
+ : '='
415
+ | '*='
416
+ | SLASH_ASGN
417
+ | '%='
418
+ | '+='
419
+ | '-='
420
+ | '<<='
421
+ | '>>='
422
+ | '>>>='
423
+ | '&='
424
+ | '^='
425
+ | '|='
426
+ ;
427
+
428
+ conditional
429
+ : logical_or ( '?'^ t=expression ':'! f=expression )?
430
+ ;
431
+
432
+ logical_or
433
+ : logical_and ( '||'^ logical_and )*
434
+ ;
435
+
436
+ logical_and
437
+ : bit_or ( '&&'^ bit_or )*
438
+ ;
439
+
440
+ bit_or
441
+ : bit_xor ( '|'^ bit_xor )*
442
+ ;
443
+
444
+ bit_xor
445
+ : bit_and ( '^'^ bit_and )*
446
+ ;
447
+
448
+ bit_and
449
+ : equality ( '&'^ equality )*
450
+ ;
451
+
452
+ equality
453
+ : relation
454
+ (
455
+ ( '=='^ | '!='^ | '==='^ | '!=='^ )
456
+ relation
457
+ )*
458
+ ;
459
+
460
+ relation
461
+ : shift ( relation_op^ shift )*
462
+ ;
463
+
464
+ relation_op
465
+ : '<'
466
+ | '>'
467
+ | '<='
468
+ | '>='
469
+ | 'instanceof'
470
+ | { !( $InFor.last && $InFor::active ) }?=> 'in'
471
+ ;
472
+
473
+ shift
474
+ : add ( ( '<<'^ | '>>'^ | '>>>'^ ) add )*
475
+ ;
476
+
477
+ add
478
+ : mult ( ( '+'^ | '-'^ ) mult )*
479
+ ;
480
+
481
+ mult
482
+ : unary ( ( '*'^ | SLASH^ | '%'^ ) unary )*
483
+ ;
484
+
485
+ unary
486
+ : 'delete' unary -> ^( 'delete' unary )
487
+ | 'void' unary -> ^( 'void' unary )
488
+ | 'typeof' unary -> ^( 'typeof' unary )
489
+ | '++' unary -> ^( '++' unary )
490
+ | '--' unary -> ^( '--' unary )
491
+ | '+' unary -> ^( UPLUS[ '+' ] unary )
492
+ | '-' unary -> ^( UMINUS[ '-' ] unary )
493
+ | '~' unary -> ^( '~' unary )
494
+ | '!' unary -> ^( '!' unary )
495
+ | postfix -> postfix
496
+ ;
497
+
498
+ postfix
499
+ : member
500
+ ( { same_line? }?=>
501
+ ( '++' -> ^( POST_INCR[ '++' ] member )
502
+ | '--' -> ^( POST_DECR[ '--' ] member )
503
+ )
504
+ | -> member
505
+ )
506
+ ;
507
+
508
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
509
+ // Atomic Expressions
510
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
511
+
512
+ member
513
+ : ( receiver -> receiver )
514
+ ( accessor -> { prepend_tree( $accessor.tree, $tree ) }
515
+ | arguments -> ^( CALL $member arguments )
516
+ )*
517
+ ;
518
+
519
+ accessor
520
+ : '[' expression ']' -> ^( AREF[ '[' ] expression ) //]
521
+ | '.' property_name -> ^( '.' property_name )
522
+ ;
523
+
524
+ receiver
525
+ : primary -> primary
526
+ | function -> function
527
+ | ( 'new' new_target arguments? )=>
528
+ 'new' new_target arguments? -> ^( 'new' new_target arguments? )
529
+ ;
530
+
531
+ new_target
532
+ : ( receiver -> receiver )
533
+ ( accessor -> { prepend_tree( $accessor.tree, $tree ) } )*
534
+ ;
535
+
536
+ arguments
537
+ : '(' ( expression ( ',' expression )* )? ')' -> ^( ARGUMENTS expression* )
538
+ ;
539
+
540
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
541
+ // Functions / Blocks
542
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
543
+
544
+ function
545
+ : 'function'^ variable_name? function_parameters statement_block
546
+ ;
547
+
548
+ function_parameters
549
+ : '(' parameters? ')' -> ^( PARAMS parameters? )
550
+ ;
551
+
552
+ parameters
553
+ : variable_name ( ',' variable_name )* -> variable_name+
554
+ ;
555
+
556
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
557
+ // Literals
558
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
559
+
560
+ primary
561
+ : 'this'^
562
+ | variable_name^
563
+ | 'null'^
564
+ | 'true'^
565
+ | 'false'^
566
+ | 'undefined'^
567
+ | NUMBER^
568
+ | STRING^
569
+ | REGEX^
570
+ | array_literal
571
+ | object_literal
572
+ | '('! expression_list ')'!
573
+ ;
574
+
575
+ array_literal
576
+ : '[' ']' -> ^( ARRAY )
577
+ | '[' list_item ( ',' list_item )* ']' -> ^( ARRAY list_item* )
578
+ ;
579
+
580
+ list_item
581
+ : ( ',' )=> -> ^( UNDEFINED )
582
+ | expression -> expression
583
+ ;
584
+
585
+ object_literal
586
+ : '{' '}' -> ^( OBJECT )
587
+ | '{' property_definition ( ',' property_definition )* '}'
588
+ -> ^( OBJECT property_definition+ )
589
+ ;
590
+
591
+ property_definition
592
+ : 'get'^ ID function_parameters block
593
+ | 'set'^ ID function_parameters block
594
+ | property_name ':'^ expression
595
+ ;
596
+
597
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
598
+ // Names and Words
599
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
600
+
601
+ property_name
602
+ : ID
603
+ | STRING
604
+ | NUMBER
605
+ | reserved { $reserved.tree.token.type = ID }
606
+ ;
607
+
608
+ variable_name
609
+ : ID
610
+ | t=pseudokeyword { $t.tree.token.type = ID }
611
+ ;
612
+
613
+ pseudokeyword
614
+ : 'each'
615
+ | 'get'
616
+ | 'set'
617
+ ;
618
+
619
+ reserved
620
+ : 'break' | 'do' | 'function' | 'new' | 'throw'
621
+ | 'case' | 'each' | 'get' | 'null' | 'true' | 'var'
622
+ | 'catch' | 'else' | 'if' | 'return' | 'try' | 'void'
623
+ | 'continue' | 'false' | 'in' | 'set' | 'typeof' | 'while'
624
+ | 'default' | 'finally' | 'instanceof' | 'switch' | 'undefined' | 'with'
625
+ | 'delete' | 'for' | 'let' | 'this' | 'yield'
626
+ ;
627
+
628
+ /********************************************************************************
629
+ *********************************** Lexer ************************************
630
+ ********************************************************************************/
631
+
632
+
633
+ SLASH
634
+ : '//' ~( '\n' | '\r' )* { $type = LINE_COMMENT; $channel = HIDDEN }
635
+ | '/*' .* '*/' { $type = COMMENT; $channel = HIDDEN }
636
+ | { @value_expected }?=>
637
+ '/' { $type = REGEX }
638
+ ( ~( '/' | '*' | '\\' | '\r' | '\n' ) | '\\' . )
639
+ ( ~( '/' | '\\' | '\r' | '\n' ) | '\\' . )*
640
+ '/'
641
+ ( 'a' .. 'z' )*
642
+ | { !@value_expected }?=> '/' ( '=' { $type = SLASH_ASGN } | { $type = SLASH } )
643
+ ;
644
+
645
+ STRING
646
+ : '\'' ( ~( '\'' | '\\' ) | '\\' . )* '\''
647
+ | '"' ( ~( '"' | '\\' ) | '\\' . )* '"'
648
+ ;
649
+
650
+ NUMBER
651
+ : ('0'..'9')+ '.' ('0'..'9')* ( ('e' | 'E') ('+' | '-')? ('0'..'9')+ )?
652
+ | '.'? ('0'..'9')+ ( ('e' | 'E') ('+' | '-')? ('0'..'9')+ )?
653
+ | '0' ('x' | 'X') ( '0'..'9' | 'a'..'f' | 'A'..'F' )+
654
+ ;
655
+
656
+ NEWLINE
657
+ : ( '\n' | '\r' )+ { $channel = HIDDEN }
658
+ ;
659
+
660
+ ID
661
+ : ( '$' | '_' | 'a'..'z' | 'A'..'Z' )
662
+ ( '$' | '_' | 'a'..'z' | 'A'..'Z' | '0'..'9' )*
663
+ ;
664
+
665
+ WS // Tab, vertical tab, form feed, space, non-breaking space and any other unicode "space separator".
666
+ : ( '\t' | '\f' | ' ' | '\u00A0' )+ { $channel = HIDDEN }
667
+ ;
668
+