jejune 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+