rkelly-turbo 0.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.
- checksums.yaml +7 -0
- data/CHANGELOG.rdoc +38 -0
- data/Manifest.txt +203 -0
- data/README.rdoc +135 -0
- data/Rakefile +41 -0
- data/lib/parser.y +883 -0
- data/lib/rkelly.rb +14 -0
- data/lib/rkelly/char_pos.rb +39 -0
- data/lib/rkelly/char_range.rb +33 -0
- data/lib/rkelly/constants.rb +3 -0
- data/lib/rkelly/generated_parser.rb +3380 -0
- data/lib/rkelly/js.rb +14 -0
- data/lib/rkelly/js/array.rb +15 -0
- data/lib/rkelly/js/base.rb +91 -0
- data/lib/rkelly/js/boolean.rb +21 -0
- data/lib/rkelly/js/function.rb +39 -0
- data/lib/rkelly/js/function_prototype.rb +15 -0
- data/lib/rkelly/js/global_object.rb +52 -0
- data/lib/rkelly/js/math.rb +10 -0
- data/lib/rkelly/js/nan.rb +18 -0
- data/lib/rkelly/js/number.rb +22 -0
- data/lib/rkelly/js/object.rb +30 -0
- data/lib/rkelly/js/object_prototype.rb +14 -0
- data/lib/rkelly/js/property.rb +20 -0
- data/lib/rkelly/js/scope.rb +6 -0
- data/lib/rkelly/js/string.rb +21 -0
- data/lib/rkelly/lexeme.rb +18 -0
- data/lib/rkelly/nodes.rb +25 -0
- data/lib/rkelly/nodes/binary_node.rb +18 -0
- data/lib/rkelly/nodes/bracket_accessor_node.rb +11 -0
- data/lib/rkelly/nodes/case_clause_node.rb +11 -0
- data/lib/rkelly/nodes/comma_node.rb +11 -0
- data/lib/rkelly/nodes/conditional_node.rb +11 -0
- data/lib/rkelly/nodes/dot_accessor_node.rb +11 -0
- data/lib/rkelly/nodes/for_in_node.rb +12 -0
- data/lib/rkelly/nodes/for_node.rb +13 -0
- data/lib/rkelly/nodes/function_call_node.rb +16 -0
- data/lib/rkelly/nodes/function_decl_node.rb +6 -0
- data/lib/rkelly/nodes/function_expr_node.rb +12 -0
- data/lib/rkelly/nodes/if_node.rb +12 -0
- data/lib/rkelly/nodes/label_node.rb +11 -0
- data/lib/rkelly/nodes/new_expr_node.rb +11 -0
- data/lib/rkelly/nodes/node.rb +116 -0
- data/lib/rkelly/nodes/not_strict_equal_node.rb +6 -0
- data/lib/rkelly/nodes/op_equal_node.rb +16 -0
- data/lib/rkelly/nodes/postfix_node.rb +11 -0
- data/lib/rkelly/nodes/prefix_node.rb +6 -0
- data/lib/rkelly/nodes/property_node.rb +13 -0
- data/lib/rkelly/nodes/resolve_node.rb +19 -0
- data/lib/rkelly/nodes/strict_equal_node.rb +6 -0
- data/lib/rkelly/nodes/try_node.rb +13 -0
- data/lib/rkelly/nodes/var_decl_node.rb +15 -0
- data/lib/rkelly/parser.rb +106 -0
- data/lib/rkelly/runtime.rb +36 -0
- data/lib/rkelly/runtime/ruby_function.rb +13 -0
- data/lib/rkelly/runtime/scope_chain.rb +57 -0
- data/lib/rkelly/syntax_error.rb +4 -0
- data/lib/rkelly/token.rb +27 -0
- data/lib/rkelly/tokenizer.rb +255 -0
- data/lib/rkelly/visitable.rb +31 -0
- data/lib/rkelly/visitors.rb +4 -0
- data/lib/rkelly/visitors/dot_visitor.rb +228 -0
- data/lib/rkelly/visitors/ecma_visitor.rb +328 -0
- data/lib/rkelly/visitors/enumerable_visitor.rb +18 -0
- data/lib/rkelly/visitors/evaluation_visitor.rb +419 -0
- data/lib/rkelly/visitors/function_visitor.rb +46 -0
- data/lib/rkelly/visitors/pointcut_visitor.rb +31 -0
- data/lib/rkelly/visitors/real_sexp_visitor.rb +16 -0
- data/lib/rkelly/visitors/sexp_visitor.rb +373 -0
- data/lib/rkelly/visitors/visitor.rb +149 -0
- data/test/ecma_script_test_case.rb +21 -0
- data/test/execute_test_case.rb +16 -0
- data/test/execution_contexts/test_10_1_3-1.rb +32 -0
- data/test/expressions/test_11_3_1.rb +64 -0
- data/test/expressions/test_11_3_2.rb +64 -0
- data/test/expressions/test_11_4_2.rb +13 -0
- data/test/expressions/test_11_4_3.rb +52 -0
- data/test/expressions/test_11_4_4.rb +68 -0
- data/test/expressions/test_11_4_5.rb +69 -0
- data/test/expressions/test_11_4_6.rb +94 -0
- data/test/expressions/test_11_4_8.rb +28 -0
- data/test/expressions/test_11_4_9.rb +103 -0
- data/test/expressions/test_11_5_1.rb +51 -0
- data/test/expressions/test_11_5_2.rb +80 -0
- data/test/expressions/test_11_5_3.rb +88 -0
- data/test/expressions/test_11_6_1-1.rb +19 -0
- data/test/expressions/test_11_9_1.rb +19 -0
- data/test/function/test_15_3_1_1-1.rb +34 -0
- data/test/global_object/test_15_1_1_1.rb +29 -0
- data/test/global_object/test_15_1_1_2.rb +17 -0
- data/test/global_object/test_15_1_1_3.rb +9 -0
- data/test/helper.rb +5 -0
- data/test/node_test_case.rb +11 -0
- data/test/object/test_15_2_1_1.rb +257 -0
- data/test/object/test_15_2_1_2.rb +21 -0
- data/test/object/test_15_2_2_1.rb +52 -0
- data/test/statements/test_12_5-1.rb +27 -0
- data/test/test_add_node.rb +8 -0
- data/test/test_arguments_node.rb +8 -0
- data/test/test_array_node.rb +9 -0
- data/test/test_assign_expr_node.rb +8 -0
- data/test/test_automatic_semicolon_insertion.rb +137 -0
- data/test/test_bit_and_node.rb +8 -0
- data/test/test_bit_or_node.rb +8 -0
- data/test/test_bit_x_or_node.rb +8 -0
- data/test/test_bitwise_not_node.rb +8 -0
- data/test/test_block_node.rb +14 -0
- data/test/test_bracket_accessor_node.rb +16 -0
- data/test/test_break_node.rb +11 -0
- data/test/test_case_block_node.rb +11 -0
- data/test/test_case_clause_node.rb +15 -0
- data/test/test_char_pos.rb +39 -0
- data/test/test_char_range.rb +29 -0
- data/test/test_comma_node.rb +13 -0
- data/test/test_comments.rb +45 -0
- data/test/test_conditional_node.rb +17 -0
- data/test/test_const_statement_node.rb +14 -0
- data/test/test_continue_node.rb +11 -0
- data/test/test_delete_node.rb +8 -0
- data/test/test_divide_node.rb +8 -0
- data/test/test_do_while_node.rb +13 -0
- data/test/test_dot_accessor_node.rb +9 -0
- data/test/test_ecma_visitor.rb +213 -0
- data/test/test_element_node.rb +8 -0
- data/test/test_empty_statement_node.rb +8 -0
- data/test/test_equal_node.rb +8 -0
- data/test/test_evaluation_visitor.rb +66 -0
- data/test/test_expression_statement_node.rb +10 -0
- data/test/test_false_node.rb +8 -0
- data/test/test_for_in_node.rb +17 -0
- data/test/test_for_node.rb +24 -0
- data/test/test_function_body_node.rb +8 -0
- data/test/test_function_call_node.rb +10 -0
- data/test/test_function_decl_node.rb +16 -0
- data/test/test_function_expr_node.rb +16 -0
- data/test/test_function_visitor.rb +26 -0
- data/test/test_getter_property_node.rb +10 -0
- data/test/test_global_object.rb +49 -0
- data/test/test_greater_node.rb +8 -0
- data/test/test_greater_or_equal_node.rb +8 -0
- data/test/test_if_node.rb +17 -0
- data/test/test_in_node.rb +8 -0
- data/test/test_instance_of_node.rb +8 -0
- data/test/test_label_node.rb +13 -0
- data/test/test_left_shift_node.rb +8 -0
- data/test/test_less_node.rb +8 -0
- data/test/test_less_or_equal_node.rb +8 -0
- data/test/test_line_number.rb +81 -0
- data/test/test_logical_and_node.rb +8 -0
- data/test/test_logical_not_node.rb +8 -0
- data/test/test_logical_or_node.rb +8 -0
- data/test/test_modulus_node.rb +8 -0
- data/test/test_multiply_node.rb +8 -0
- data/test/test_new_expr_node.rb +9 -0
- data/test/test_not_equal_node.rb +8 -0
- data/test/test_not_strict_equal_node.rb +8 -0
- data/test/test_null_node.rb +8 -0
- data/test/test_number_node.rb +8 -0
- data/test/test_object_literal_node.rb +9 -0
- data/test/test_op_and_equal_node.rb +10 -0
- data/test/test_op_divide_equal_node.rb +10 -0
- data/test/test_op_equal_node.rb +10 -0
- data/test/test_op_l_shift_equal_node.rb +10 -0
- data/test/test_op_minus_equal_node.rb +10 -0
- data/test/test_op_mod_equal_node.rb +10 -0
- data/test/test_op_multiply_equal_node.rb +10 -0
- data/test/test_op_or_equal_node.rb +10 -0
- data/test/test_op_plus_equal_node.rb +10 -0
- data/test/test_op_r_shift_equal_node.rb +10 -0
- data/test/test_op_u_r_shift_equal_node.rb +10 -0
- data/test/test_op_x_or_equal_node.rb +10 -0
- data/test/test_parameter_node.rb +8 -0
- data/test/test_parser.rb +1434 -0
- data/test/test_pointcut_visitor.rb +34 -0
- data/test/test_postfix_node.rb +8 -0
- data/test/test_prefix_node.rb +8 -0
- data/test/test_property_node.rb +8 -0
- data/test/test_regexp_node.rb +8 -0
- data/test/test_resolve_node.rb +22 -0
- data/test/test_return_node.rb +11 -0
- data/test/test_right_shift_node.rb +8 -0
- data/test/test_rkelly.rb +19 -0
- data/test/test_runtime.rb +12 -0
- data/test/test_scope_chain.rb +50 -0
- data/test/test_setter_property_node.rb +10 -0
- data/test/test_source_elements.rb +9 -0
- data/test/test_strict_equal_node.rb +8 -0
- data/test/test_string_node.rb +8 -0
- data/test/test_subtract_node.rb +8 -0
- data/test/test_switch_node.rb +12 -0
- data/test/test_this_node.rb +8 -0
- data/test/test_throw_node.rb +7 -0
- data/test/test_tokenizer.rb +285 -0
- data/test/test_true_node.rb +8 -0
- data/test/test_try_node.rb +59 -0
- data/test/test_type_of_node.rb +8 -0
- data/test/test_unary_minus_node.rb +8 -0
- data/test/test_unary_plus_node.rb +8 -0
- data/test/test_unsigned_right_shift_node.rb +8 -0
- data/test/test_var_decl_node.rb +21 -0
- data/test/test_var_statement_node.rb +14 -0
- data/test/test_void_node.rb +8 -0
- data/test/test_while_node.rb +15 -0
- data/test/test_with_node.rb +8 -0
- metadata +293 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: aef98d0989a1aa032fe7e0231129fb518d13c45ff7b359ce4f805fb40a23116e
|
4
|
+
data.tar.gz: 2aef9b143d414fb8c9dc3ddcc67d51e674375d7889ccdc738fe6f909bbeaf239
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 95c57e77d03ed1bc68daabb5cc8450b2fba7cad9bc98dcbea9c2cc7443386f87b90b9369f553dd0c29ce4154701763783385deb9d3f1f1a30f9232cbd110c3d9
|
7
|
+
data.tar.gz: a562b85535364137bd5675506e9c56054be829dbac4d4e347da000bc548a5d33e71adc20baa316c179027a66e10385a6ce7ed410a0248a661d8c05011f5e3c2e
|
data/CHANGELOG.rdoc
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
= RKelly-Turbo CHANGELOG
|
2
|
+
|
3
|
+
=== 0.1.0
|
4
|
+
|
5
|
+
* Gain about 2x speedup by enacting some optimizations.
|
6
|
+
|
7
|
+
=== 0.0.7
|
8
|
+
|
9
|
+
* Allow reserved words reserved only in strict mode.
|
10
|
+
|
11
|
+
=== 0.0.6
|
12
|
+
|
13
|
+
* Properly treat all unicode whitespace characters as whitespace.
|
14
|
+
|
15
|
+
=== 0.0.5
|
16
|
+
|
17
|
+
* Update list of reserved words to match ECMAScript 5
|
18
|
+
* Fix ecma visitor for function expressions with name
|
19
|
+
|
20
|
+
=== 0.0.4
|
21
|
+
|
22
|
+
* Allow use of keywords in property names.
|
23
|
+
|
24
|
+
=== 0.0.3
|
25
|
+
|
26
|
+
* Add RKelly::Parser#stopped_at method for error reporting.
|
27
|
+
|
28
|
+
=== 0.0.2
|
29
|
+
|
30
|
+
* Handle multibyte characters without crashing.
|
31
|
+
|
32
|
+
=== 0.0.1
|
33
|
+
|
34
|
+
* A fork of RKelly
|
35
|
+
* 10x speedup of Tokenizer.
|
36
|
+
* Full begin/end line/char info on each node.
|
37
|
+
* List all comment nodes in root node instead of attempting to associate them with syntax nodes and failing at it.
|
38
|
+
* Recognize /[/]/ as valid JS regex.
|
data/Manifest.txt
ADDED
@@ -0,0 +1,203 @@
|
|
1
|
+
CHANGELOG.rdoc
|
2
|
+
Manifest.txt
|
3
|
+
README.rdoc
|
4
|
+
Rakefile
|
5
|
+
lib/parser.y
|
6
|
+
lib/rkelly.rb
|
7
|
+
lib/rkelly/char_pos.rb
|
8
|
+
lib/rkelly/char_range.rb
|
9
|
+
lib/rkelly/constants.rb
|
10
|
+
lib/rkelly/generated_parser.rb
|
11
|
+
lib/rkelly/js.rb
|
12
|
+
lib/rkelly/js/array.rb
|
13
|
+
lib/rkelly/js/base.rb
|
14
|
+
lib/rkelly/js/boolean.rb
|
15
|
+
lib/rkelly/js/function.rb
|
16
|
+
lib/rkelly/js/function_prototype.rb
|
17
|
+
lib/rkelly/js/global_object.rb
|
18
|
+
lib/rkelly/js/math.rb
|
19
|
+
lib/rkelly/js/nan.rb
|
20
|
+
lib/rkelly/js/number.rb
|
21
|
+
lib/rkelly/js/object.rb
|
22
|
+
lib/rkelly/js/object_prototype.rb
|
23
|
+
lib/rkelly/js/property.rb
|
24
|
+
lib/rkelly/js/scope.rb
|
25
|
+
lib/rkelly/js/string.rb
|
26
|
+
lib/rkelly/lexeme.rb
|
27
|
+
lib/rkelly/nodes.rb
|
28
|
+
lib/rkelly/nodes/binary_node.rb
|
29
|
+
lib/rkelly/nodes/bracket_accessor_node.rb
|
30
|
+
lib/rkelly/nodes/case_clause_node.rb
|
31
|
+
lib/rkelly/nodes/comma_node.rb
|
32
|
+
lib/rkelly/nodes/conditional_node.rb
|
33
|
+
lib/rkelly/nodes/dot_accessor_node.rb
|
34
|
+
lib/rkelly/nodes/for_in_node.rb
|
35
|
+
lib/rkelly/nodes/for_node.rb
|
36
|
+
lib/rkelly/nodes/function_call_node.rb
|
37
|
+
lib/rkelly/nodes/function_decl_node.rb
|
38
|
+
lib/rkelly/nodes/function_expr_node.rb
|
39
|
+
lib/rkelly/nodes/if_node.rb
|
40
|
+
lib/rkelly/nodes/label_node.rb
|
41
|
+
lib/rkelly/nodes/new_expr_node.rb
|
42
|
+
lib/rkelly/nodes/node.rb
|
43
|
+
lib/rkelly/nodes/not_strict_equal_node.rb
|
44
|
+
lib/rkelly/nodes/op_equal_node.rb
|
45
|
+
lib/rkelly/nodes/postfix_node.rb
|
46
|
+
lib/rkelly/nodes/prefix_node.rb
|
47
|
+
lib/rkelly/nodes/property_node.rb
|
48
|
+
lib/rkelly/nodes/resolve_node.rb
|
49
|
+
lib/rkelly/nodes/strict_equal_node.rb
|
50
|
+
lib/rkelly/nodes/try_node.rb
|
51
|
+
lib/rkelly/nodes/var_decl_node.rb
|
52
|
+
lib/rkelly/parser.rb
|
53
|
+
lib/rkelly/runtime.rb
|
54
|
+
lib/rkelly/runtime/ruby_function.rb
|
55
|
+
lib/rkelly/runtime/scope_chain.rb
|
56
|
+
lib/rkelly/syntax_error.rb
|
57
|
+
lib/rkelly/token.rb
|
58
|
+
lib/rkelly/tokenizer.rb
|
59
|
+
lib/rkelly/visitable.rb
|
60
|
+
lib/rkelly/visitors.rb
|
61
|
+
lib/rkelly/visitors/dot_visitor.rb
|
62
|
+
lib/rkelly/visitors/ecma_visitor.rb
|
63
|
+
lib/rkelly/visitors/enumerable_visitor.rb
|
64
|
+
lib/rkelly/visitors/evaluation_visitor.rb
|
65
|
+
lib/rkelly/visitors/function_visitor.rb
|
66
|
+
lib/rkelly/visitors/pointcut_visitor.rb
|
67
|
+
lib/rkelly/visitors/real_sexp_visitor.rb
|
68
|
+
lib/rkelly/visitors/sexp_visitor.rb
|
69
|
+
lib/rkelly/visitors/visitor.rb
|
70
|
+
test/ecma_script_test_case.rb
|
71
|
+
test/execute_test_case.rb
|
72
|
+
test/execution_contexts/test_10_1_3-1.rb
|
73
|
+
test/expressions/test_11_3_1.rb
|
74
|
+
test/expressions/test_11_3_2.rb
|
75
|
+
test/expressions/test_11_4_2.rb
|
76
|
+
test/expressions/test_11_4_3.rb
|
77
|
+
test/expressions/test_11_4_4.rb
|
78
|
+
test/expressions/test_11_4_5.rb
|
79
|
+
test/expressions/test_11_4_6.rb
|
80
|
+
test/expressions/test_11_4_8.rb
|
81
|
+
test/expressions/test_11_4_9.rb
|
82
|
+
test/expressions/test_11_5_1.rb
|
83
|
+
test/expressions/test_11_5_2.rb
|
84
|
+
test/expressions/test_11_5_3.rb
|
85
|
+
test/expressions/test_11_6_1-1.rb
|
86
|
+
test/expressions/test_11_9_1.rb
|
87
|
+
test/function/test_15_3_1_1-1.rb
|
88
|
+
test/global_object/test_15_1_1_1.rb
|
89
|
+
test/global_object/test_15_1_1_2.rb
|
90
|
+
test/global_object/test_15_1_1_3.rb
|
91
|
+
test/helper.rb
|
92
|
+
test/node_test_case.rb
|
93
|
+
test/object/test_15_2_1_1.rb
|
94
|
+
test/object/test_15_2_1_2.rb
|
95
|
+
test/object/test_15_2_2_1.rb
|
96
|
+
test/statements/test_12_5-1.rb
|
97
|
+
test/test_add_node.rb
|
98
|
+
test/test_arguments_node.rb
|
99
|
+
test/test_array_node.rb
|
100
|
+
test/test_assign_expr_node.rb
|
101
|
+
test/test_automatic_semicolon_insertion.rb
|
102
|
+
test/test_bit_and_node.rb
|
103
|
+
test/test_bit_or_node.rb
|
104
|
+
test/test_bit_x_or_node.rb
|
105
|
+
test/test_bitwise_not_node.rb
|
106
|
+
test/test_block_node.rb
|
107
|
+
test/test_bracket_accessor_node.rb
|
108
|
+
test/test_break_node.rb
|
109
|
+
test/test_case_block_node.rb
|
110
|
+
test/test_case_clause_node.rb
|
111
|
+
test/test_char_pos.rb
|
112
|
+
test/test_char_range.rb
|
113
|
+
test/test_comma_node.rb
|
114
|
+
test/test_comments.rb
|
115
|
+
test/test_conditional_node.rb
|
116
|
+
test/test_const_statement_node.rb
|
117
|
+
test/test_continue_node.rb
|
118
|
+
test/test_delete_node.rb
|
119
|
+
test/test_divide_node.rb
|
120
|
+
test/test_do_while_node.rb
|
121
|
+
test/test_dot_accessor_node.rb
|
122
|
+
test/test_ecma_visitor.rb
|
123
|
+
test/test_element_node.rb
|
124
|
+
test/test_empty_statement_node.rb
|
125
|
+
test/test_equal_node.rb
|
126
|
+
test/test_evaluation_visitor.rb
|
127
|
+
test/test_expression_statement_node.rb
|
128
|
+
test/test_false_node.rb
|
129
|
+
test/test_for_in_node.rb
|
130
|
+
test/test_for_node.rb
|
131
|
+
test/test_function_body_node.rb
|
132
|
+
test/test_function_call_node.rb
|
133
|
+
test/test_function_decl_node.rb
|
134
|
+
test/test_function_expr_node.rb
|
135
|
+
test/test_function_visitor.rb
|
136
|
+
test/test_getter_property_node.rb
|
137
|
+
test/test_global_object.rb
|
138
|
+
test/test_greater_node.rb
|
139
|
+
test/test_greater_or_equal_node.rb
|
140
|
+
test/test_if_node.rb
|
141
|
+
test/test_in_node.rb
|
142
|
+
test/test_instance_of_node.rb
|
143
|
+
test/test_label_node.rb
|
144
|
+
test/test_left_shift_node.rb
|
145
|
+
test/test_less_node.rb
|
146
|
+
test/test_less_or_equal_node.rb
|
147
|
+
test/test_line_number.rb
|
148
|
+
test/test_logical_and_node.rb
|
149
|
+
test/test_logical_not_node.rb
|
150
|
+
test/test_logical_or_node.rb
|
151
|
+
test/test_modulus_node.rb
|
152
|
+
test/test_multiply_node.rb
|
153
|
+
test/test_new_expr_node.rb
|
154
|
+
test/test_not_equal_node.rb
|
155
|
+
test/test_not_strict_equal_node.rb
|
156
|
+
test/test_null_node.rb
|
157
|
+
test/test_number_node.rb
|
158
|
+
test/test_object_literal_node.rb
|
159
|
+
test/test_op_and_equal_node.rb
|
160
|
+
test/test_op_divide_equal_node.rb
|
161
|
+
test/test_op_equal_node.rb
|
162
|
+
test/test_op_l_shift_equal_node.rb
|
163
|
+
test/test_op_minus_equal_node.rb
|
164
|
+
test/test_op_mod_equal_node.rb
|
165
|
+
test/test_op_multiply_equal_node.rb
|
166
|
+
test/test_op_or_equal_node.rb
|
167
|
+
test/test_op_plus_equal_node.rb
|
168
|
+
test/test_op_r_shift_equal_node.rb
|
169
|
+
test/test_op_u_r_shift_equal_node.rb
|
170
|
+
test/test_op_x_or_equal_node.rb
|
171
|
+
test/test_parameter_node.rb
|
172
|
+
test/test_parser.rb
|
173
|
+
test/test_pointcut_visitor.rb
|
174
|
+
test/test_postfix_node.rb
|
175
|
+
test/test_prefix_node.rb
|
176
|
+
test/test_property_node.rb
|
177
|
+
test/test_regexp_node.rb
|
178
|
+
test/test_resolve_node.rb
|
179
|
+
test/test_return_node.rb
|
180
|
+
test/test_right_shift_node.rb
|
181
|
+
test/test_rkelly.rb
|
182
|
+
test/test_runtime.rb
|
183
|
+
test/test_scope_chain.rb
|
184
|
+
test/test_setter_property_node.rb
|
185
|
+
test/test_source_elements.rb
|
186
|
+
test/test_strict_equal_node.rb
|
187
|
+
test/test_string_node.rb
|
188
|
+
test/test_subtract_node.rb
|
189
|
+
test/test_switch_node.rb
|
190
|
+
test/test_this_node.rb
|
191
|
+
test/test_throw_node.rb
|
192
|
+
test/test_tokenizer.rb
|
193
|
+
test/test_true_node.rb
|
194
|
+
test/test_try_node.rb
|
195
|
+
test/test_type_of_node.rb
|
196
|
+
test/test_unary_minus_node.rb
|
197
|
+
test/test_unary_plus_node.rb
|
198
|
+
test/test_unsigned_right_shift_node.rb
|
199
|
+
test/test_var_decl_node.rb
|
200
|
+
test/test_var_statement_node.rb
|
201
|
+
test/test_void_node.rb
|
202
|
+
test/test_while_node.rb
|
203
|
+
test/test_with_node.rb
|
data/README.rdoc
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
= RKelly Remix
|
2
|
+
|
3
|
+
https://github.com/nene/rkelly-remix
|
4
|
+
|
5
|
+
== DESCRIPTION
|
6
|
+
|
7
|
+
RKelly Remix is a fork of the
|
8
|
+
RKelly[https://github.com/tenderlove/rkelly] JavaScript parser.
|
9
|
+
|
10
|
+
== Install
|
11
|
+
|
12
|
+
gem install rkelly-remix
|
13
|
+
|
14
|
+
Note that you can't have rkelly and rkelly-remix both installed at the
|
15
|
+
same time. That would cause a conflict since they're both included
|
16
|
+
with:
|
17
|
+
|
18
|
+
require 'rkelly'
|
19
|
+
|
20
|
+
== Example
|
21
|
+
|
22
|
+
# Iterate over and modify a JavaScript AST. Then print the modified
|
23
|
+
# AST as JavaScript.
|
24
|
+
require 'rkelly'
|
25
|
+
|
26
|
+
parser = RKelly::Parser.new
|
27
|
+
ast = parser.parse(
|
28
|
+
"for(var i = 0; i < 10; i++) { var x = 5 + 5; }"
|
29
|
+
)
|
30
|
+
|
31
|
+
ast.each do |node|
|
32
|
+
node.value = 'hello' if node.value == 'i'
|
33
|
+
node.name = 'hello' if node.respond_to?(:name) && node.name == 'i'
|
34
|
+
end
|
35
|
+
puts ast.to_ecma # => awesome javascript
|
36
|
+
|
37
|
+
== Why fork?
|
38
|
+
|
39
|
+
Currently the original RKelly project is unmaintained. The latest
|
40
|
+
release was in late 2012, and since then the author has not responded
|
41
|
+
to bug reports or pull requests.
|
42
|
+
|
43
|
+
I created this fork mainly to satisfy the needs of my
|
44
|
+
JSDuck[https://github.com/senchalabs/jsduck] project, but you too
|
45
|
+
should consider using it, as it fixes several problems in the original
|
46
|
+
RKelly:
|
47
|
+
|
48
|
+
=== Much improved speed
|
49
|
+
|
50
|
+
* 20 x faster in Ruby 1.8.
|
51
|
+
* 2 x faster in Ruby 1.9 and 2.0.
|
52
|
+
|
53
|
+
=== Correct start/end position data for all syntax nodes
|
54
|
+
|
55
|
+
Original RKelly only had a rudimentary support for getting the line
|
56
|
+
number of an AST node, and even that was often wrong.
|
57
|
+
|
58
|
+
In RKelly Remix each AST node has a range property, which contains
|
59
|
+
granular data about the exact location of the node in source code:
|
60
|
+
|
61
|
+
parser = RKelly::Parser.new
|
62
|
+
ast = parser.parse(<<-eojs)
|
63
|
+
function aaron() {
|
64
|
+
var x = 10;
|
65
|
+
return 1 + 1;
|
66
|
+
}
|
67
|
+
eojs
|
68
|
+
|
69
|
+
node = ast.pointcut(ReturnNode).matches.first
|
70
|
+
|
71
|
+
node.range.to_s # <{line:3 char:5 (41)}...{line:3 char:17 (53)}>
|
72
|
+
|
73
|
+
node.range.from.line # 3
|
74
|
+
node.range.from.char # 5
|
75
|
+
node.range.from.index # 41
|
76
|
+
|
77
|
+
node.range.to.line # 3
|
78
|
+
node.range.to.char # 17
|
79
|
+
node.range.to.index # 53
|
80
|
+
|
81
|
+
=== Sensible comments handling
|
82
|
+
|
83
|
+
Original RKelly attempted to associate each comment with a related AST
|
84
|
+
node, but failed to correctly do so, which is understandable, as there
|
85
|
+
is no standard way to do such a mapping. RKelly Remix abandons this
|
86
|
+
and just lists all commenst in the root node, leaving the user with
|
87
|
+
the task of associating them with AST nodes if he desires so (the same
|
88
|
+
approach is taken by another JS parser: Esprima[http://esprima.org] ).
|
89
|
+
|
90
|
+
parser = RKelly::Parser.new
|
91
|
+
ast = parser.parse(<<-eojs)
|
92
|
+
/**
|
93
|
+
* This is an awesome test comment.
|
94
|
+
*/
|
95
|
+
function aaron() { // This is a side comment
|
96
|
+
var x = 10;
|
97
|
+
return 1 + 1; // Equals two!
|
98
|
+
}
|
99
|
+
eojs
|
100
|
+
|
101
|
+
# print out all the comments
|
102
|
+
ast.comments.each do |c|
|
103
|
+
puts c.value
|
104
|
+
end
|
105
|
+
|
106
|
+
=== Improved parser
|
107
|
+
|
108
|
+
* List of reserved words matches with ECMAScript 5.1.
|
109
|
+
* Keywords are allowed in property names.
|
110
|
+
* Multibyte characters are supported in Ruby >= 1.9.
|
111
|
+
* Correct parsing of regexes like /[/]/
|
112
|
+
|
113
|
+
== License
|
114
|
+
|
115
|
+
The MIT License
|
116
|
+
|
117
|
+
Copyright (c) 2007, 2008, 2009 Aaron Patterson, John Barnette
|
118
|
+
|
119
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
120
|
+
of this software and associated documentation files (the "Software"), to deal
|
121
|
+
in the Software without restriction, including without limitation the rights
|
122
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
123
|
+
copies of the Software, and to permit persons to whom the Software is
|
124
|
+
furnished to do so, subject to the following conditions:
|
125
|
+
|
126
|
+
The above copyright notice and this permission notice shall be included in
|
127
|
+
all copies or substantial portions of the Software.
|
128
|
+
|
129
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
130
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
131
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
132
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
133
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
134
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
135
|
+
THE SOFTWARE
|
data/Rakefile
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'hoe'
|
3
|
+
|
4
|
+
Hoe.plugin :gemspec # `gem install hoe-gemspec`
|
5
|
+
Hoe.plugin :git # `gem install hoe-git`
|
6
|
+
|
7
|
+
GENERATED_PARSER = "lib/rkelly/generated_parser.rb"
|
8
|
+
|
9
|
+
HOE = Hoe.spec('rkelly-turbo') do |p|
|
10
|
+
license "MIT"
|
11
|
+
developer('Aaron Patterson', 'aaron.patterson@gmail.com')
|
12
|
+
developer('Rene Saarsoo', 'rene.saarsoo@sencha.com')
|
13
|
+
developer('hmdne', '54514036+hmdne@users.noreply.github.com')
|
14
|
+
self.readme_file = 'README.rdoc'
|
15
|
+
self.history_file = 'CHANGELOG.rdoc'
|
16
|
+
self.extra_rdoc_files = FileList['*.rdoc']
|
17
|
+
self.clean_globs = [GENERATED_PARSER]
|
18
|
+
end
|
19
|
+
|
20
|
+
file GENERATED_PARSER => "lib/parser.y" do |t|
|
21
|
+
if ENV['DEBUG']
|
22
|
+
sh "racc -g -v -o #{t.name} #{t.prerequisites.first}"
|
23
|
+
else
|
24
|
+
sh "racc -o #{t.name} #{t.prerequisites.first}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
task :parser => GENERATED_PARSER
|
29
|
+
|
30
|
+
# make sure the parser's up-to-date when we test
|
31
|
+
Rake::Task[:test].prerequisites << :parser
|
32
|
+
Rake::Task[:check_manifest].prerequisites << :parser
|
33
|
+
|
34
|
+
namespace :gem do
|
35
|
+
task :spec do
|
36
|
+
File.open("#{HOE.name}.gemspec", 'w') do |f|
|
37
|
+
HOE.spec.version = "#{HOE.version}.#{Time.now.strftime("%Y%m%d%H%M%S")}"
|
38
|
+
f.write(HOE.spec.to_ruby)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/parser.y
ADDED
@@ -0,0 +1,883 @@
|
|
1
|
+
/* vim: set filetype=racc : */
|
2
|
+
|
3
|
+
class RKelly::GeneratedParser
|
4
|
+
|
5
|
+
/* Literals */
|
6
|
+
token NULL TRUE FALSE
|
7
|
+
|
8
|
+
/* keywords */
|
9
|
+
token BREAK CASE CATCH CONST CONTINUE DEBUGGER DEFAULT DELETE DO ELSE
|
10
|
+
token FINALLY FOR FUNCTION IF IN INSTANCEOF NEW RETURN SWITCH THIS THROW TRY
|
11
|
+
token TYPEOF VAR VOID WHILE WITH
|
12
|
+
|
13
|
+
/* reserved keywords */
|
14
|
+
token RESERVED
|
15
|
+
|
16
|
+
/* punctuators */
|
17
|
+
token EQEQ NE /* == and != */
|
18
|
+
token STREQ STRNEQ /* === and !== */
|
19
|
+
token LE GE /* < and > */
|
20
|
+
token OR AND /* || and && */
|
21
|
+
token PLUSPLUS MINUSMINUS /* ++ and -- */
|
22
|
+
token LSHIFT /* << */
|
23
|
+
token RSHIFT URSHIFT /* >> and >>> */
|
24
|
+
token PLUSEQUAL MINUSEQUAL /* += and -= */
|
25
|
+
token MULTEQUAL DIVEQUAL /* *= and /= */
|
26
|
+
token LSHIFTEQUAL /* <<= */
|
27
|
+
token RSHIFTEQUAL URSHIFTEQUAL /* >>= and >>>= */
|
28
|
+
token ANDEQUAL MODEQUAL /* &= and %= */
|
29
|
+
token XOREQUAL OREQUAL /* ^= and |= */
|
30
|
+
|
31
|
+
/* Terminal types */
|
32
|
+
token REGEXP
|
33
|
+
token NUMBER
|
34
|
+
token STRING
|
35
|
+
token IDENT
|
36
|
+
|
37
|
+
token AUTOPLUSPLUS AUTOMINUSMINUS IF_WITHOUT_ELSE
|
38
|
+
|
39
|
+
prechigh
|
40
|
+
nonassoc ELSE
|
41
|
+
nonassoc IF_WITHOUT_ELSE
|
42
|
+
preclow
|
43
|
+
|
44
|
+
rule
|
45
|
+
SourceElements:
|
46
|
+
/* nothing */ { result = SourceElementsNode.new([]) }
|
47
|
+
| SourceElementList { result = SourceElementsNode.new([val].flatten) }
|
48
|
+
|
49
|
+
SourceElementList:
|
50
|
+
SourceElement
|
51
|
+
| SourceElementList SourceElement { result = val.flatten }
|
52
|
+
;
|
53
|
+
|
54
|
+
SourceElement:
|
55
|
+
FunctionDeclaration
|
56
|
+
| Statement
|
57
|
+
;
|
58
|
+
|
59
|
+
Statement:
|
60
|
+
Block
|
61
|
+
| VariableStatement
|
62
|
+
| ConstStatement
|
63
|
+
| EmptyStatement
|
64
|
+
| ExprStatement
|
65
|
+
| IfStatement
|
66
|
+
| IterationStatement
|
67
|
+
| ContinueStatement
|
68
|
+
| BreakStatement
|
69
|
+
| ReturnStatement
|
70
|
+
| WithStatement
|
71
|
+
| SwitchStatement
|
72
|
+
| LabelledStatement
|
73
|
+
| ThrowStatement
|
74
|
+
| TryStatement
|
75
|
+
| DebuggerStatement
|
76
|
+
;
|
77
|
+
|
78
|
+
Literal:
|
79
|
+
NULL { result = NullNode.new(val.first) }
|
80
|
+
| TRUE { result = TrueNode.new(val.first) }
|
81
|
+
| FALSE { result = FalseNode.new(val.first) }
|
82
|
+
| NUMBER { result = NumberNode.new(val.first) }
|
83
|
+
| STRING { result = StringNode.new(val.first) }
|
84
|
+
| REGEXP { result = RegexpNode.new(val.first) }
|
85
|
+
;
|
86
|
+
|
87
|
+
Property:
|
88
|
+
IdentName ':' AssignmentExpr {
|
89
|
+
result = PropertyNode.new(val[0], val[2])
|
90
|
+
}
|
91
|
+
| STRING ':' AssignmentExpr { result = PropertyNode.new(val.first, val.last) }
|
92
|
+
| NUMBER ':' AssignmentExpr { result = PropertyNode.new(val.first, val.last) }
|
93
|
+
| IDENT IdentName '(' ')' FunctionBody {
|
94
|
+
klass = property_class_for(val.first)
|
95
|
+
yyabort unless klass
|
96
|
+
result = klass.new(val[1], FunctionExprNode.new(nil, val[4]))
|
97
|
+
}
|
98
|
+
| IDENT IdentName '(' FormalParameterList ')' FunctionBody {
|
99
|
+
klass = property_class_for(val.first)
|
100
|
+
yyabort unless klass
|
101
|
+
result = klass.new(val[1], FunctionExprNode.new(nil, val[5], val[3]))
|
102
|
+
}
|
103
|
+
;
|
104
|
+
|
105
|
+
IdentName:
|
106
|
+
IDENT
|
107
|
+
| NULL | TRUE | FALSE
|
108
|
+
| BREAK | CASE | CATCH | CONST | CONTINUE | DEBUGGER | DEFAULT | DELETE | DO | ELSE
|
109
|
+
| FINALLY | FOR | FUNCTION | IF | IN | INSTANCEOF | NEW | RETURN | SWITCH | THIS | THROW | TRY
|
110
|
+
| TYPEOF | VAR | VOID | WHILE | WITH
|
111
|
+
| RESERVED
|
112
|
+
;
|
113
|
+
|
114
|
+
PropertyList:
|
115
|
+
Property { result = val }
|
116
|
+
| PropertyList ',' Property { result = [val.first, val.last].flatten }
|
117
|
+
;
|
118
|
+
|
119
|
+
PrimaryExpr:
|
120
|
+
PrimaryExprNoBrace
|
121
|
+
| '{' '}' { result = ObjectLiteralNode.new([]) }
|
122
|
+
| '{' PropertyList '}' { result = ObjectLiteralNode.new(val[1]) }
|
123
|
+
| '{' PropertyList ',' '}' { result = ObjectLiteralNode.new(val[1]) }
|
124
|
+
;
|
125
|
+
|
126
|
+
PrimaryExprNoBrace:
|
127
|
+
THIS { result = ThisNode.new(val.first) }
|
128
|
+
| Literal
|
129
|
+
| ArrayLiteral
|
130
|
+
| IDENT { result = ResolveNode.new(val.first) }
|
131
|
+
| '(' Expr ')' { result = ParentheticalNode.new(val[1]) }
|
132
|
+
;
|
133
|
+
|
134
|
+
ArrayLiteral:
|
135
|
+
'[' ElisionOpt ']' { result = ArrayNode.new([] + [nil] * val[1]) }
|
136
|
+
| '[' ElementList ']' { result = ArrayNode.new(val[1]) }
|
137
|
+
| '[' ElementList ',' ElisionOpt ']' {
|
138
|
+
result = ArrayNode.new(val[1] + [nil] * val[3])
|
139
|
+
}
|
140
|
+
;
|
141
|
+
|
142
|
+
ElementList:
|
143
|
+
ElisionOpt AssignmentExpr {
|
144
|
+
result = [nil] * val[0] + [ElementNode.new(val[1])]
|
145
|
+
}
|
146
|
+
| ElementList ',' ElisionOpt AssignmentExpr {
|
147
|
+
result = [val[0], [nil] * val[2], ElementNode.new(val[3])].flatten
|
148
|
+
}
|
149
|
+
;
|
150
|
+
|
151
|
+
ElisionOpt:
|
152
|
+
/* nothing */ { result = 0 }
|
153
|
+
| Elision
|
154
|
+
;
|
155
|
+
|
156
|
+
Elision:
|
157
|
+
',' { result = 1 }
|
158
|
+
| Elision ',' { result = val.first + 1 }
|
159
|
+
;
|
160
|
+
|
161
|
+
MemberExpr:
|
162
|
+
PrimaryExpr
|
163
|
+
| FunctionExpr
|
164
|
+
| MemberExpr '[' Expr ']' { result = BracketAccessorNode.new(val[0], val[2]) }
|
165
|
+
| MemberExpr '.' IdentName { result = DotAccessorNode.new(val[0], val[2]) }
|
166
|
+
| NEW MemberExpr Arguments { result = NewExprNode.new(val[1], val[2]) }
|
167
|
+
;
|
168
|
+
|
169
|
+
MemberExprNoBF:
|
170
|
+
PrimaryExprNoBrace
|
171
|
+
| MemberExprNoBF '[' Expr ']' {
|
172
|
+
result = BracketAccessorNode.new(val[0], val[2])
|
173
|
+
}
|
174
|
+
| MemberExprNoBF '.' IdentName { result = DotAccessorNode.new(val[0], val[2]) }
|
175
|
+
| NEW MemberExpr Arguments { result = NewExprNode.new(val[1], val[2]) }
|
176
|
+
;
|
177
|
+
|
178
|
+
NewExpr:
|
179
|
+
MemberExpr
|
180
|
+
| NEW NewExpr { result = NewExprNode.new(val[1], ArgumentsNode.new([])) }
|
181
|
+
;
|
182
|
+
|
183
|
+
NewExprNoBF:
|
184
|
+
MemberExprNoBF
|
185
|
+
| NEW NewExpr { result = NewExprNode.new(val[1], ArgumentsNode.new([])) }
|
186
|
+
;
|
187
|
+
|
188
|
+
CallExpr:
|
189
|
+
MemberExpr Arguments { result = FunctionCallNode.new(val[0], val[1]) }
|
190
|
+
| CallExpr Arguments { result = FunctionCallNode.new(val[0], val[1]) }
|
191
|
+
| CallExpr '[' Expr ']' { result = BracketAccessorNode.new(val[0], val[2]) }
|
192
|
+
| CallExpr '.' IdentName { result = DotAccessorNode.new(val[0], val[2]) }
|
193
|
+
;
|
194
|
+
|
195
|
+
CallExprNoBF:
|
196
|
+
VOID '(' MemberExpr ')' { result = FunctionCallNode.new(ResolveNode.new(val[0]), val[2]) }
|
197
|
+
| MemberExprNoBF Arguments { result = FunctionCallNode.new(val[0], val[1]) }
|
198
|
+
| CallExprNoBF Arguments { result = FunctionCallNode.new(val[0], val[1]) }
|
199
|
+
| CallExprNoBF '[' Expr ']' { result = BracketAccessorNode.new(val[0], val[2]) }
|
200
|
+
| CallExprNoBF '.' IdentName { result = DotAccessorNode.new(val[0], val[2]) }
|
201
|
+
;
|
202
|
+
|
203
|
+
Arguments:
|
204
|
+
'(' ')' { result = ArgumentsNode.new([]) }
|
205
|
+
| '(' ArgumentList ')' { result = ArgumentsNode.new(val[1]); }
|
206
|
+
;
|
207
|
+
|
208
|
+
ArgumentList:
|
209
|
+
AssignmentExpr { result = val }
|
210
|
+
| ArgumentList ',' AssignmentExpr { result = [val[0], val[2]].flatten }
|
211
|
+
;
|
212
|
+
|
213
|
+
LeftHandSideExpr:
|
214
|
+
NewExpr
|
215
|
+
| CallExpr
|
216
|
+
;
|
217
|
+
|
218
|
+
LeftHandSideExprNoBF:
|
219
|
+
NewExprNoBF
|
220
|
+
| CallExprNoBF
|
221
|
+
;
|
222
|
+
|
223
|
+
PostfixExpr:
|
224
|
+
LeftHandSideExpr
|
225
|
+
| LeftHandSideExpr PLUSPLUS { result = PostfixNode.new(val[0], '++') }
|
226
|
+
| LeftHandSideExpr MINUSMINUS { result = PostfixNode.new(val[0], '--') }
|
227
|
+
;
|
228
|
+
|
229
|
+
PostfixExprNoBF:
|
230
|
+
LeftHandSideExprNoBF
|
231
|
+
| LeftHandSideExprNoBF PLUSPLUS { result = PostfixNode.new(val[0], '++') }
|
232
|
+
| LeftHandSideExprNoBF MINUSMINUS { result = PostfixNode.new(val[0], '--') }
|
233
|
+
;
|
234
|
+
|
235
|
+
UnaryExprCommon:
|
236
|
+
DELETE UnaryExpr { result = DeleteNode.new(val[1]) }
|
237
|
+
| VOID UnaryExpr { result = VoidNode.new(val[1]) }
|
238
|
+
| TYPEOF UnaryExpr { result = TypeOfNode.new(val[1]) }
|
239
|
+
| PLUSPLUS UnaryExpr { result = PrefixNode.new(val[1], '++') }
|
240
|
+
/* FIXME: Not sure when this can ever happen
|
241
|
+
| AUTOPLUSPLUS UnaryExpr { result = makePrefixNode($2, OpPlusPlus); } */
|
242
|
+
| MINUSMINUS UnaryExpr { result = PrefixNode.new(val[1], '--') }
|
243
|
+
/* FIXME: Not sure when this can ever happen
|
244
|
+
| AUTOMINUSMINUS UnaryExpr { result = makePrefixNode($2, OpMinusMinus); } */
|
245
|
+
| '+' UnaryExpr { result = UnaryPlusNode.new(val[1]) }
|
246
|
+
| '-' UnaryExpr { result = UnaryMinusNode.new(val[1]) }
|
247
|
+
| '~' UnaryExpr { result = BitwiseNotNode.new(val[1]) }
|
248
|
+
| '!' UnaryExpr { result = LogicalNotNode.new(val[1]) }
|
249
|
+
;
|
250
|
+
|
251
|
+
UnaryExpr:
|
252
|
+
PostfixExpr
|
253
|
+
| UnaryExprCommon
|
254
|
+
;
|
255
|
+
|
256
|
+
UnaryExprNoBF:
|
257
|
+
PostfixExprNoBF
|
258
|
+
| UnaryExprCommon
|
259
|
+
;
|
260
|
+
|
261
|
+
MultiplicativeExpr:
|
262
|
+
UnaryExpr
|
263
|
+
| MultiplicativeExpr '*' UnaryExpr { result = MultiplyNode.new(val[0],val[2])}
|
264
|
+
| MultiplicativeExpr '/' UnaryExpr { result = DivideNode.new(val[0], val[2]) }
|
265
|
+
| MultiplicativeExpr '%' UnaryExpr { result = ModulusNode.new(val[0], val[2])}
|
266
|
+
;
|
267
|
+
|
268
|
+
MultiplicativeExprNoBF:
|
269
|
+
UnaryExprNoBF
|
270
|
+
| MultiplicativeExprNoBF '*' UnaryExpr { result = MultiplyNode.new(val[0], val[2]) }
|
271
|
+
| MultiplicativeExprNoBF '/' UnaryExpr { result = DivideNode.new(val[0],val[2]) }
|
272
|
+
| MultiplicativeExprNoBF '%' UnaryExpr { result = ModulusNode.new(val[0], val[2]) }
|
273
|
+
;
|
274
|
+
|
275
|
+
AdditiveExpr:
|
276
|
+
MultiplicativeExpr
|
277
|
+
| AdditiveExpr '+' MultiplicativeExpr { result = AddNode.new(val[0], val[2]) }
|
278
|
+
| AdditiveExpr '-' MultiplicativeExpr { result = SubtractNode.new(val[0], val[2]) }
|
279
|
+
;
|
280
|
+
|
281
|
+
AdditiveExprNoBF:
|
282
|
+
MultiplicativeExprNoBF
|
283
|
+
| AdditiveExprNoBF '+' MultiplicativeExpr { result = AddNode.new(val[0], val[2]) }
|
284
|
+
| AdditiveExprNoBF '-' MultiplicativeExpr { result = SubtractNode.new(val[0], val[2]) }
|
285
|
+
;
|
286
|
+
|
287
|
+
ShiftExpr:
|
288
|
+
AdditiveExpr
|
289
|
+
| ShiftExpr LSHIFT AdditiveExpr { result = LeftShiftNode.new(val[0], val[2]) }
|
290
|
+
| ShiftExpr RSHIFT AdditiveExpr { result = RightShiftNode.new(val[0], val[2]) }
|
291
|
+
| ShiftExpr URSHIFT AdditiveExpr { result = UnsignedRightShiftNode.new(val[0], val[2]) }
|
292
|
+
;
|
293
|
+
|
294
|
+
ShiftExprNoBF:
|
295
|
+
AdditiveExprNoBF
|
296
|
+
| ShiftExprNoBF LSHIFT AdditiveExpr { result = LeftShiftNode.new(val[0], val[2]) }
|
297
|
+
| ShiftExprNoBF RSHIFT AdditiveExpr { result = RightShiftNode.new(val[0], val[2]) }
|
298
|
+
| ShiftExprNoBF URSHIFT AdditiveExpr { result = UnsignedRightShiftNode.new(val[0], val[2]) }
|
299
|
+
;
|
300
|
+
|
301
|
+
RelationalExpr:
|
302
|
+
ShiftExpr
|
303
|
+
| RelationalExpr '<' ShiftExpr { result = LessNode.new(val[0], val[2])}
|
304
|
+
| RelationalExpr '>' ShiftExpr { result = GreaterNode.new(val[0], val[2]) }
|
305
|
+
| RelationalExpr LE ShiftExpr { result = LessOrEqualNode.new(val[0], val[2]) }
|
306
|
+
| RelationalExpr GE ShiftExpr { result = GreaterOrEqualNode.new(val[0], val[2]) }
|
307
|
+
| RelationalExpr INSTANCEOF ShiftExpr { result = InstanceOfNode.new(val[0], val[2]) }
|
308
|
+
| RelationalExpr IN ShiftExpr { result = InNode.new(val[0], val[2]) }
|
309
|
+
;
|
310
|
+
|
311
|
+
RelationalExprNoIn:
|
312
|
+
ShiftExpr
|
313
|
+
| RelationalExprNoIn '<' ShiftExpr { result = LessNode.new(val[0], val[2])}
|
314
|
+
| RelationalExprNoIn '>' ShiftExpr { result = GreaterNode.new(val[0], val[2]) }
|
315
|
+
| RelationalExprNoIn LE ShiftExpr { result = LessOrEqualNode.new(val[0], val[2]) }
|
316
|
+
| RelationalExprNoIn GE ShiftExpr { result = GreaterOrEqualNode.new(val[0], val[2]) }
|
317
|
+
| RelationalExprNoIn INSTANCEOF ShiftExpr
|
318
|
+
{ result = InstanceOfNode.new(val[0], val[2]) }
|
319
|
+
;
|
320
|
+
|
321
|
+
RelationalExprNoBF:
|
322
|
+
ShiftExprNoBF
|
323
|
+
| RelationalExprNoBF '<' ShiftExpr { result = LessNode.new(val[0], val[2]) }
|
324
|
+
| RelationalExprNoBF '>' ShiftExpr { result = GreaterNode.new(val[0], val[2]) }
|
325
|
+
| RelationalExprNoBF LE ShiftExpr { result = LessOrEqualNode.new(val[0], val[2]) }
|
326
|
+
| RelationalExprNoBF GE ShiftExpr { result = GreaterOrEqualNode.new(val[0], val[2]) }
|
327
|
+
| RelationalExprNoBF INSTANCEOF ShiftExpr
|
328
|
+
{ result = InstanceOfNode.new(val[0], val[2]) }
|
329
|
+
| RelationalExprNoBF IN ShiftExpr { result = InNode.new(val[0], val[2]) }
|
330
|
+
;
|
331
|
+
|
332
|
+
EqualityExpr:
|
333
|
+
RelationalExpr
|
334
|
+
| EqualityExpr EQEQ RelationalExpr { result = EqualNode.new(val[0], val[2]) }
|
335
|
+
| EqualityExpr NE RelationalExpr { result = NotEqualNode.new(val[0], val[2]) }
|
336
|
+
| EqualityExpr STREQ RelationalExpr { result = StrictEqualNode.new(val[0], val[2]) }
|
337
|
+
| EqualityExpr STRNEQ RelationalExpr { result = NotStrictEqualNode.new(val[0], val[2]) }
|
338
|
+
;
|
339
|
+
|
340
|
+
EqualityExprNoIn:
|
341
|
+
RelationalExprNoIn
|
342
|
+
| EqualityExprNoIn EQEQ RelationalExprNoIn
|
343
|
+
{ result = EqualNode.new(val[0], val[2]) }
|
344
|
+
| EqualityExprNoIn NE RelationalExprNoIn
|
345
|
+
{ result = NotEqualNode.new(val[0], val[2]) }
|
346
|
+
| EqualityExprNoIn STREQ RelationalExprNoIn
|
347
|
+
{ result = StrictEqualNode.new(val[0], val[2]) }
|
348
|
+
| EqualityExprNoIn STRNEQ RelationalExprNoIn
|
349
|
+
{ result = NotStrictEqualNode.new(val[0], val[2]) }
|
350
|
+
;
|
351
|
+
|
352
|
+
EqualityExprNoBF:
|
353
|
+
RelationalExprNoBF
|
354
|
+
| EqualityExprNoBF EQEQ RelationalExpr
|
355
|
+
{ result = EqualNode.new(val[0], val[2]) }
|
356
|
+
| EqualityExprNoBF NE RelationalExpr { result = NotEqualNode.new(val[0], val[2]) }
|
357
|
+
| EqualityExprNoBF STREQ RelationalExpr
|
358
|
+
{ result = StrictEqualNode.new(val[0], val[2]) }
|
359
|
+
| EqualityExprNoBF STRNEQ RelationalExpr
|
360
|
+
{ result = NotStrictEqualNode.new(val[0], val[2]) }
|
361
|
+
;
|
362
|
+
|
363
|
+
BitwiseANDExpr:
|
364
|
+
EqualityExpr
|
365
|
+
| BitwiseANDExpr '&' EqualityExpr { result = BitAndNode.new(val[0], val[2]) }
|
366
|
+
;
|
367
|
+
|
368
|
+
BitwiseANDExprNoIn:
|
369
|
+
EqualityExprNoIn
|
370
|
+
| BitwiseANDExprNoIn '&' EqualityExprNoIn
|
371
|
+
{ result = BitAndNode.new(val[0], val[2]) }
|
372
|
+
;
|
373
|
+
|
374
|
+
BitwiseANDExprNoBF:
|
375
|
+
EqualityExprNoBF
|
376
|
+
| BitwiseANDExprNoBF '&' EqualityExpr { result = BitAndNode.new(val[0], val[2]) }
|
377
|
+
;
|
378
|
+
|
379
|
+
BitwiseXORExpr:
|
380
|
+
BitwiseANDExpr
|
381
|
+
| BitwiseXORExpr '^' BitwiseANDExpr { result = BitXOrNode.new(val[0], val[2]) }
|
382
|
+
;
|
383
|
+
|
384
|
+
BitwiseXORExprNoIn:
|
385
|
+
BitwiseANDExprNoIn
|
386
|
+
| BitwiseXORExprNoIn '^' BitwiseANDExprNoIn
|
387
|
+
{ result = BitXOrNode.new(val[0], val[2]) }
|
388
|
+
;
|
389
|
+
|
390
|
+
BitwiseXORExprNoBF:
|
391
|
+
BitwiseANDExprNoBF
|
392
|
+
| BitwiseXORExprNoBF '^' BitwiseANDExpr
|
393
|
+
{ result = BitXOrNode.new(val[0], val[2]) }
|
394
|
+
;
|
395
|
+
|
396
|
+
BitwiseORExpr:
|
397
|
+
BitwiseXORExpr
|
398
|
+
| BitwiseORExpr '|' BitwiseXORExpr { result = BitOrNode.new(val[0], val[2]) }
|
399
|
+
;
|
400
|
+
|
401
|
+
BitwiseORExprNoIn:
|
402
|
+
BitwiseXORExprNoIn
|
403
|
+
| BitwiseORExprNoIn '|' BitwiseXORExprNoIn
|
404
|
+
{ result = BitOrNode.new(val[0], val[2]) }
|
405
|
+
;
|
406
|
+
|
407
|
+
BitwiseORExprNoBF:
|
408
|
+
BitwiseXORExprNoBF
|
409
|
+
| BitwiseORExprNoBF '|' BitwiseXORExpr
|
410
|
+
{ result = BitOrNode.new(val[0], val[2]) }
|
411
|
+
;
|
412
|
+
|
413
|
+
LogicalANDExpr:
|
414
|
+
BitwiseORExpr
|
415
|
+
| LogicalANDExpr AND BitwiseORExpr { result = LogicalAndNode.new(val[0], val[2]) }
|
416
|
+
;
|
417
|
+
|
418
|
+
LogicalANDExprNoIn:
|
419
|
+
BitwiseORExprNoIn
|
420
|
+
| LogicalANDExprNoIn AND BitwiseORExprNoIn
|
421
|
+
{ result = LogicalAndNode.new(val[0], val[2]) }
|
422
|
+
;
|
423
|
+
|
424
|
+
LogicalANDExprNoBF:
|
425
|
+
BitwiseORExprNoBF
|
426
|
+
| LogicalANDExprNoBF AND BitwiseORExpr
|
427
|
+
{ result = LogicalAndNode.new(val[0], val[2]) }
|
428
|
+
;
|
429
|
+
|
430
|
+
LogicalORExpr:
|
431
|
+
LogicalANDExpr
|
432
|
+
| LogicalORExpr OR LogicalANDExpr { result = LogicalOrNode.new(val[0], val[2]) }
|
433
|
+
;
|
434
|
+
|
435
|
+
LogicalORExprNoIn:
|
436
|
+
LogicalANDExprNoIn
|
437
|
+
| LogicalORExprNoIn OR LogicalANDExprNoIn
|
438
|
+
{ result = LogicalOrNode.new(val[0], val[2]) }
|
439
|
+
;
|
440
|
+
|
441
|
+
LogicalORExprNoBF:
|
442
|
+
LogicalANDExprNoBF
|
443
|
+
| LogicalORExprNoBF OR LogicalANDExpr { result = LogicalOrNode.new(val[0], val[2]) }
|
444
|
+
;
|
445
|
+
|
446
|
+
ConditionalExpr:
|
447
|
+
LogicalORExpr
|
448
|
+
| LogicalORExpr '?' AssignmentExpr ':' AssignmentExpr {
|
449
|
+
result = ConditionalNode.new(val[0], val[2], val[4])
|
450
|
+
}
|
451
|
+
;
|
452
|
+
|
453
|
+
ConditionalExprNoIn:
|
454
|
+
LogicalORExprNoIn
|
455
|
+
| LogicalORExprNoIn '?' AssignmentExprNoIn ':' AssignmentExprNoIn {
|
456
|
+
result = ConditionalNode.new(val[0], val[2], val[4])
|
457
|
+
}
|
458
|
+
;
|
459
|
+
|
460
|
+
ConditionalExprNoBF:
|
461
|
+
LogicalORExprNoBF
|
462
|
+
| LogicalORExprNoBF '?' AssignmentExpr ':' AssignmentExpr {
|
463
|
+
result = ConditionalNode.new(val[0], val[2], val[4])
|
464
|
+
}
|
465
|
+
;
|
466
|
+
|
467
|
+
AssignmentExpr:
|
468
|
+
ConditionalExpr
|
469
|
+
| LeftHandSideExpr AssignmentOperator AssignmentExpr {
|
470
|
+
result = val[1].new(val.first, val.last)
|
471
|
+
}
|
472
|
+
;
|
473
|
+
|
474
|
+
AssignmentExprNoIn:
|
475
|
+
ConditionalExprNoIn
|
476
|
+
| LeftHandSideExpr AssignmentOperator AssignmentExprNoIn {
|
477
|
+
result = val[1].new(val.first, val.last)
|
478
|
+
}
|
479
|
+
;
|
480
|
+
|
481
|
+
AssignmentExprNoBF:
|
482
|
+
ConditionalExprNoBF
|
483
|
+
| LeftHandSideExprNoBF AssignmentOperator AssignmentExpr {
|
484
|
+
result = val[1].new(val.first, val.last)
|
485
|
+
}
|
486
|
+
;
|
487
|
+
|
488
|
+
AssignmentOperator:
|
489
|
+
'=' { result = OpEqualNode }
|
490
|
+
| PLUSEQUAL { result = OpPlusEqualNode }
|
491
|
+
| MINUSEQUAL { result = OpMinusEqualNode }
|
492
|
+
| MULTEQUAL { result = OpMultiplyEqualNode }
|
493
|
+
| DIVEQUAL { result = OpDivideEqualNode }
|
494
|
+
| LSHIFTEQUAL { result = OpLShiftEqualNode }
|
495
|
+
| RSHIFTEQUAL { result = OpRShiftEqualNode }
|
496
|
+
| URSHIFTEQUAL { result = OpURShiftEqualNode }
|
497
|
+
| ANDEQUAL { result = OpAndEqualNode }
|
498
|
+
| XOREQUAL { result = OpXOrEqualNode }
|
499
|
+
| OREQUAL { result = OpOrEqualNode }
|
500
|
+
| MODEQUAL { result = OpModEqualNode }
|
501
|
+
;
|
502
|
+
|
503
|
+
Expr:
|
504
|
+
AssignmentExpr
|
505
|
+
| Expr ',' AssignmentExpr { result = CommaNode.new(val[0], val[2]) }
|
506
|
+
;
|
507
|
+
|
508
|
+
ExprNoIn:
|
509
|
+
AssignmentExprNoIn
|
510
|
+
| ExprNoIn ',' AssignmentExprNoIn { result = CommaNode.new(val[0], val[2]) }
|
511
|
+
;
|
512
|
+
|
513
|
+
ExprNoBF:
|
514
|
+
AssignmentExprNoBF
|
515
|
+
| ExprNoBF ',' AssignmentExpr { result = CommaNode.new(val[0], val[2]) }
|
516
|
+
;
|
517
|
+
|
518
|
+
|
519
|
+
Block:
|
520
|
+
'{' SourceElements '}' {
|
521
|
+
result = BlockNode.new(val[1])
|
522
|
+
debug(result)
|
523
|
+
}
|
524
|
+
;
|
525
|
+
|
526
|
+
VariableStatement:
|
527
|
+
VAR VariableDeclarationList ';' {
|
528
|
+
result = VarStatementNode.new(val[1])
|
529
|
+
debug(result)
|
530
|
+
}
|
531
|
+
| VAR VariableDeclarationList error {
|
532
|
+
result = VarStatementNode.new(val[1])
|
533
|
+
debug(result)
|
534
|
+
yyabort unless allow_auto_semi?(val.last)
|
535
|
+
}
|
536
|
+
;
|
537
|
+
|
538
|
+
VariableDeclarationList:
|
539
|
+
VariableDeclaration { result = val }
|
540
|
+
| VariableDeclarationList ',' VariableDeclaration {
|
541
|
+
result = [val.first, val.last].flatten
|
542
|
+
}
|
543
|
+
;
|
544
|
+
|
545
|
+
VariableDeclarationListNoIn:
|
546
|
+
VariableDeclarationNoIn { result = val }
|
547
|
+
| VariableDeclarationListNoIn ',' VariableDeclarationNoIn {
|
548
|
+
result = [val.first, val.last].flatten
|
549
|
+
}
|
550
|
+
;
|
551
|
+
|
552
|
+
VariableDeclaration:
|
553
|
+
IDENT { result = VarDeclNode.new(val.first, nil) }
|
554
|
+
| IDENT Initializer { result = VarDeclNode.new(val.first, val[1]) }
|
555
|
+
;
|
556
|
+
|
557
|
+
VariableDeclarationNoIn:
|
558
|
+
IDENT { result = VarDeclNode.new(val[0],nil) }
|
559
|
+
| IDENT InitializerNoIn { result = VarDeclNode.new(val[0], val[1]) }
|
560
|
+
;
|
561
|
+
|
562
|
+
ConstStatement:
|
563
|
+
CONST ConstDeclarationList ';' {
|
564
|
+
result = ConstStatementNode.new(val[1])
|
565
|
+
debug(result)
|
566
|
+
}
|
567
|
+
| CONST ConstDeclarationList error {
|
568
|
+
result = ConstStatementNode.new(val[1])
|
569
|
+
debug(result)
|
570
|
+
yyerror unless allow_auto_semi?(val.last)
|
571
|
+
}
|
572
|
+
;
|
573
|
+
|
574
|
+
ConstDeclarationList:
|
575
|
+
ConstDeclaration { result = val }
|
576
|
+
| ConstDeclarationList ',' ConstDeclaration {
|
577
|
+
result = [val.first, val.last].flatten
|
578
|
+
}
|
579
|
+
;
|
580
|
+
|
581
|
+
ConstDeclaration:
|
582
|
+
IDENT { result = VarDeclNode.new(val[0], nil, true) }
|
583
|
+
| IDENT Initializer { result = VarDeclNode.new(val[0], val[1], true) }
|
584
|
+
;
|
585
|
+
|
586
|
+
Initializer:
|
587
|
+
'=' AssignmentExpr { result = AssignExprNode.new(val[1]) }
|
588
|
+
;
|
589
|
+
|
590
|
+
InitializerNoIn:
|
591
|
+
'=' AssignmentExprNoIn { result = AssignExprNode.new(val[1]) }
|
592
|
+
;
|
593
|
+
|
594
|
+
EmptyStatement:
|
595
|
+
';' { result = EmptyStatementNode.new(val[0]) }
|
596
|
+
;
|
597
|
+
|
598
|
+
ExprStatement:
|
599
|
+
ExprNoBF ';' {
|
600
|
+
result = ExpressionStatementNode.new(val.first)
|
601
|
+
debug(result)
|
602
|
+
}
|
603
|
+
| ExprNoBF error {
|
604
|
+
result = ExpressionStatementNode.new(val.first)
|
605
|
+
debug(result)
|
606
|
+
raise RKelly::SyntaxError unless allow_auto_semi?(val.last)
|
607
|
+
}
|
608
|
+
;
|
609
|
+
|
610
|
+
IfStatement:
|
611
|
+
IF '(' Expr ')' Statement =IF_WITHOUT_ELSE {
|
612
|
+
result = IfNode.new(val[2], val[4])
|
613
|
+
debug(result)
|
614
|
+
}
|
615
|
+
| IF '(' Expr ')' Statement ELSE Statement {
|
616
|
+
result = IfNode.new(val[2], val[4], val[6])
|
617
|
+
debug(result)
|
618
|
+
}
|
619
|
+
;
|
620
|
+
|
621
|
+
IterationStatement:
|
622
|
+
DO Statement WHILE '(' Expr ')' ';' {
|
623
|
+
result = DoWhileNode.new(val[1], val[4])
|
624
|
+
debug(result)
|
625
|
+
}
|
626
|
+
| DO Statement WHILE '(' Expr ')' error {
|
627
|
+
result = DoWhileNode.new(val[1], val[4])
|
628
|
+
debug(result)
|
629
|
+
} /* Always performs automatic semicolon insertion. */
|
630
|
+
| WHILE '(' Expr ')' Statement {
|
631
|
+
result = WhileNode.new(val[2], val[4])
|
632
|
+
debug(result)
|
633
|
+
}
|
634
|
+
| FOR '(' ExprNoInOpt ';' ExprOpt ';' ExprOpt ')' Statement {
|
635
|
+
result = ForNode.new(val[2], val[4], val[6], val[8])
|
636
|
+
debug(result)
|
637
|
+
}
|
638
|
+
| FOR '(' VAR VariableDeclarationListNoIn ';' ExprOpt ';' ExprOpt ')' Statement
|
639
|
+
{
|
640
|
+
result = ForNode.new(VarStatementNode.new(val[3]), val[5], val[7], val[9])
|
641
|
+
debug(result)
|
642
|
+
}
|
643
|
+
| FOR '(' LeftHandSideExpr IN Expr ')' Statement {
|
644
|
+
#yyabort if (!n.isLocation())
|
645
|
+
result = ForInNode.new(val[2], val[4], val[6])
|
646
|
+
debug(result);
|
647
|
+
}
|
648
|
+
| FOR '(' VAR IDENT IN Expr ')' Statement {
|
649
|
+
result = ForInNode.new(
|
650
|
+
VarDeclNode.new(val[3], nil), val[5], val[7])
|
651
|
+
debug(result)
|
652
|
+
}
|
653
|
+
| FOR '(' VAR IDENT InitializerNoIn IN Expr ')' Statement {
|
654
|
+
result = ForInNode.new(
|
655
|
+
VarDeclNode.new(val[3], val[4]), val[6], val[8]
|
656
|
+
)
|
657
|
+
debug(result)
|
658
|
+
}
|
659
|
+
;
|
660
|
+
|
661
|
+
ExprOpt:
|
662
|
+
/* nothing */ { result = nil }
|
663
|
+
| Expr
|
664
|
+
;
|
665
|
+
|
666
|
+
ExprNoInOpt:
|
667
|
+
/* nothing */ { result = nil }
|
668
|
+
| ExprNoIn
|
669
|
+
;
|
670
|
+
|
671
|
+
ContinueStatement:
|
672
|
+
CONTINUE ';' {
|
673
|
+
result = ContinueNode.new(nil)
|
674
|
+
debug(result)
|
675
|
+
}
|
676
|
+
| CONTINUE error {
|
677
|
+
result = ContinueNode.new(nil)
|
678
|
+
debug(result)
|
679
|
+
yyabort unless allow_auto_semi?(val[1])
|
680
|
+
}
|
681
|
+
| CONTINUE IDENT ';' {
|
682
|
+
result = ContinueNode.new(val[1])
|
683
|
+
debug(result)
|
684
|
+
}
|
685
|
+
| CONTINUE IDENT error {
|
686
|
+
result = ContinueNode.new(val[1])
|
687
|
+
debug(result)
|
688
|
+
yyabort unless allow_auto_semi?(val[2])
|
689
|
+
}
|
690
|
+
;
|
691
|
+
|
692
|
+
BreakStatement:
|
693
|
+
BREAK ';' {
|
694
|
+
result = BreakNode.new(nil)
|
695
|
+
debug(result)
|
696
|
+
}
|
697
|
+
| BREAK error {
|
698
|
+
result = BreakNode.new(nil)
|
699
|
+
debug(result)
|
700
|
+
yyabort unless allow_auto_semi?(val[1])
|
701
|
+
}
|
702
|
+
| BREAK IDENT ';' {
|
703
|
+
result = BreakNode.new(val[1])
|
704
|
+
debug(result)
|
705
|
+
}
|
706
|
+
| BREAK IDENT error {
|
707
|
+
result = BreakNode.new(val[1])
|
708
|
+
debug(result)
|
709
|
+
yyabort unless allow_auto_semi?(val[2])
|
710
|
+
}
|
711
|
+
;
|
712
|
+
|
713
|
+
ReturnStatement:
|
714
|
+
RETURN ';' {
|
715
|
+
result = ReturnNode.new(nil)
|
716
|
+
debug(result)
|
717
|
+
}
|
718
|
+
| RETURN error {
|
719
|
+
result = ReturnNode.new(nil)
|
720
|
+
debug(result)
|
721
|
+
yyabort unless allow_auto_semi?(val[1])
|
722
|
+
}
|
723
|
+
| RETURN Expr ';' {
|
724
|
+
result = ReturnNode.new(val[1])
|
725
|
+
debug(result)
|
726
|
+
}
|
727
|
+
| RETURN Expr error {
|
728
|
+
result = ReturnNode.new(val[1])
|
729
|
+
debug(result)
|
730
|
+
yyabort unless allow_auto_semi?(val[2])
|
731
|
+
}
|
732
|
+
;
|
733
|
+
|
734
|
+
WithStatement:
|
735
|
+
WITH '(' Expr ')' Statement {
|
736
|
+
result = WithNode.new(val[2], val[4])
|
737
|
+
debug(result)
|
738
|
+
}
|
739
|
+
;
|
740
|
+
|
741
|
+
SwitchStatement:
|
742
|
+
SWITCH '(' Expr ')' CaseBlock {
|
743
|
+
result = SwitchNode.new(val[2], val[4])
|
744
|
+
debug(result)
|
745
|
+
}
|
746
|
+
;
|
747
|
+
|
748
|
+
CaseBlock:
|
749
|
+
'{' CaseClausesOpt '}' { result = CaseBlockNode.new(val[1]) }
|
750
|
+
| '{' CaseClausesOpt DefaultClause CaseClausesOpt '}' {
|
751
|
+
result = CaseBlockNode.new([val[1], val[2], val[3]].flatten)
|
752
|
+
}
|
753
|
+
;
|
754
|
+
|
755
|
+
CaseClausesOpt:
|
756
|
+
/* nothing */ { result = [] }
|
757
|
+
| CaseClauses
|
758
|
+
;
|
759
|
+
|
760
|
+
CaseClauses:
|
761
|
+
CaseClause { result = val }
|
762
|
+
| CaseClauses CaseClause { result = val.flatten }
|
763
|
+
;
|
764
|
+
|
765
|
+
CaseClause:
|
766
|
+
CASE Expr ':' SourceElements {
|
767
|
+
result = CaseClauseNode.new(val[1], val[3])
|
768
|
+
}
|
769
|
+
;
|
770
|
+
|
771
|
+
DefaultClause:
|
772
|
+
DEFAULT ':' SourceElements {
|
773
|
+
result = CaseClauseNode.new(nil, val[2])
|
774
|
+
}
|
775
|
+
;
|
776
|
+
|
777
|
+
LabelledStatement:
|
778
|
+
IDENT ':' Statement { result = LabelNode.new(val[0], val[2]) }
|
779
|
+
;
|
780
|
+
|
781
|
+
ThrowStatement:
|
782
|
+
THROW Expr ';' {
|
783
|
+
result = ThrowNode.new(val[1])
|
784
|
+
debug(result)
|
785
|
+
}
|
786
|
+
| THROW Expr error {
|
787
|
+
result = ThrowNode.new(val[1])
|
788
|
+
debug(result)
|
789
|
+
yyabort unless allow_auto_semi?(val[2])
|
790
|
+
}
|
791
|
+
;
|
792
|
+
|
793
|
+
TryStatement:
|
794
|
+
TRY Block FINALLY Block {
|
795
|
+
result = TryNode.new(val[1], nil, nil, val[3])
|
796
|
+
debug(result)
|
797
|
+
}
|
798
|
+
| TRY Block CATCH '(' IDENT ')' Block {
|
799
|
+
result = TryNode.new(val[1], val[4], val[6])
|
800
|
+
debug(result)
|
801
|
+
}
|
802
|
+
| TRY Block CATCH '(' IDENT ')' Block FINALLY Block {
|
803
|
+
result = TryNode.new(val[1], val[4], val[6], val[8])
|
804
|
+
debug(result)
|
805
|
+
}
|
806
|
+
;
|
807
|
+
|
808
|
+
DebuggerStatement:
|
809
|
+
DEBUGGER ';' {
|
810
|
+
result = EmptyStatementNode.new(val[0])
|
811
|
+
debug(result)
|
812
|
+
}
|
813
|
+
| DEBUGGER error {
|
814
|
+
result = EmptyStatementNode.new(val[0])
|
815
|
+
debug(result)
|
816
|
+
yyabort unless allow_auto_semi?(val[1])
|
817
|
+
}
|
818
|
+
;
|
819
|
+
|
820
|
+
FunctionDeclaration:
|
821
|
+
FUNCTION IDENT '(' ')' FunctionBody {
|
822
|
+
result = FunctionDeclNode.new(val[1], val[4])
|
823
|
+
debug(val[5])
|
824
|
+
}
|
825
|
+
| FUNCTION IDENT '(' FormalParameterList ')' FunctionBody {
|
826
|
+
result = FunctionDeclNode.new(val[1], val[5], val[3])
|
827
|
+
debug(val[6])
|
828
|
+
}
|
829
|
+
;
|
830
|
+
|
831
|
+
FunctionExpr:
|
832
|
+
FUNCTION '(' ')' FunctionBody {
|
833
|
+
result = FunctionExprNode.new(val[0], val[3])
|
834
|
+
debug(val[4])
|
835
|
+
}
|
836
|
+
| FUNCTION '(' FormalParameterList ')' FunctionBody {
|
837
|
+
result = FunctionExprNode.new(val[0], val[4], val[2])
|
838
|
+
debug(val[5])
|
839
|
+
}
|
840
|
+
| FUNCTION IDENT '(' ')' FunctionBody {
|
841
|
+
result = FunctionExprNode.new(val[1], val[4])
|
842
|
+
debug(val[5])
|
843
|
+
}
|
844
|
+
| FUNCTION IDENT '(' FormalParameterList ')' FunctionBody {
|
845
|
+
result = FunctionExprNode.new(val[1], val[5], val[3])
|
846
|
+
debug(val[6])
|
847
|
+
}
|
848
|
+
;
|
849
|
+
|
850
|
+
FormalParameterList:
|
851
|
+
IDENT { result = [ParameterNode.new(val[0])] }
|
852
|
+
| FormalParameterList ',' IDENT {
|
853
|
+
result = [val.first, ParameterNode.new(val.last)].flatten
|
854
|
+
}
|
855
|
+
;
|
856
|
+
|
857
|
+
FunctionBody:
|
858
|
+
'{' SourceElements '}' { result = FunctionBodyNode.new(val[1]) }
|
859
|
+
;
|
860
|
+
end
|
861
|
+
|
862
|
+
---- header
|
863
|
+
require "rkelly/nodes"
|
864
|
+
|
865
|
+
---- inner
|
866
|
+
include RKelly::Nodes
|
867
|
+
|
868
|
+
def allow_auto_semi?(error_token)
|
869
|
+
error_token == false || error_token == '}' || @terminator
|
870
|
+
end
|
871
|
+
|
872
|
+
def property_class_for(ident)
|
873
|
+
case ident
|
874
|
+
when 'get'
|
875
|
+
GetterPropertyNode
|
876
|
+
when 'set'
|
877
|
+
SetterPropertyNode
|
878
|
+
end
|
879
|
+
end
|
880
|
+
|
881
|
+
def debug(*args)
|
882
|
+
logger.debug(*args) if logger
|
883
|
+
end
|