brakeman 5.2.1 → 5.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (205) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +25 -0
  3. data/bundle/load.rb +4 -4
  4. data/bundle/ruby/2.7.0/gems/{parallel-1.21.0 → parallel-1.22.1}/MIT-LICENSE.txt +0 -0
  5. data/bundle/ruby/2.7.0/gems/{parallel-1.21.0 → parallel-1.22.1}/lib/parallel/processor_count.rb +2 -3
  6. data/bundle/ruby/2.7.0/gems/parallel-1.22.1/lib/parallel/version.rb +4 -0
  7. data/bundle/ruby/2.7.0/gems/{parallel-1.21.0 → parallel-1.22.1}/lib/parallel.rb +84 -4
  8. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/History.rdoc +28 -0
  9. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/Manifest.txt +2 -0
  10. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/README.rdoc +8 -6
  11. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/compare/normalize.rb +0 -0
  12. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/debugging.md +0 -0
  13. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/gauntlet.md +19 -18
  14. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/rp_extensions.rb +0 -0
  15. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/rp_stringscanner.rb +0 -0
  16. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby20_parser.rb +10973 -0
  17. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby20_parser.y +14 -27
  18. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby21_parser.rb +10980 -0
  19. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby21_parser.y +14 -27
  20. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby22_parser.rb +11123 -0
  21. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby22_parser.y +14 -27
  22. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby23_parser.rb +11132 -0
  23. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby23_parser.y +14 -27
  24. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby24_parser.rb +11231 -0
  25. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby24_parser.y +14 -27
  26. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby25_parser.rb +11231 -0
  27. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby25_parser.y +14 -27
  28. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby26_parser.rb +11253 -0
  29. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby26_parser.y +14 -27
  30. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby27_parser.rb +12980 -0
  31. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby27_parser.y +19 -41
  32. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby30_parser.rb +13242 -0
  33. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby30_parser.y +65 -90
  34. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby31_parser.rb +13622 -0
  35. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1/lib/ruby3_parser.yy → ruby_parser-3.19.1/lib/ruby31_parser.y} +110 -105
  36. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby3_parser.yy +3536 -0
  37. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby_lexer.rb +0 -0
  38. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby_lexer.rex +0 -0
  39. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby_lexer.rex.rb +0 -0
  40. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby_lexer_strings.rb +0 -0
  41. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby_parser.rb +2 -0
  42. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby_parser.yy +19 -41
  43. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/lib/ruby_parser_extras.rb +55 -2
  44. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/tools/munge.rb +0 -0
  45. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.1 → ruby_parser-3.19.1}/tools/ripper.rb +0 -0
  46. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.16.0 → sexp_processor-4.16.1}/History.rdoc +6 -0
  47. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.16.0 → sexp_processor-4.16.1}/Manifest.txt +0 -0
  48. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.16.0 → sexp_processor-4.16.1}/README.rdoc +0 -0
  49. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.16.0 → sexp_processor-4.16.1}/lib/composite_sexp_processor.rb +0 -0
  50. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.16.0 → sexp_processor-4.16.1}/lib/pt_testcase.rb +7 -3
  51. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.16.0 → sexp_processor-4.16.1}/lib/sexp.rb +0 -0
  52. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.16.0 → sexp_processor-4.16.1}/lib/sexp_matcher.rb +0 -0
  53. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.16.0 → sexp_processor-4.16.1}/lib/sexp_processor.rb +1 -1
  54. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.16.0 → sexp_processor-4.16.1}/lib/strict_sexp.rb +0 -0
  55. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.16.0 → sexp_processor-4.16.1}/lib/unique.rb +0 -0
  56. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/COPYING +0 -0
  57. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/asciidoc.rb +0 -0
  58. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/babel.rb +0 -0
  59. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/bluecloth.rb +0 -0
  60. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/builder.rb +0 -0
  61. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/coffee.rb +0 -0
  62. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/commonmarker.rb +11 -1
  63. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/creole.rb +0 -0
  64. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/csv.rb +1 -1
  65. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/dummy.rb +0 -0
  66. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/erb.rb +0 -0
  67. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/erubi.rb +0 -0
  68. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/erubis.rb +0 -0
  69. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/etanni.rb +0 -0
  70. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/haml.rb +0 -0
  71. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/kramdown.rb +0 -0
  72. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/less.rb +0 -0
  73. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/liquid.rb +0 -0
  74. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/livescript.rb +0 -0
  75. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/mapping.rb +0 -0
  76. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/markaby.rb +0 -0
  77. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/maruku.rb +0 -0
  78. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/nokogiri.rb +0 -0
  79. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/pandoc.rb +23 -15
  80. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/plain.rb +0 -0
  81. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/prawn.rb +0 -0
  82. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/radius.rb +0 -0
  83. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/rdiscount.rb +0 -0
  84. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/rdoc.rb +0 -0
  85. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/redcarpet.rb +5 -2
  86. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/redcloth.rb +0 -0
  87. data/bundle/ruby/2.7.0/gems/tilt-2.0.11/lib/tilt/rst-pandoc.rb +23 -0
  88. data/bundle/ruby/2.7.0/gems/tilt-2.0.11/lib/tilt/sass.rb +78 -0
  89. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/sigil.rb +0 -0
  90. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/string.rb +0 -0
  91. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/template.rb +12 -1
  92. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/typescript.rb +0 -0
  93. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/wikicloth.rb +0 -0
  94. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt/yajl.rb +0 -0
  95. data/bundle/ruby/2.7.0/gems/{tilt-2.0.10 → tilt-2.0.11}/lib/tilt.rb +2 -1
  96. data/lib/brakeman/app_tree.rb +9 -1
  97. data/lib/brakeman/checks/check_basic_auth.rb +4 -2
  98. data/lib/brakeman/checks/check_basic_auth_timing_attack.rb +2 -1
  99. data/lib/brakeman/checks/check_content_tag.rb +8 -4
  100. data/lib/brakeman/checks/check_cookie_serialization.rb +2 -1
  101. data/lib/brakeman/checks/check_create_with.rb +4 -2
  102. data/lib/brakeman/checks/check_cross_site_scripting.rb +6 -3
  103. data/lib/brakeman/checks/check_csrf_token_forgery_cve.rb +2 -1
  104. data/lib/brakeman/checks/check_default_routes.rb +6 -3
  105. data/lib/brakeman/checks/check_deserialize.rb +2 -1
  106. data/lib/brakeman/checks/check_detailed_exceptions.rb +4 -2
  107. data/lib/brakeman/checks/check_digest_dos.rb +2 -1
  108. data/lib/brakeman/checks/check_divide_by_zero.rb +2 -1
  109. data/lib/brakeman/checks/check_dynamic_finders.rb +2 -1
  110. data/lib/brakeman/checks/check_escape_function.rb +2 -1
  111. data/lib/brakeman/checks/check_evaluation.rb +2 -1
  112. data/lib/brakeman/checks/check_execute.rb +6 -3
  113. data/lib/brakeman/checks/check_file_access.rb +2 -1
  114. data/lib/brakeman/checks/check_file_disclosure.rb +2 -1
  115. data/lib/brakeman/checks/check_filter_skipping.rb +2 -1
  116. data/lib/brakeman/checks/check_force_ssl.rb +2 -1
  117. data/lib/brakeman/checks/check_forgery_setting.rb +4 -2
  118. data/lib/brakeman/checks/check_header_dos.rb +2 -1
  119. data/lib/brakeman/checks/check_i18n_xss.rb +2 -1
  120. data/lib/brakeman/checks/check_jruby_xml.rb +2 -1
  121. data/lib/brakeman/checks/check_json_encoding.rb +2 -1
  122. data/lib/brakeman/checks/check_json_entity_escape.rb +4 -2
  123. data/lib/brakeman/checks/check_json_parsing.rb +4 -2
  124. data/lib/brakeman/checks/check_link_to.rb +2 -1
  125. data/lib/brakeman/checks/check_link_to_href.rb +4 -2
  126. data/lib/brakeman/checks/check_mail_to.rb +2 -1
  127. data/lib/brakeman/checks/check_mass_assignment.rb +6 -3
  128. data/lib/brakeman/checks/check_mime_type_dos.rb +2 -1
  129. data/lib/brakeman/checks/check_model_attr_accessible.rb +2 -1
  130. data/lib/brakeman/checks/check_model_attributes.rb +4 -2
  131. data/lib/brakeman/checks/check_model_serialize.rb +2 -1
  132. data/lib/brakeman/checks/check_nested_attributes.rb +2 -1
  133. data/lib/brakeman/checks/check_nested_attributes_bypass.rb +2 -1
  134. data/lib/brakeman/checks/check_number_to_currency.rb +4 -2
  135. data/lib/brakeman/checks/check_page_caching_cve.rb +2 -1
  136. data/lib/brakeman/checks/check_permit_attributes.rb +2 -1
  137. data/lib/brakeman/checks/check_quote_table_name.rb +2 -1
  138. data/lib/brakeman/checks/check_redirect.rb +2 -1
  139. data/lib/brakeman/checks/check_regex_dos.rb +2 -1
  140. data/lib/brakeman/checks/check_render.rb +4 -2
  141. data/lib/brakeman/checks/check_render_dos.rb +2 -1
  142. data/lib/brakeman/checks/check_render_inline.rb +4 -2
  143. data/lib/brakeman/checks/check_response_splitting.rb +2 -1
  144. data/lib/brakeman/checks/check_reverse_tabnabbing.rb +2 -1
  145. data/lib/brakeman/checks/check_route_dos.rb +2 -1
  146. data/lib/brakeman/checks/check_safe_buffer_manipulation.rb +2 -1
  147. data/lib/brakeman/checks/check_sanitize_config_cve.rb +120 -0
  148. data/lib/brakeman/checks/check_sanitize_methods.rb +6 -3
  149. data/lib/brakeman/checks/check_secrets.rb +2 -1
  150. data/lib/brakeman/checks/check_select_tag.rb +2 -1
  151. data/lib/brakeman/checks/check_select_vulnerability.rb +2 -1
  152. data/lib/brakeman/checks/check_send.rb +2 -1
  153. data/lib/brakeman/checks/check_session_manipulation.rb +2 -1
  154. data/lib/brakeman/checks/check_session_settings.rb +6 -3
  155. data/lib/brakeman/checks/check_simple_format.rb +4 -2
  156. data/lib/brakeman/checks/check_single_quotes.rb +2 -1
  157. data/lib/brakeman/checks/check_skip_before_filter.rb +4 -2
  158. data/lib/brakeman/checks/check_sprockets_path_traversal.rb +2 -1
  159. data/lib/brakeman/checks/check_sql.rb +7 -4
  160. data/lib/brakeman/checks/check_sql_cves.rb +4 -2
  161. data/lib/brakeman/checks/check_ssl_verify.rb +2 -1
  162. data/lib/brakeman/checks/check_strip_tags.rb +6 -3
  163. data/lib/brakeman/checks/check_symbol_dos.rb +2 -1
  164. data/lib/brakeman/checks/check_symbol_dos_cve.rb +2 -1
  165. data/lib/brakeman/checks/check_template_injection.rb +2 -1
  166. data/lib/brakeman/checks/check_translate_bug.rb +2 -1
  167. data/lib/brakeman/checks/check_unsafe_reflection.rb +9 -3
  168. data/lib/brakeman/checks/check_unsafe_reflection_methods.rb +2 -1
  169. data/lib/brakeman/checks/check_unscoped_find.rb +2 -1
  170. data/lib/brakeman/checks/check_validation_regex.rb +2 -1
  171. data/lib/brakeman/checks/check_verb_confusion.rb +2 -1
  172. data/lib/brakeman/checks/check_weak_hash.rb +6 -3
  173. data/lib/brakeman/checks/check_without_protection.rb +2 -1
  174. data/lib/brakeman/checks/check_xml_dos.rb +2 -1
  175. data/lib/brakeman/checks/check_yaml_parsing.rb +4 -2
  176. data/lib/brakeman/checks/eol_check.rb +4 -2
  177. data/lib/brakeman/options.rb +1 -1
  178. data/lib/brakeman/processors/alias_processor.rb +41 -2
  179. data/lib/brakeman/processors/lib/find_all_calls.rb +1 -0
  180. data/lib/brakeman/report/ignore/interactive.rb +2 -2
  181. data/lib/brakeman/report/report_csv.rb +2 -0
  182. data/lib/brakeman/report/report_junit.rb +2 -2
  183. data/lib/brakeman/report/report_table.rb +5 -5
  184. data/lib/brakeman/report/report_text.rb +2 -0
  185. data/lib/brakeman/report/templates/controller_warnings.html.erb +2 -0
  186. data/lib/brakeman/report/templates/ignored_warnings.html.erb +2 -0
  187. data/lib/brakeman/report/templates/model_warnings.html.erb +2 -0
  188. data/lib/brakeman/report/templates/security_warnings.html.erb +2 -0
  189. data/lib/brakeman/report/templates/view_warnings.html.erb +2 -0
  190. data/lib/brakeman/version.rb +1 -1
  191. data/lib/brakeman/warning.rb +5 -2
  192. data/lib/brakeman/warning_codes.rb +1 -0
  193. metadata +95 -92
  194. data/bundle/ruby/2.7.0/gems/parallel-1.21.0/lib/parallel/version.rb +0 -4
  195. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby20_parser.rb +0 -7128
  196. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby21_parser.rb +0 -7182
  197. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby22_parser.rb +0 -7228
  198. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby23_parser.rb +0 -7237
  199. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby24_parser.rb +0 -7268
  200. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby25_parser.rb +0 -7268
  201. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby26_parser.rb +0 -7287
  202. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby27_parser.rb +0 -8517
  203. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.1/lib/ruby30_parser.rb +0 -8751
  204. data/bundle/ruby/2.7.0/gems/tilt-2.0.10/lib/tilt/rst-pandoc.rb +0 -18
  205. data/bundle/ruby/2.7.0/gems/tilt-2.0.10/lib/tilt/sass.rb +0 -52
@@ -0,0 +1,3536 @@
1
+ # -*- racc -*-
2
+
3
+ #if V == 30
4
+ class Ruby30Parser
5
+ #elif V == 31
6
+ class Ruby31Parser
7
+ #else
8
+ fail "version not specified or supported on code generation"
9
+ #endif
10
+
11
+ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
12
+ kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
13
+ kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
14
+ kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
15
+ kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
16
+ k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
17
+ tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
18
+ tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
19
+ tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
20
+ tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
21
+ tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
22
+ tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
23
+ tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
24
+ tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
25
+ tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
26
+ tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
27
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
28
+ tRATIONAL tIMAGINARY
29
+ tLABEL_END
30
+ tLONELY
31
+ tBDOT2 tBDOT3
32
+
33
+ preclow
34
+ nonassoc tLOWEST
35
+ nonassoc tLBRACE_ARG
36
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
37
+ left kOR kAND
38
+ right kNOT
39
+ nonassoc kDEFINED
40
+ right tEQL tOP_ASGN
41
+ left kRESCUE_MOD
42
+ right tEH tCOLON
43
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
44
+ left tOROP
45
+ left tANDOP
46
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
47
+ left tGT tGEQ tLT tLEQ
48
+ left tPIPE tCARET
49
+ left tAMPER2
50
+ left tLSHFT tRSHFT
51
+ left tPLUS tMINUS
52
+ left tSTAR2 tDIVIDE tPERCENT # TODO: tSTAR2 -> tMULT
53
+ right tUMINUS_NUM tUMINUS
54
+ right tPOW
55
+ right tBANG tTILDE tUPLUS
56
+ prechigh
57
+
58
+ rule
59
+
60
+ program: {
61
+ self.lexer.lex_state = EXPR_BEG
62
+ }
63
+ top_compstmt
64
+ {
65
+ result = new_compstmt val
66
+
67
+ lexer.cond.pop # local_pop
68
+ lexer.cmdarg.pop
69
+ }
70
+
71
+ top_compstmt: top_stmts opt_terms
72
+ {
73
+ stmt, _ = val
74
+ result = stmt
75
+ }
76
+
77
+ top_stmts: none
78
+ | top_stmt
79
+ | top_stmts terms top_stmt
80
+ {
81
+ result = self.block_append val[0], val[2]
82
+ }
83
+ | error top_stmt
84
+
85
+ top_stmt: stmt
86
+ | klBEGIN
87
+ {
88
+ if (self.in_def || self.in_single > 0) then
89
+ debug 1
90
+ yyerror "BEGIN in method"
91
+ end
92
+ self.env.extend
93
+ }
94
+ begin_block
95
+ {
96
+ (_, lineno), _, iter = val
97
+ iter.line lineno
98
+
99
+ (_, preexe,) = iter
100
+ preexe.line lineno
101
+
102
+ result = iter
103
+ }
104
+
105
+ begin_block: tLCURLY { result = lexer.lineno } top_compstmt tRCURLY
106
+ {
107
+ _, line, stmt, _ = val
108
+ result = new_iter s(:preexe).line(line), 0, stmt
109
+ }
110
+
111
+ bodystmt: compstmt opt_rescue k_else
112
+ {
113
+ res = _values[-2]
114
+ yyerror "else without rescue is useless" unless res
115
+ }
116
+ compstmt
117
+ opt_ensure
118
+ {
119
+ body, resc, _, _, els, ens = val
120
+
121
+ result = new_body [body, resc, els, ens]
122
+ }
123
+ | compstmt opt_rescue opt_ensure
124
+ {
125
+ body, resc, ens = val
126
+
127
+ result = new_body [body, resc, nil, ens]
128
+ }
129
+
130
+ compstmt: stmts opt_terms
131
+ {
132
+ result = new_compstmt val
133
+ }
134
+
135
+ stmts: none
136
+ | stmt_or_begin # TODO: newline_node ?
137
+ | stmts terms stmt_or_begin
138
+ {
139
+ result = self.block_append val[0], val[2]
140
+ }
141
+ | error stmt
142
+ {
143
+ result = val[1]
144
+ debug 2
145
+ }
146
+
147
+ stmt_or_begin: stmt
148
+ | klBEGIN
149
+ {
150
+ yyerror "BEGIN is permitted only at toplevel"
151
+ }
152
+ begin_block
153
+ {
154
+ result = val[2] # wtf?
155
+ }
156
+
157
+ stmt: kALIAS fitem
158
+ {
159
+ lexer.lex_state = EXPR_FNAME
160
+ }
161
+ fitem
162
+ {
163
+ (_, line), lhs, _, rhs = val
164
+ result = s(:alias, lhs, rhs).line(line).line line
165
+ }
166
+ | kALIAS tGVAR tGVAR
167
+ {
168
+ (_, line), (lhs, _), (rhs, _) = val
169
+ result = s(:valias, lhs.to_sym, rhs.to_sym).line line
170
+ }
171
+ | kALIAS tGVAR tBACK_REF
172
+ {
173
+ (_, line), (lhs, _), (rhs, _) = val
174
+ result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
175
+ }
176
+ | kALIAS tGVAR tNTH_REF
177
+ {
178
+ yyerror "can't make alias for the number variables"
179
+ }
180
+ | kUNDEF undef_list
181
+ {
182
+ result = val[1]
183
+ }
184
+ | stmt kIF_MOD expr_value
185
+ {
186
+ t, _, c = val
187
+ result = new_if c, t, nil
188
+ }
189
+ | stmt kUNLESS_MOD expr_value
190
+ {
191
+ f, _, c = val
192
+ result = new_if c, nil, f
193
+ }
194
+ | stmt kWHILE_MOD expr_value
195
+ {
196
+ e, _, c = val
197
+ result = new_while e, c, true
198
+ }
199
+ | stmt kUNTIL_MOD expr_value
200
+ {
201
+ e, _, c = val
202
+ result = new_until e, c, true
203
+ }
204
+ | stmt kRESCUE_MOD stmt
205
+ {
206
+ body, _, resbody = val
207
+
208
+ resbody = new_resbody s(:array).line(resbody.line), resbody
209
+ result = new_rescue body, resbody
210
+ }
211
+ | klEND tLCURLY compstmt tRCURLY
212
+ {
213
+ (_, line), _, stmt, _ = val
214
+
215
+ if (self.in_def || self.in_single > 0) then
216
+ debug 3
217
+ yyerror "END in method; use at_exit"
218
+ end
219
+
220
+ result = new_iter s(:postexe).line(line), 0, stmt
221
+ }
222
+ | command_asgn
223
+ | mlhs tEQL command_call
224
+ {
225
+ result = new_masgn val[0], val[2], :wrap
226
+ }
227
+ | lhs tEQL mrhs
228
+ {
229
+ lhs, _, rhs = val
230
+ result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
231
+ }
232
+ | mlhs tEQL mrhs_arg kRESCUE_MOD stmt
233
+ {
234
+ # unwraps s(:to_ary, rhs)
235
+ lhs, _, (_, rhs), _, resbody = val
236
+
237
+ resbody = new_resbody s(:array).line(resbody.line), resbody
238
+
239
+ result = new_masgn lhs, new_rescue(rhs, resbody), :wrap
240
+ }
241
+ | mlhs tEQL mrhs_arg
242
+ {
243
+ result = new_masgn val[0], val[2]
244
+ }
245
+ | expr
246
+
247
+ command_asgn: lhs tEQL command_rhs
248
+ {
249
+ result = new_assign val[0], val[2]
250
+ }
251
+ # | lhs tEQL command_asgn
252
+ # {
253
+ # result = new_assign val[0], val[2]
254
+ # }
255
+ | var_lhs tOP_ASGN command_rhs
256
+ {
257
+ result = new_op_asgn val
258
+ }
259
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_rhs
260
+ {
261
+ result = new_op_asgn1 val
262
+ }
263
+ | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
264
+ {
265
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
266
+
267
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
268
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
269
+ result.line prim.line
270
+ }
271
+ | primary_value call_op tCONSTANT tOP_ASGN command_rhs
272
+ {
273
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
274
+
275
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
276
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
277
+ result.line prim.line
278
+ }
279
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
280
+ {
281
+ lhs1, _, (lhs2, line), (id, _), rhs = val
282
+
283
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
284
+ }
285
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
286
+ {
287
+ lhs1, _, (lhs2, line), (id, _), rhs = val
288
+
289
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
290
+ }
291
+ #if V > 30
292
+ | defn_head f_opt_paren_args tEQL command
293
+ {
294
+ result = new_endless_defn val
295
+ }
296
+ | defn_head f_opt_paren_args tEQL command kRESCUE_MOD arg
297
+ {
298
+ result = new_endless_defn val
299
+ }
300
+ | defs_head f_opt_paren_args tEQL command
301
+ {
302
+ result = new_endless_defs val
303
+ }
304
+ | defs_head f_opt_paren_args tEQL command kRESCUE_MOD arg
305
+ {
306
+ result = new_endless_defs val
307
+ }
308
+ #endif
309
+ | backref tOP_ASGN command_rhs
310
+ {
311
+ self.backref_assign_error val[0]
312
+ }
313
+
314
+ command_rhs: command_call =tOP_ASGN
315
+ {
316
+ expr, = val
317
+ result = value_expr expr
318
+ }
319
+ | command_call kRESCUE_MOD stmt
320
+ {
321
+ expr, (_, line), resbody = val
322
+
323
+ expr = value_expr expr
324
+ ary = s(:array).line line
325
+ result = new_rescue(expr, new_resbody(ary, resbody))
326
+ }
327
+ | command_asgn
328
+
329
+ expr: command_call
330
+ | expr kAND expr
331
+ {
332
+ lhs, _, rhs = val
333
+ result = logical_op :and, lhs, rhs
334
+ }
335
+ | expr kOR expr
336
+ {
337
+ lhs, _, rhs = val
338
+ result = logical_op :or, lhs, rhs
339
+ }
340
+ | kNOT opt_nl expr
341
+ {
342
+ (_, line), _, expr = val
343
+ result = new_call(expr, :"!").line line
344
+ # REFACTOR: call_uni_op
345
+ }
346
+ | tBANG command_call
347
+ {
348
+ _, cmd = val
349
+ result = new_call(cmd, :"!").line cmd.line
350
+ # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
351
+ # REFACTOR: call_uni_op -- see parse26.y
352
+ }
353
+ | arg tASSOC
354
+ {
355
+ # value_expr($1);
356
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
357
+ self.lexer.command_start = false
358
+ result = self.in_kwarg
359
+ self.in_kwarg = true
360
+ self.env.extend
361
+ }
362
+ #if V == 30
363
+ p_expr
364
+ #else
365
+ p_top_expr_body
366
+ #endif
367
+ {
368
+ lhs, _, in_kwarg, rhs = val
369
+
370
+ self.env.unextend
371
+ self.in_kwarg = in_kwarg
372
+
373
+ rhs = new_in rhs, nil, nil, rhs.line
374
+ result = new_case lhs, rhs, rhs.line
375
+ }
376
+ | arg
377
+ kIN
378
+ {
379
+ # TODO? value_expr($1);
380
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
381
+ self.lexer.command_start = false
382
+ result = self.in_kwarg
383
+ self.in_kwarg = true
384
+ self.env.extend
385
+ }
386
+ #if V == 30
387
+ p_expr
388
+ #else
389
+ p_top_expr_body
390
+ #endif
391
+ {
392
+ self.env.unextend
393
+
394
+ expr, _, old_kwarg, pat = val
395
+
396
+ expr = value_expr expr
397
+
398
+ self.in_kwarg = old_kwarg
399
+ pat_in = new_in pat, nil, nil, expr.line
400
+ result = new_case expr, pat_in, expr.line
401
+ }
402
+ | arg =tLBRACE_ARG
403
+
404
+ def_name: fname
405
+ {
406
+ # TODO: numparam_name(p, fname);
407
+
408
+ (id, line), = val
409
+ old_in_def = self.in_def
410
+
411
+ self.in_def = true # group = local_push
412
+ self.env.extend
413
+ lexer.cmdarg.push false
414
+ lexer.cond.push false
415
+
416
+ result = [id.to_sym, line, old_in_def]
417
+ }
418
+ defn_head: k_def def_name
419
+ {
420
+ _, name = val
421
+ result = name
422
+ }
423
+ defs_head: k_def singleton dot_or_colon
424
+ {
425
+ lexer.lex_state = EXPR_FNAME
426
+ }
427
+ def_name
428
+ {
429
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
430
+ self.in_single += 1 # TODO: remove?
431
+
432
+ # self.in_def = true # local_push
433
+ # self.env.extend
434
+ # lexer.cmdarg.push false
435
+ # lexer.cond.push false
436
+
437
+ _, recv, _, _, name = val
438
+
439
+ result = [recv, name]
440
+ }
441
+
442
+ expr_value: expr
443
+ {
444
+ result = value_expr(val[0])
445
+ }
446
+
447
+ expr_value_do: {
448
+ lexer.cond.push true
449
+ }
450
+ expr_value do
451
+ {
452
+ lexer.cond.pop
453
+ }
454
+ {
455
+ _, expr, _, _ = val
456
+ result = expr
457
+ }
458
+
459
+ command_call: command
460
+ | block_command
461
+
462
+ block_command: block_call
463
+ | block_call call_op2 operation2 command_args
464
+ {
465
+ blk, _, (msg, _line), args = val
466
+ result = new_call(blk, msg.to_sym, args).line blk.line
467
+ }
468
+
469
+ cmd_brace_block: tLBRACE_ARG
470
+ {
471
+ # self.env.extend(:dynamic)
472
+ result = self.lexer.lineno
473
+ }
474
+ brace_body tRCURLY
475
+ {
476
+ _, line, body, _ = val
477
+
478
+ result = body
479
+ result.line line
480
+
481
+ # self.env.unextend
482
+ }
483
+
484
+ fcall: operation
485
+ {
486
+ (msg, line), = val
487
+ result = new_call(nil, msg.to_sym).line line
488
+ }
489
+
490
+ command: fcall command_args =tLOWEST
491
+ {
492
+ call, args = val
493
+ result = call.concat args.sexp_body
494
+ }
495
+ | fcall command_args cmd_brace_block
496
+ {
497
+ call, args, block = val
498
+
499
+ result = call.concat args.sexp_body
500
+
501
+ if block then
502
+ block_dup_check result, block
503
+
504
+ result, operation = block, result
505
+ result.insert 1, operation
506
+ end
507
+ }
508
+ | primary_value call_op operation2 command_args =tLOWEST
509
+ {
510
+ lhs, callop, (op, _), args = val
511
+
512
+ result = new_call lhs, op.to_sym, args, callop
513
+ result.line lhs.line
514
+ }
515
+ | primary_value call_op operation2 command_args cmd_brace_block
516
+ {
517
+ recv, _, (msg, _line), args, block = val
518
+ call = new_call recv, msg.to_sym, args, val[1]
519
+
520
+ block_dup_check call, block
521
+
522
+ block.insert 1, call
523
+ result = block
524
+ }
525
+ | primary_value tCOLON2 operation2 command_args =tLOWEST
526
+ {
527
+ lhs, _, (id, line), args = val
528
+
529
+ result = new_call lhs, id.to_sym, args
530
+ result.line line
531
+ }
532
+ | primary_value tCOLON2 operation2 command_args cmd_brace_block
533
+ {
534
+ recv, _, (msg, _line), args, block = val
535
+ call = new_call recv, msg.to_sym, args
536
+
537
+ block_dup_check call, block
538
+
539
+ block.insert 1, call
540
+ result = block
541
+ }
542
+ | kSUPER command_args
543
+ {
544
+ result = new_super val[1]
545
+ }
546
+ | kYIELD command_args
547
+ {
548
+ (_, line), args = val
549
+ result = new_yield args
550
+ result.line line # TODO: push to new_yield
551
+ }
552
+ | k_return call_args
553
+ {
554
+ line = val[0].last
555
+ result = s(:return, ret_args(val[1])).line(line)
556
+ }
557
+ | kBREAK call_args
558
+ {
559
+ (_, line), args = val
560
+ result = s(:break, ret_args(args)).line line
561
+ }
562
+ | kNEXT call_args
563
+ {
564
+ line = val[0].last
565
+ result = s(:next, ret_args(val[1])).line(line)
566
+ }
567
+
568
+ mlhs: mlhs_basic
569
+ | tLPAREN mlhs_inner rparen
570
+ {
571
+ result = val[1]
572
+ }
573
+
574
+ mlhs_inner: mlhs_basic
575
+ | tLPAREN mlhs_inner rparen
576
+ {
577
+ _, arg, _ = val
578
+ l = arg.line
579
+
580
+ result = s(:masgn, s(:array, arg).line(l)).line l
581
+ }
582
+
583
+ mlhs_basic: mlhs_head
584
+ {
585
+ head, = val
586
+ result = s(:masgn, head).line head.line
587
+ }
588
+ | mlhs_head mlhs_item
589
+ {
590
+ lhs, rhs = val
591
+ result = s(:masgn, lhs << rhs.compact).line lhs.line
592
+ }
593
+ | mlhs_head tSTAR mlhs_node
594
+ {
595
+ head, _, tail = val
596
+ head << s(:splat, tail).line(tail.line)
597
+ result = s(:masgn, head).line head.line
598
+ }
599
+ | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
600
+ {
601
+ ary1, _, splat, _, ary2 = val
602
+
603
+ result = list_append ary1, s(:splat, splat).line(splat.line)
604
+ result.concat ary2.sexp_body
605
+ result = s(:masgn, result).line result.line
606
+ }
607
+ | mlhs_head tSTAR
608
+ {
609
+ head, _ = val
610
+ l = head.line
611
+ result = s(:masgn, head << s(:splat).line(l)).line l
612
+ }
613
+ | mlhs_head tSTAR tCOMMA mlhs_post
614
+ {
615
+ head, _, _, post = val
616
+ ary = list_append head, s(:splat).line(head.line)
617
+ ary.concat post.sexp_body
618
+ result = s(:masgn, ary).line ary.line
619
+ }
620
+ | tSTAR mlhs_node
621
+ {
622
+ _, node = val
623
+ l = node.line
624
+ splat = s(:splat, node).line l
625
+ ary = s(:array, splat).line l
626
+ result = s(:masgn, ary).line l
627
+ }
628
+ | tSTAR mlhs_node tCOMMA mlhs_post
629
+ {
630
+ _, node, _, post = val
631
+
632
+ splat = s(:splat, node).line node.line
633
+ ary = s(:array, splat).line splat.line
634
+ ary.concat post.sexp_body
635
+ result = s(:masgn, ary).line ary.line
636
+ }
637
+ | tSTAR
638
+ {
639
+ l = lexer.lineno
640
+ result = s(:masgn, s(:array, s(:splat).line(l)).line(l)).line l
641
+ }
642
+ | tSTAR tCOMMA mlhs_post
643
+ {
644
+ _, _, post = val
645
+ l = post.line
646
+
647
+ splat = s(:splat).line l
648
+ ary = s(:array, splat, *post.sexp_body).line l
649
+ result = s(:masgn, ary).line l
650
+ }
651
+
652
+ mlhs_item: mlhs_node
653
+ | tLPAREN mlhs_inner rparen
654
+ {
655
+ result = val[1]
656
+ }
657
+
658
+ mlhs_head: mlhs_item tCOMMA
659
+ {
660
+ lhs, _ = val
661
+ result = s(:array, lhs).line lhs.line
662
+ }
663
+ | mlhs_head mlhs_item tCOMMA
664
+ {
665
+ result = val[0] << val[1].compact
666
+ }
667
+
668
+ mlhs_post: mlhs_item
669
+ {
670
+ item, = val
671
+ result = s(:array, item).line item.line
672
+ }
673
+ | mlhs_post tCOMMA mlhs_item
674
+ {
675
+ result = list_append val[0], val[2]
676
+ }
677
+
678
+ mlhs_node: user_variable
679
+ {
680
+ result = self.assignable val[0]
681
+ }
682
+ | keyword_variable
683
+ {
684
+ result = self.assignable val[0]
685
+ }
686
+ | primary_value tLBRACK2 opt_call_args rbracket
687
+ {
688
+ result = self.aryset val[0], val[2]
689
+ }
690
+ | primary_value call_op tIDENTIFIER
691
+ {
692
+ lhs, call_op, (id, _line) = val
693
+
694
+ result = new_attrasgn lhs, id, call_op
695
+ }
696
+ | primary_value tCOLON2 tIDENTIFIER
697
+ {
698
+ recv, _, (id, _line) = val
699
+ result = new_attrasgn recv, id
700
+ }
701
+ | primary_value call_op tCONSTANT
702
+ {
703
+ lhs, call_op, (id, _line) = val
704
+
705
+ result = new_attrasgn lhs, id, call_op
706
+ }
707
+ | primary_value tCOLON2 tCONSTANT
708
+ {
709
+ if (self.in_def || self.in_single > 0) then
710
+ debug 4
711
+ yyerror "dynamic constant assignment"
712
+ end
713
+
714
+ expr, _, (id, _line) = val
715
+ l = expr.line
716
+
717
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
718
+ }
719
+ | tCOLON3 tCONSTANT
720
+ {
721
+ if (self.in_def || self.in_single > 0) then
722
+ debug 5
723
+ yyerror "dynamic constant assignment"
724
+ end
725
+
726
+ _, (id, l) = val
727
+
728
+ result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
729
+ }
730
+ | backref
731
+ {
732
+ ref, = val
733
+
734
+ self.backref_assign_error ref
735
+ }
736
+
737
+ lhs: user_variable
738
+ {
739
+ var, = val
740
+
741
+ result = self.assignable var
742
+ }
743
+ | keyword_variable
744
+ {
745
+ var, = val
746
+
747
+ result = self.assignable var
748
+
749
+ debug 6
750
+ }
751
+ | primary_value tLBRACK2 opt_call_args rbracket
752
+ {
753
+ lhs, _, args, _ = val
754
+
755
+ result = self.aryset lhs, args
756
+ }
757
+ | primary_value call_op tIDENTIFIER # REFACTOR
758
+ {
759
+ lhs, op, (id, _line) = val
760
+
761
+ result = new_attrasgn lhs, id, op
762
+ }
763
+ | primary_value tCOLON2 tIDENTIFIER
764
+ {
765
+ lhs, _, (id, _line) = val
766
+
767
+ result = new_attrasgn lhs, id
768
+ }
769
+ | primary_value call_op tCONSTANT # REFACTOR?
770
+ {
771
+ lhs, call_op, (id, _line) = val
772
+
773
+ result = new_attrasgn lhs, id, call_op
774
+ }
775
+ | primary_value tCOLON2 tCONSTANT
776
+ {
777
+ expr, _, (id, _line) = val
778
+
779
+ if (self.in_def || self.in_single > 0) then
780
+ debug 7
781
+ yyerror "dynamic constant assignment"
782
+ end
783
+
784
+ l = expr.line
785
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l)).line l
786
+ }
787
+ | tCOLON3 tCONSTANT
788
+ {
789
+ _, (id, l) = val
790
+
791
+ if (self.in_def || self.in_single > 0) then
792
+ debug 8
793
+ yyerror "dynamic constant assignment"
794
+ end
795
+
796
+ result = s(:const, s(:colon3, id.to_sym).line(l)).line l
797
+ }
798
+ | backref
799
+ {
800
+ self.backref_assign_error val[0]
801
+ }
802
+
803
+ cname: tIDENTIFIER
804
+ {
805
+ yyerror "class/module name must be CONSTANT"
806
+ }
807
+ | tCONSTANT
808
+
809
+ cpath: tCOLON3 cname
810
+ {
811
+ result = wrap :colon3, val[1]
812
+ }
813
+ | cname
814
+ {
815
+ (id, line), = val
816
+ result = [id.to_sym, line] # TODO: sexp?
817
+ }
818
+ | primary_value tCOLON2 cname
819
+ {
820
+ pval, _, (name, _line) = val
821
+
822
+ result = s(:colon2, pval, name.to_sym)
823
+ result.line pval.line
824
+ }
825
+
826
+ fname: tIDENTIFIER | tCONSTANT | tFID
827
+ | op
828
+ {
829
+ lexer.lex_state = EXPR_END
830
+ }
831
+
832
+ | reswords
833
+
834
+ fitem: fname
835
+ {
836
+ result = wrap :lit, val[0]
837
+ }
838
+ | symbol
839
+
840
+ undef_list: fitem
841
+ {
842
+ result = new_undef val[0]
843
+ }
844
+ |
845
+ undef_list tCOMMA
846
+ {
847
+ lexer.lex_state = EXPR_FNAME
848
+ }
849
+ fitem
850
+ {
851
+ result = new_undef val[0], val[3]
852
+ }
853
+
854
+ op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
855
+ | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ
856
+ | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
857
+ | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
858
+ | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
859
+
860
+ reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
861
+ | kALIAS | kAND | kBEGIN | kBREAK | kCASE
862
+ | kCLASS | kDEF | kDEFINED | kDO | kELSE
863
+ | kELSIF | kEND | kENSURE | kFALSE | kFOR
864
+ | kIN | kMODULE | kNEXT | kNIL | kNOT
865
+ | kOR | kREDO | kRESCUE | kRETRY | kRETURN
866
+ | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF
867
+ | kWHEN | kYIELD | kIF | kUNLESS | kWHILE
868
+ | kUNTIL
869
+
870
+ arg: lhs tEQL arg_rhs
871
+ {
872
+ result = new_assign val[0], val[2]
873
+ }
874
+ | var_lhs tOP_ASGN arg_rhs
875
+ {
876
+ result = new_op_asgn val
877
+ }
878
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
879
+ {
880
+ result = new_op_asgn1 val
881
+ }
882
+ | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
883
+ {
884
+ result = new_op_asgn2 val
885
+ }
886
+ | primary_value call_op tCONSTANT tOP_ASGN arg_rhs
887
+ {
888
+ result = new_op_asgn2 val
889
+ }
890
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
891
+ {
892
+ lhs, _, (id, _line), (op, _), rhs = val
893
+
894
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
895
+ }
896
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
897
+ {
898
+ lhs1, _, (lhs2, _line), op, rhs = val
899
+
900
+ lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
901
+ result = new_const_op_asgn [lhs, op, rhs]
902
+ }
903
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
904
+ {
905
+ _, lhs, op, rhs = val
906
+
907
+ lhs = wrap :colon3, lhs
908
+ result = new_const_op_asgn [lhs, op, rhs]
909
+ }
910
+ | backref tOP_ASGN arg_rhs
911
+ {
912
+ # TODO: lhs = var_field val[0]
913
+ asgn = new_op_asgn val
914
+ result = self.backref_assign_error asgn
915
+ }
916
+ | arg tDOT2 arg
917
+ {
918
+ v1, v2 = val[0], val[2]
919
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
920
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
921
+ else
922
+ result = s(:dot2, v1, v2).line v1.line
923
+ end
924
+ }
925
+ | arg tDOT3 arg
926
+ {
927
+ v1, v2 = val[0], val[2]
928
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
929
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
930
+ else
931
+ result = s(:dot3, v1, v2).line v1.line
932
+ end
933
+ }
934
+ | arg tDOT2
935
+ {
936
+ v1, _ = val
937
+ v2 = nil
938
+
939
+ result = s(:dot2, v1, v2).line v1.line
940
+ }
941
+ | arg tDOT3
942
+ {
943
+ v1, _ = val
944
+ v2 = nil
945
+
946
+ result = s(:dot3, v1, v2).line v1.line
947
+ }
948
+
949
+ | tBDOT2 arg
950
+ {
951
+ _, v2, = val
952
+ v1 = nil
953
+
954
+ result = s(:dot2, v1, v2).line v2.line
955
+ }
956
+ | tBDOT3 arg
957
+ {
958
+ _, v2 = val
959
+ v1 = nil
960
+
961
+ result = s(:dot3, v1, v2).line v2.line
962
+ }
963
+
964
+ | arg tPLUS arg
965
+ {
966
+ result = new_call val[0], :+, argl(val[2])
967
+ }
968
+ | arg tMINUS arg
969
+ {
970
+ result = new_call val[0], :-, argl(val[2])
971
+ }
972
+ | arg tSTAR2 arg # TODO: rename
973
+ {
974
+ result = new_call val[0], :*, argl(val[2])
975
+ }
976
+ | arg tDIVIDE arg
977
+ {
978
+ result = new_call val[0], :"/", argl(val[2])
979
+ }
980
+ | arg tPERCENT arg
981
+ {
982
+ result = new_call val[0], :"%", argl(val[2])
983
+ }
984
+ | arg tPOW arg
985
+ {
986
+ result = new_call val[0], :**, argl(val[2])
987
+ }
988
+ | tUMINUS_NUM simple_numeric tPOW arg
989
+ {
990
+ _, num, _, arg = val
991
+ lit = wrap :lit, num
992
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
993
+
994
+ }
995
+ | tUPLUS arg
996
+ {
997
+ result = new_call val[1], :"+@"
998
+ }
999
+ | tUMINUS arg
1000
+ {
1001
+ result = new_call val[1], :"-@"
1002
+ }
1003
+ | arg tPIPE arg
1004
+ {
1005
+ result = new_call val[0], :"|", argl(val[2])
1006
+ }
1007
+ | arg tCARET arg
1008
+ {
1009
+ result = new_call val[0], :"^", argl(val[2])
1010
+ }
1011
+ | arg tAMPER2 arg
1012
+ {
1013
+ result = new_call val[0], :"&", argl(val[2])
1014
+ }
1015
+ | arg tCMP arg
1016
+ {
1017
+ result = new_call val[0], :"<=>", argl(val[2])
1018
+ }
1019
+ | rel_expr =tCMP
1020
+ | arg tEQ arg
1021
+ {
1022
+ result = new_call val[0], :"==", argl(val[2])
1023
+ }
1024
+ | arg tEQQ arg
1025
+ {
1026
+ result = new_call val[0], :"===", argl(val[2])
1027
+ }
1028
+ | arg tNEQ arg
1029
+ {
1030
+ result = new_call val[0], :"!=", argl(val[2])
1031
+ }
1032
+ | arg tMATCH arg
1033
+ {
1034
+ lhs, _, rhs = val
1035
+ result = new_match lhs, rhs
1036
+ }
1037
+ | arg tNMATCH arg
1038
+ {
1039
+ lhs, _, rhs = val
1040
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
1041
+ }
1042
+ | tBANG arg
1043
+ {
1044
+ _, arg = val
1045
+ result = new_call arg, :"!"
1046
+ result.line arg.line
1047
+ }
1048
+ | tTILDE arg
1049
+ {
1050
+ result = new_call value_expr(val[1]), :"~"
1051
+ }
1052
+ | arg tLSHFT arg
1053
+ {
1054
+ val[0] = value_expr val[0]
1055
+ val[2] = value_expr val[2]
1056
+ result = new_call val[0], :"\<\<", argl(val[2])
1057
+ }
1058
+ | arg tRSHFT arg
1059
+ {
1060
+ val[0] = value_expr val[0]
1061
+ val[2] = value_expr val[2]
1062
+ result = new_call val[0], :">>", argl(val[2])
1063
+ }
1064
+ | arg tANDOP arg
1065
+ {
1066
+ result = logical_op :and, val[0], val[2]
1067
+ }
1068
+ | arg tOROP arg
1069
+ {
1070
+ result = logical_op :or, val[0], val[2]
1071
+ }
1072
+ | kDEFINED opt_nl arg
1073
+ {
1074
+ (_, line), _, arg = val
1075
+ result = s(:defined, arg).line line
1076
+ }
1077
+ | arg tEH arg opt_nl tCOLON arg
1078
+ {
1079
+ c, _, t, _, _, f = val
1080
+ result = s(:if, c, t, f).line c.line
1081
+ }
1082
+ | defn_head f_opt_paren_args tEQL arg
1083
+ {
1084
+ result = new_endless_defn val
1085
+ }
1086
+ | defn_head f_opt_paren_args tEQL arg kRESCUE_MOD arg
1087
+ {
1088
+ result = new_endless_defn val
1089
+ }
1090
+ | defs_head f_opt_paren_args tEQL arg
1091
+ {
1092
+ result = new_endless_defs val
1093
+ }
1094
+ | defs_head f_opt_paren_args tEQL arg kRESCUE_MOD arg
1095
+ {
1096
+ result = new_endless_defs val
1097
+ }
1098
+ | primary
1099
+
1100
+ relop: tGT
1101
+ | tLT
1102
+ | tGEQ
1103
+ | tLEQ
1104
+
1105
+ rel_expr: arg relop arg =tGT
1106
+ {
1107
+ lhs, (op, _), rhs = val
1108
+ result = new_call lhs, op.to_sym, argl(rhs)
1109
+ }
1110
+ | rel_expr relop arg =tGT
1111
+ {
1112
+ lhs, (op, _), rhs = val
1113
+ warn "comparison '%s' after comparison", op
1114
+ result = new_call lhs, op.to_sym, argl(rhs)
1115
+ }
1116
+
1117
+ arg_value: arg
1118
+ {
1119
+ result = value_expr(val[0])
1120
+ }
1121
+
1122
+ aref_args: none
1123
+ | args trailer
1124
+ {
1125
+ result = args [val[0]]
1126
+ }
1127
+ | args tCOMMA assocs trailer
1128
+ {
1129
+ result = args [val[0], array_to_hash(val[2])]
1130
+ }
1131
+ | assocs trailer
1132
+ {
1133
+ result = args [array_to_hash(val[0])]
1134
+ }
1135
+
1136
+ arg_rhs: arg =tOP_ASGN
1137
+ | arg kRESCUE_MOD arg
1138
+ {
1139
+ body, (_, line), resbody = val
1140
+ body = value_expr body
1141
+ resbody = remove_begin resbody
1142
+
1143
+ ary = s(:array).line line
1144
+ result = new_rescue(body, new_resbody(ary, resbody))
1145
+ }
1146
+
1147
+ paren_args: tLPAREN2 opt_call_args rparen
1148
+ {
1149
+ _, args, _ = val
1150
+ result = args
1151
+ }
1152
+ | tLPAREN2 args tCOMMA args_forward rparen
1153
+ {
1154
+ yyerror "Unexpected ..." unless
1155
+ self.lexer.is_local_id(:"*") &&
1156
+ self.lexer.is_local_id(:"**") &&
1157
+ self.lexer.is_local_id(:"&")
1158
+
1159
+ result = call_args val
1160
+ }
1161
+ | tLPAREN2 args_forward rparen
1162
+ {
1163
+ yyerror "Unexpected ..." unless
1164
+ self.lexer.is_local_id(:"*") &&
1165
+ self.lexer.is_local_id(:"**") &&
1166
+ self.lexer.is_local_id(:"&")
1167
+
1168
+ result = call_args val
1169
+ }
1170
+
1171
+ opt_paren_args: none
1172
+ | paren_args
1173
+
1174
+ opt_call_args: none
1175
+ | call_args
1176
+ | args tCOMMA
1177
+ {
1178
+ result = args val
1179
+ }
1180
+ | args tCOMMA assocs tCOMMA
1181
+ {
1182
+ result = args [val[0], array_to_hash(val[2])]
1183
+ }
1184
+ | assocs tCOMMA
1185
+ {
1186
+ result = args [array_to_hash(val[0])]
1187
+ }
1188
+
1189
+ call_args: command
1190
+ {
1191
+ warning "parenthesize argument(s) for future version"
1192
+ result = call_args val
1193
+ }
1194
+ | args opt_block_arg
1195
+ {
1196
+ result = call_args val
1197
+ }
1198
+ | assocs opt_block_arg
1199
+ {
1200
+ result = call_args [array_to_hash(val[0]), val[1]]
1201
+ }
1202
+ | args tCOMMA assocs opt_block_arg
1203
+ {
1204
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
1205
+ }
1206
+ | block_arg
1207
+ {
1208
+ result = call_args val
1209
+ }
1210
+
1211
+ command_args: {
1212
+ # parse26.y line 2200
1213
+
1214
+ # If call_args starts with a open paren '(' or
1215
+ # '[', look-ahead reading of the letters calls
1216
+ # CMDARG_PUSH(0), but the push must be done
1217
+ # after CMDARG_PUSH(1). So this code makes them
1218
+ # consistent by first cancelling the premature
1219
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1220
+ # finally redoing CMDARG_PUSH(0).
1221
+
1222
+ result = yychar = self.last_token_type.first
1223
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1224
+ lexer.cmdarg.pop if lookahead
1225
+ lexer.cmdarg.push true
1226
+ lexer.cmdarg.push false if lookahead
1227
+ }
1228
+ call_args
1229
+ {
1230
+ yychar, args = val
1231
+
1232
+ # call_args can be followed by tLBRACE_ARG (that
1233
+ # does CMDARG_PUSH(0) in the lexer) but the push
1234
+ # must be done after CMDARG_POP() in the parser.
1235
+ # So this code does CMDARG_POP() to pop 0 pushed
1236
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1237
+ # by command_args, and CMDARG_PUSH(0) to restore
1238
+ # back the flag set by tLBRACE_ARG.
1239
+
1240
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1241
+ lexer.cmdarg.pop if lookahead
1242
+ lexer.cmdarg.pop
1243
+ lexer.cmdarg.push false if lookahead
1244
+ result = args
1245
+ }
1246
+
1247
+ block_arg: tAMPER arg_value
1248
+ {
1249
+ _, arg = val
1250
+ result = s(:block_pass, arg).line arg.line
1251
+ }
1252
+ #if V > 30
1253
+ | tAMPER
1254
+ {
1255
+ (_, line), = val
1256
+ result = s(:block_pass).line line
1257
+ }
1258
+ #endif
1259
+
1260
+ opt_block_arg: tCOMMA block_arg
1261
+ {
1262
+ result = val[1]
1263
+ }
1264
+ | none
1265
+
1266
+ args: arg_value
1267
+ {
1268
+ arg, = val
1269
+ lineno = arg.line || lexer.lineno # HACK
1270
+
1271
+ result = s(:array, arg).line lineno
1272
+ }
1273
+ | tSTAR arg_value
1274
+ {
1275
+ _, arg = val
1276
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1277
+ }
1278
+ | args tCOMMA arg_value
1279
+ {
1280
+ args, _, id = val
1281
+ result = self.list_append args, id
1282
+ }
1283
+ | args tCOMMA tSTAR arg_value
1284
+ {
1285
+ # TODO: the line number from tSTAR has been dropped
1286
+ args, _, _, id = val
1287
+ line = lexer.lineno
1288
+ result = self.list_append args, s(:splat, id).line(line)
1289
+ }
1290
+
1291
+ mrhs_arg: mrhs
1292
+ {
1293
+ result = new_masgn_arg val[0]
1294
+ }
1295
+ | arg_value
1296
+ {
1297
+ result = new_masgn_arg val[0], :wrap
1298
+ }
1299
+
1300
+ mrhs: args tCOMMA arg_value
1301
+ {
1302
+ result = val[0] << val[2]
1303
+ }
1304
+ | args tCOMMA tSTAR arg_value
1305
+ {
1306
+ # TODO: make all tXXXX terminals include lexer.lineno
1307
+ arg, _, _, splat = val
1308
+ result = self.arg_concat arg, splat
1309
+ }
1310
+ | tSTAR arg_value
1311
+ {
1312
+ _, arg = val
1313
+ result = s(:splat, arg).line arg.line
1314
+ }
1315
+
1316
+ primary: literal
1317
+ | strings
1318
+ | xstring
1319
+ | regexp
1320
+ | words
1321
+ | qwords
1322
+ | symbols
1323
+ | qsymbols
1324
+ | var_ref
1325
+ | backref
1326
+ | tFID
1327
+ {
1328
+ (msg, line), = val
1329
+ result = new_call nil, msg.to_sym
1330
+ result.line line
1331
+ }
1332
+ | k_begin
1333
+ {
1334
+ lexer.cmdarg.push false
1335
+ result = self.lexer.lineno
1336
+ }
1337
+ bodystmt k_end
1338
+ {
1339
+ lexer.cmdarg.pop
1340
+ result = new_begin val
1341
+ }
1342
+ | tLPAREN_ARG
1343
+ {
1344
+ lexer.lex_state = EXPR_ENDARG
1345
+ result = lexer.lineno
1346
+ }
1347
+ rparen
1348
+ {
1349
+ _, line, _ = val
1350
+ result = s(:begin).line line
1351
+ }
1352
+ | tLPAREN_ARG
1353
+ stmt
1354
+ {
1355
+ lexer.lex_state = EXPR_ENDARG
1356
+ }
1357
+ rparen
1358
+ {
1359
+ _, stmt, _, _, = val
1360
+ # warning "(...) interpreted as grouped expression"
1361
+ result = stmt
1362
+ }
1363
+ | tLPAREN compstmt tRPAREN
1364
+ {
1365
+ _, stmt, _ = val
1366
+ result = stmt
1367
+ result ||= s(:nil).line lexer.lineno
1368
+ result.paren = true
1369
+ }
1370
+ | primary_value tCOLON2 tCONSTANT
1371
+ {
1372
+ expr, _, (id, _line) = val
1373
+
1374
+ result = s(:colon2, expr, id.to_sym).line expr.line
1375
+ }
1376
+ | tCOLON3 tCONSTANT
1377
+ {
1378
+ result = wrap :colon3, val[1]
1379
+ }
1380
+ | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1381
+ {
1382
+ _, line, args, _ = val
1383
+ result = args || s(:array)
1384
+ result.sexp_type = :array # aref_args is :args
1385
+ result.line line
1386
+ }
1387
+ | tLBRACE
1388
+ {
1389
+ result = self.lexer.lineno
1390
+ }
1391
+ assoc_list tRCURLY
1392
+ {
1393
+ result = new_hash val
1394
+ }
1395
+ | k_return
1396
+ {
1397
+ (_, line), = val
1398
+ result = s(:return).line line
1399
+ }
1400
+ | kYIELD tLPAREN2 call_args rparen
1401
+ {
1402
+ (_, line), _, args, _ = val
1403
+
1404
+ result = new_yield(args).line line
1405
+ }
1406
+ | kYIELD tLPAREN2 rparen
1407
+ {
1408
+ (_, line), _, _ = val
1409
+
1410
+ result = new_yield.line line
1411
+ }
1412
+ | kYIELD
1413
+ {
1414
+ (_, line), = val
1415
+
1416
+ result = new_yield.line line
1417
+ }
1418
+ | kDEFINED opt_nl tLPAREN2 expr rparen
1419
+ {
1420
+ (_, line), _, _, arg, _ = val
1421
+
1422
+ result = s(:defined, arg).line line
1423
+ }
1424
+ | kNOT tLPAREN2 expr rparen
1425
+ {
1426
+ _, _, lhs, _ = val
1427
+ result = new_call lhs, :"!"
1428
+ }
1429
+ | kNOT tLPAREN2 rparen
1430
+ {
1431
+ debug 9
1432
+ }
1433
+ | fcall brace_block
1434
+ {
1435
+ call, iter = val
1436
+
1437
+ iter.insert 1, call
1438
+ result = iter
1439
+ # FIX: probably not: call.line = iter.line
1440
+ }
1441
+ | method_call
1442
+ | method_call brace_block
1443
+ {
1444
+ call, iter = val[0], val[1]
1445
+ block_dup_check call, iter
1446
+ iter.insert 1, call # FIX
1447
+ result = iter
1448
+ }
1449
+ | lambda
1450
+ {
1451
+ expr, = val
1452
+ result = expr
1453
+ }
1454
+ | k_if expr_value then compstmt if_tail k_end
1455
+ {
1456
+ _, c, _, t, f, _ = val
1457
+ result = new_if c, t, f
1458
+ }
1459
+ | k_unless expr_value then compstmt opt_else k_end
1460
+ {
1461
+ _, c, _, t, f, _ = val
1462
+ result = new_if c, f, t
1463
+ }
1464
+ | k_while expr_value_do compstmt k_end
1465
+ {
1466
+ _, cond, body, _ = val
1467
+ result = new_while body, cond, true
1468
+ }
1469
+ | k_until expr_value_do compstmt k_end
1470
+ {
1471
+ _, cond, body, _ = val
1472
+ result = new_until body, cond, true
1473
+ }
1474
+ | k_case expr_value opt_terms case_body k_end
1475
+ {
1476
+ (_, line), expr, _, body, _ = val
1477
+ result = new_case expr, body, line
1478
+ }
1479
+ | k_case opt_terms case_body k_end
1480
+ {
1481
+ (_, line), _, body, _ = val
1482
+ result = new_case nil, body, line
1483
+ }
1484
+ | k_case expr_value opt_terms p_case_body k_end
1485
+ {
1486
+ (_, line), expr, _, body, _ = val
1487
+
1488
+ result = new_case expr, body, line
1489
+ }
1490
+ | k_for for_var kIN expr_value_do compstmt k_end
1491
+ {
1492
+ _, var, _, iter, body, _ = val
1493
+ result = new_for iter, var, body
1494
+ }
1495
+ | k_class
1496
+ {
1497
+ result = self.lexer.lineno
1498
+ }
1499
+ cpath superclass
1500
+ {
1501
+ if (self.in_def || self.in_single > 0) then
1502
+ yyerror "class definition in method body"
1503
+ end
1504
+ self.env.extend
1505
+ }
1506
+ bodystmt k_end
1507
+ {
1508
+ result = new_class val
1509
+ self.env.unextend
1510
+ self.lexer.ignore_body_comments
1511
+ }
1512
+ | k_class tLSHFT
1513
+ {
1514
+ result = self.lexer.lineno
1515
+ }
1516
+ expr
1517
+ {
1518
+ result = self.in_def
1519
+ self.in_def = false
1520
+ }
1521
+ term
1522
+ {
1523
+ result = self.in_single
1524
+ self.in_single = 0
1525
+ self.env.extend
1526
+ }
1527
+ bodystmt k_end
1528
+ {
1529
+ result = new_sclass val
1530
+ self.env.unextend
1531
+ self.lexer.ignore_body_comments
1532
+ }
1533
+ | k_module
1534
+ {
1535
+ result = self.lexer.lineno
1536
+ }
1537
+ cpath
1538
+ {
1539
+ yyerror "module definition in method body" if
1540
+ self.in_def or self.in_single > 0
1541
+
1542
+ self.env.extend
1543
+ }
1544
+ bodystmt k_end
1545
+ {
1546
+ result = new_module val
1547
+ self.env.unextend
1548
+ self.lexer.ignore_body_comments
1549
+ }
1550
+ | defn_head f_arglist bodystmt k_end
1551
+ {
1552
+ # [ [:f, 1, false], s(:args)...]
1553
+ # =>
1554
+ # [[:k_def, 666], [:f, 1], false, s(:args)...]
1555
+ val.insert 1, val.first.pop
1556
+ val.insert 0, [:k_def, 666]
1557
+
1558
+ result, in_def = new_defn val
1559
+
1560
+ lexer.cond.pop # group = local_pop
1561
+ lexer.cmdarg.pop
1562
+ self.env.unextend
1563
+ self.in_def = in_def
1564
+
1565
+ self.lexer.ignore_body_comments
1566
+ }
1567
+ | defs_head f_arglist bodystmt k_end
1568
+ {
1569
+ # [ [recv, [:name, 1, false]], s(:args...]
1570
+ # =>
1571
+ # [ recv, [:name, 1, false], s(:args...]
1572
+ # =>
1573
+ # [ recv, [:name, 1], false, s(:args...]
1574
+ # =>
1575
+ # [ :k_def, recv, [:name, 1], false, s(:args...]
1576
+
1577
+ val.prepend(*val.shift)
1578
+ val.insert 2, val[1].pop
1579
+ val.insert 0, [:k_def, 666]
1580
+
1581
+ result, in_def = new_defs val
1582
+
1583
+ lexer.cond.pop # group = local_pop
1584
+ lexer.cmdarg.pop
1585
+ self.env.unextend
1586
+ self.in_def = in_def
1587
+
1588
+ self.in_single -= 1
1589
+
1590
+ # TODO: restore cur_arg ? what's cur_arg?
1591
+
1592
+ self.lexer.ignore_body_comments
1593
+ }
1594
+ | kBREAK
1595
+ {
1596
+ (_, line), = val
1597
+ result = s(:break).line line
1598
+ }
1599
+ | kNEXT
1600
+ {
1601
+ (_, line), = val
1602
+ result = s(:next).line line
1603
+ }
1604
+ | kREDO
1605
+ {
1606
+ (_, line), = val
1607
+ result = s(:redo).line line
1608
+ }
1609
+ | kRETRY
1610
+ {
1611
+ (_, line), = val
1612
+ result = s(:retry).line line
1613
+ }
1614
+
1615
+ primary_value: primary
1616
+ {
1617
+ result = value_expr(val[0])
1618
+ }
1619
+
1620
+ # These are really stupid
1621
+ k_begin: kBEGIN
1622
+ k_if: kIF
1623
+ k_unless: kUNLESS
1624
+ k_while: kWHILE
1625
+ k_until: kUNTIL
1626
+ k_case: kCASE
1627
+ k_for: kFOR
1628
+ k_class: kCLASS
1629
+ {
1630
+ self.comments.push self.lexer.comments
1631
+ }
1632
+ k_module: kMODULE
1633
+ {
1634
+ self.comments.push self.lexer.comments
1635
+ }
1636
+ k_def: kDEF
1637
+ {
1638
+ self.comments.push self.lexer.comments
1639
+ }
1640
+ k_do: kDO
1641
+ k_do_block: kDO_BLOCK
1642
+ k_rescue: kRESCUE
1643
+ k_ensure: kENSURE
1644
+ k_when: kWHEN
1645
+ k_else: kELSE
1646
+ k_elsif: kELSIF
1647
+ k_end: kEND
1648
+ k_return: kRETURN
1649
+
1650
+ then: term
1651
+ | kTHEN
1652
+ | term kTHEN
1653
+
1654
+ do: term
1655
+ | kDO_COND
1656
+
1657
+ if_tail: opt_else
1658
+ | k_elsif expr_value then compstmt if_tail
1659
+ {
1660
+ (_, line), c, _, t, rest = val
1661
+
1662
+ result = s(:if, c, t, rest).line line
1663
+ }
1664
+
1665
+ opt_else: none
1666
+ | kELSE compstmt
1667
+ {
1668
+ result = val[1]
1669
+ }
1670
+
1671
+ for_var: lhs
1672
+ | mlhs
1673
+ {
1674
+ val[0].delete_at 1 if val[0][1].nil? # HACK
1675
+ }
1676
+
1677
+ f_marg: f_norm_arg
1678
+ | tLPAREN f_margs rparen
1679
+ {
1680
+ result = val[1]
1681
+ }
1682
+
1683
+ f_marg_list: f_marg
1684
+ {
1685
+ sym, = val
1686
+
1687
+ result = s(:array, sym).line lexer.lineno
1688
+ }
1689
+ | f_marg_list tCOMMA f_marg
1690
+ {
1691
+ result = list_append val[0], val[2]
1692
+ }
1693
+
1694
+ f_margs: f_marg_list
1695
+ {
1696
+ args, = val
1697
+
1698
+ result = block_var args
1699
+ }
1700
+ | f_marg_list tCOMMA f_rest_marg
1701
+ {
1702
+ args, _, rest = val
1703
+
1704
+ result = block_var args, rest
1705
+ }
1706
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1707
+ {
1708
+ lhs, _, splat, _, rhs = val
1709
+
1710
+ result = block_var lhs, splat, rhs
1711
+ }
1712
+ | f_rest_marg
1713
+ {
1714
+ rest, = val
1715
+
1716
+ result = block_var rest
1717
+ }
1718
+ | f_rest_marg tCOMMA f_marg_list
1719
+ {
1720
+ splat, _, rest = val
1721
+
1722
+ result = block_var splat, rest
1723
+ }
1724
+
1725
+ f_rest_marg: tSTAR f_norm_arg
1726
+ {
1727
+ _, (id, line) = val
1728
+
1729
+ result = args ["*#{id}".to_sym]
1730
+ result.line line
1731
+ }
1732
+ | tSTAR
1733
+ {
1734
+ result = args [:*]
1735
+ result.line lexer.lineno # FIX: tSTAR -> line
1736
+ }
1737
+
1738
+ f_any_kwrest: f_kwrest
1739
+ | f_no_kwarg
1740
+
1741
+ #if V > 30
1742
+ f_eq: tEQL # TODO: self.in_argdef = false
1743
+ #endif
1744
+
1745
+ block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
1746
+ {
1747
+ result = call_args val
1748
+ }
1749
+ | f_block_kwarg opt_f_block_arg
1750
+ {
1751
+ result = call_args val
1752
+ }
1753
+ | f_any_kwrest opt_f_block_arg
1754
+ {
1755
+ result = call_args val
1756
+ }
1757
+ | f_block_arg
1758
+ {
1759
+ (id, line), = val
1760
+ result = call_args [id]
1761
+ result.line line
1762
+ }
1763
+
1764
+ opt_block_args_tail: tCOMMA block_args_tail
1765
+ {
1766
+ result = args val
1767
+ }
1768
+ | none
1769
+
1770
+ excessed_comma: tCOMMA
1771
+ {
1772
+ result = s(:WTF_COMMA!)
1773
+ }
1774
+
1775
+ block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1776
+ {
1777
+ result = args val
1778
+ }
1779
+ | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1780
+ {
1781
+ result = args val
1782
+ }
1783
+ | f_arg tCOMMA f_block_optarg opt_block_args_tail
1784
+ {
1785
+ result = args val
1786
+ }
1787
+ | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail
1788
+ {
1789
+ result = args val
1790
+ }
1791
+ | f_arg tCOMMA f_rest_arg opt_block_args_tail
1792
+ {
1793
+ result = args val
1794
+ }
1795
+ | f_arg excessed_comma
1796
+ {
1797
+ arg, _ = val
1798
+ result = arg << nil
1799
+ }
1800
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1801
+ {
1802
+ result = args val
1803
+ }
1804
+ | f_arg opt_block_args_tail
1805
+ {
1806
+ result = args val
1807
+ }
1808
+ | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1809
+ {
1810
+ result = args val
1811
+ }
1812
+ | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1813
+ {
1814
+ result = args val
1815
+ }
1816
+ | f_block_optarg opt_block_args_tail
1817
+ {
1818
+ result = args val
1819
+ }
1820
+ | f_block_optarg tCOMMA f_arg opt_block_args_tail
1821
+ {
1822
+ result = args val
1823
+ }
1824
+ | f_rest_arg opt_block_args_tail
1825
+ {
1826
+ result = args val
1827
+ }
1828
+ | f_rest_arg tCOMMA f_arg opt_block_args_tail
1829
+ {
1830
+ result = args val
1831
+ }
1832
+ | block_args_tail
1833
+ {
1834
+ result = args val
1835
+ }
1836
+
1837
+ opt_block_param: none { result = 0 }
1838
+ | block_param_def
1839
+ {
1840
+ self.lexer.command_start = true
1841
+ }
1842
+
1843
+ block_param_def: tPIPE opt_bv_decl tPIPE
1844
+ {
1845
+ # TODO: current_arg = 0
1846
+ result = args val
1847
+ }
1848
+ | tOROP
1849
+ {
1850
+ result = s(:args).line lexer.lineno
1851
+ }
1852
+ | tPIPE block_param opt_bv_decl tPIPE
1853
+ {
1854
+ # TODO: current_arg = 0
1855
+ result = args val
1856
+ }
1857
+
1858
+ opt_bv_decl: opt_nl
1859
+ | opt_nl tSEMI bv_decls opt_nl
1860
+ {
1861
+ result = args val
1862
+ }
1863
+
1864
+ bv_decls: bvar
1865
+ {
1866
+ result = args val
1867
+ }
1868
+ | bv_decls tCOMMA bvar
1869
+ {
1870
+ result = args val
1871
+ }
1872
+
1873
+ bvar: tIDENTIFIER
1874
+ {
1875
+ result = wrap :shadow, val[0]
1876
+ }
1877
+ | f_bad_arg
1878
+
1879
+ lambda: tLAMBDA
1880
+ {
1881
+ self.env.extend :dynamic
1882
+ result = [lexer.lineno, lexer.lpar_beg]
1883
+ lexer.paren_nest += 1
1884
+ lexer.lpar_beg = lexer.paren_nest
1885
+ }
1886
+ f_larglist
1887
+ {
1888
+ lexer.cmdarg.push false
1889
+ }
1890
+ lambda_body
1891
+ {
1892
+ _, (line, lpar), args, _cmdarg, body = val
1893
+ lexer.lpar_beg = lpar
1894
+
1895
+ lexer.cmdarg.pop
1896
+
1897
+ call = s(:lambda).line line
1898
+ result = new_iter call, args, body
1899
+ result.line line
1900
+ self.env.unextend # TODO: dynapush & dynapop
1901
+ }
1902
+
1903
+ f_larglist: tLPAREN2 f_args opt_bv_decl rparen
1904
+ {
1905
+ result = args val
1906
+ }
1907
+ | f_args
1908
+ {
1909
+ result = val[0]
1910
+ result = 0 if result == s(:args)
1911
+ }
1912
+
1913
+ lambda_body: tLAMBEG compstmt tRCURLY
1914
+ {
1915
+ result = val[1]
1916
+ }
1917
+ | kDO_LAMBDA bodystmt kEND
1918
+ {
1919
+ result = val[1]
1920
+ }
1921
+
1922
+ do_block: k_do_block do_body kEND
1923
+ {
1924
+ (_, line), iter, _ = val
1925
+ result = iter.line line
1926
+ }
1927
+
1928
+ block_call: command do_block
1929
+ {
1930
+ # TODO:
1931
+ ## if (nd_type($1) == NODE_YIELD) {
1932
+ ## compile_error(PARSER_ARG "block given to yield");
1933
+
1934
+ cmd, blk = val
1935
+
1936
+ syntax_error "Both block arg and actual block given." if
1937
+ cmd.block_pass?
1938
+
1939
+ if inverted? val then
1940
+ val = invert_block_call val
1941
+ cmd, blk = val
1942
+ end
1943
+
1944
+ result = blk
1945
+ result.insert 1, cmd
1946
+ }
1947
+ | block_call call_op2 operation2 opt_paren_args
1948
+ {
1949
+ lhs, _, (id, _line), args = val
1950
+
1951
+ result = new_call lhs, id.to_sym, args
1952
+ }
1953
+ | block_call call_op2 operation2 opt_paren_args brace_block
1954
+ {
1955
+ iter1, _, (name, _line), args, iter2 = val
1956
+
1957
+ call = new_call iter1, name.to_sym, args
1958
+ iter2.insert 1, call
1959
+
1960
+ result = iter2
1961
+ }
1962
+ | block_call call_op2 operation2 command_args do_block
1963
+ {
1964
+ iter1, _, (name, _line), args, iter2 = val
1965
+
1966
+ call = new_call iter1, name.to_sym, args
1967
+ iter2.insert 1, call
1968
+
1969
+ result = iter2
1970
+ }
1971
+
1972
+ method_call: fcall paren_args
1973
+ {
1974
+ call, args = val
1975
+
1976
+ result = call.concat args.sexp_body if args
1977
+ }
1978
+ | primary_value call_op operation2 opt_paren_args
1979
+ {
1980
+ recv, call_op, (op, _line), args = val
1981
+
1982
+ result = new_call recv, op.to_sym, args, call_op
1983
+ }
1984
+ | primary_value tCOLON2 operation2 paren_args
1985
+ {
1986
+ recv, _, (op, _line), args = val
1987
+
1988
+ result = new_call recv, op.to_sym, args
1989
+ }
1990
+ | primary_value tCOLON2 operation3
1991
+ {
1992
+ lhs, _, (id, _line) = val
1993
+
1994
+ result = new_call lhs, id.to_sym
1995
+ }
1996
+ | primary_value call_op paren_args
1997
+ {
1998
+ result = new_call val[0], :call, val[2], val[1]
1999
+ }
2000
+ | primary_value tCOLON2 paren_args
2001
+ {
2002
+ result = new_call val[0], :call, val[2]
2003
+ }
2004
+ | kSUPER paren_args
2005
+ {
2006
+ result = new_super val[1]
2007
+ }
2008
+ | kSUPER
2009
+ {
2010
+ result = s(:zsuper).line lexer.lineno
2011
+ }
2012
+ | primary_value tLBRACK2 opt_call_args rbracket
2013
+ {
2014
+ result = new_aref val
2015
+ }
2016
+
2017
+ brace_block: tLCURLY
2018
+ {
2019
+ self.env.extend :dynamic
2020
+ result = self.lexer.lineno
2021
+ }
2022
+ brace_body tRCURLY
2023
+ {
2024
+ _, line, body, _ = val
2025
+
2026
+ result = body
2027
+ result.line line
2028
+
2029
+ self.env.unextend
2030
+ }
2031
+ | k_do
2032
+ {
2033
+ self.env.extend :dynamic
2034
+ result = self.lexer.lineno
2035
+ }
2036
+ do_body kEND
2037
+ {
2038
+ _, line, body, _ = val
2039
+
2040
+ result = body
2041
+ result.line line
2042
+
2043
+ self.env.unextend
2044
+ }
2045
+
2046
+ brace_body: { self.env.extend :dynamic; result = self.lexer.lineno }
2047
+ { result = lexer.cmdarg.store(false) }
2048
+ opt_block_param compstmt
2049
+ {
2050
+ line, cmdarg, param, cmpstmt = val
2051
+
2052
+ result = new_brace_body param, cmpstmt, line
2053
+ self.env.unextend
2054
+ lexer.cmdarg.restore cmdarg
2055
+ lexer.cmdarg.pop # because of: cmdarg_stack >> 1 ?
2056
+ }
2057
+
2058
+ do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
2059
+ { lexer.cmdarg.push false }
2060
+ opt_block_param
2061
+ bodystmt
2062
+ {
2063
+ line, _cmdarg, param, cmpstmt = val
2064
+
2065
+ result = new_do_body param, cmpstmt, line
2066
+ lexer.cmdarg.pop
2067
+ self.env.unextend
2068
+ }
2069
+
2070
+ case_args: arg_value
2071
+ {
2072
+ arg, = val
2073
+
2074
+ result = s(:array, arg).line arg.line
2075
+ }
2076
+ | tSTAR arg_value
2077
+ {
2078
+ _, arg = val
2079
+
2080
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
2081
+ }
2082
+ | case_args tCOMMA arg_value
2083
+ {
2084
+ args, _, id = val
2085
+
2086
+ result = self.list_append args, id
2087
+ }
2088
+ | case_args tCOMMA tSTAR arg_value
2089
+ {
2090
+ args, _, _, id = val
2091
+
2092
+ result = self.list_append args, s(:splat, id).line(id.line)
2093
+ }
2094
+
2095
+ case_body: k_when
2096
+ {
2097
+ result = self.lexer.lineno
2098
+ }
2099
+ case_args then compstmt cases
2100
+ {
2101
+ result = new_when(val[2], val[4])
2102
+ result.line val[1]
2103
+ result << val[5] if val[5]
2104
+ }
2105
+
2106
+ cases: opt_else | case_body
2107
+ ######################################################################
2108
+
2109
+ p_case_body: kIN
2110
+ {
2111
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
2112
+ self.lexer.command_start = false
2113
+ result = self.in_kwarg
2114
+ self.in_kwarg = true
2115
+ push_pvtbl
2116
+ push_pktbl
2117
+ }
2118
+ p_top_expr then
2119
+ {
2120
+ pop_pktbl
2121
+ pop_pvtbl
2122
+ old_kwargs = _values[-3]
2123
+ self.in_kwarg = old_kwargs
2124
+ }
2125
+ compstmt
2126
+ p_cases
2127
+ {
2128
+ (_, line), _, pat, _, _, body, cases = val
2129
+
2130
+ result = new_in pat, body, cases, line
2131
+ }
2132
+
2133
+ p_cases: opt_else
2134
+ | p_case_body
2135
+
2136
+ p_top_expr: p_top_expr_body
2137
+ | p_top_expr_body kIF_MOD expr_value
2138
+ {
2139
+ body, _, cond = val
2140
+ body = remove_begin body
2141
+
2142
+ result = s(:if, cond, body, nil).line body.line
2143
+ }
2144
+ | p_top_expr_body kUNLESS_MOD expr_value
2145
+ {
2146
+ body, _, cond = val
2147
+ body = remove_begin body
2148
+
2149
+ result = s(:if, cond, nil, body).line body.line
2150
+ }
2151
+
2152
+ p_top_expr_body: p_expr
2153
+ | p_expr tCOMMA
2154
+ {
2155
+ expr, _ = val
2156
+
2157
+ tail = new_array_pattern_tail nil, true, nil, nil
2158
+ result = new_array_pattern nil, expr, tail, expr.line
2159
+ }
2160
+ | p_expr tCOMMA p_args
2161
+ {
2162
+ expr, _, args = val
2163
+
2164
+ result = new_array_pattern nil, expr, args, expr.line
2165
+ }
2166
+ | p_find
2167
+ {
2168
+ find, = val
2169
+
2170
+ result = new_find_pattern nil, find
2171
+ }
2172
+ | p_args_tail
2173
+ {
2174
+ args, = val
2175
+ result = new_array_pattern nil, nil, args, args.line
2176
+ }
2177
+ | p_kwargs
2178
+ {
2179
+ kwargs, = val
2180
+ result = new_hash_pattern nil, kwargs, kwargs.line
2181
+ }
2182
+
2183
+ p_expr: p_as
2184
+
2185
+ p_as: p_expr tASSOC p_variable
2186
+ {
2187
+ # NODE *n = NEW_LIST($1, &@$);
2188
+ # n = list_append(p, n, $3);
2189
+ # $$ = new_hash(p, n, &@$);
2190
+
2191
+ expr, _, var = val
2192
+
2193
+ id = var.last
2194
+
2195
+ self.env[id] = :lvar # HACK: need to extend env
2196
+ lhs = s(:lasgn, id).line var.line
2197
+
2198
+ result = new_assign lhs, expr
2199
+ }
2200
+ | p_alt
2201
+
2202
+ p_alt: p_alt tPIPE p_expr_basic
2203
+ {
2204
+ lhs, _, rhs = val
2205
+
2206
+ result = s(:or, lhs, rhs).line lhs.line
2207
+ }
2208
+ | p_expr_basic
2209
+
2210
+ p_lparen: tLPAREN2 { push_pktbl }
2211
+ p_lbracket: tLBRACK2 { push_pktbl }
2212
+
2213
+ p_expr_basic: p_value
2214
+ #if V > 30
2215
+ | p_variable
2216
+ #endif
2217
+ | p_const p_lparen p_args tRPAREN
2218
+ {
2219
+ lhs, _, args, _ = val
2220
+
2221
+ pop_pktbl
2222
+ result = new_array_pattern(lhs, nil, args, lhs.line)
2223
+ }
2224
+ | p_const p_lparen p_find tRPAREN
2225
+ {
2226
+ const, _, find, _ = val
2227
+
2228
+ pop_pktbl
2229
+ result = new_find_pattern(const, find).line const.line
2230
+ }
2231
+ | p_const p_lparen p_kwargs tRPAREN
2232
+ {
2233
+ lhs, _, kwargs, _ = val
2234
+
2235
+ pop_pktbl
2236
+ result = new_hash_pattern(lhs, kwargs, lhs.line)
2237
+ }
2238
+ | p_const tLPAREN2 tRPAREN
2239
+ {
2240
+ const, _, _ = val
2241
+
2242
+ tail = new_array_pattern_tail nil, nil, nil, nil
2243
+ result = new_array_pattern const, nil, tail, const.line
2244
+ }
2245
+ | p_const p_lbracket p_args rbracket
2246
+ {
2247
+ const, _, pre_arg, _ = val
2248
+
2249
+ pop_pktbl
2250
+ result = new_array_pattern const, nil, pre_arg, const.line
2251
+ }
2252
+ | p_const p_lbracket p_find rbracket
2253
+ {
2254
+ const, _, find, _ = val
2255
+
2256
+ pop_pktbl
2257
+ result = new_find_pattern(const, find).line const.line
2258
+ }
2259
+ | p_const p_lbracket p_kwargs rbracket
2260
+ {
2261
+ const, _, kwargs, _ = val
2262
+
2263
+ result = new_hash_pattern const, kwargs, const.line
2264
+ }
2265
+ | p_const tLBRACK2 rbracket
2266
+ {
2267
+ const, _, _ = val
2268
+
2269
+ tail = new_array_pattern_tail nil, nil, nil, nil
2270
+ result = new_array_pattern const, nil, tail, const.line
2271
+ }
2272
+ | tLBRACK p_args rbracket
2273
+ {
2274
+ _, pat, _ = val
2275
+
2276
+ result = new_array_pattern nil, nil, pat, pat.line
2277
+ }
2278
+ | tLBRACK p_find rbracket
2279
+ {
2280
+ _, find, _ = val
2281
+
2282
+ result = new_find_pattern nil, find
2283
+ }
2284
+ | tLBRACK rbracket
2285
+ {
2286
+ (_, line), _ = val
2287
+
2288
+ result = s(:array_pat).line line
2289
+ }
2290
+ | tLBRACE
2291
+ {
2292
+ push_pktbl
2293
+ result = self.in_kwarg
2294
+ self.in_kwarg = false
2295
+ }
2296
+ p_kwargs rbrace
2297
+ {
2298
+ _, in_kwarg, kwargs, _ = val
2299
+
2300
+ pop_pktbl
2301
+ self.in_kwarg = in_kwarg
2302
+
2303
+ result = new_hash_pattern(nil, kwargs, kwargs.line)
2304
+ }
2305
+ | tLBRACE rbrace
2306
+ {
2307
+ (_, line), _ = val
2308
+
2309
+ tail = new_hash_pattern_tail nil, nil, line
2310
+ result = new_hash_pattern nil, tail, line
2311
+ }
2312
+ | tLPAREN { push_pktbl } p_expr tRPAREN
2313
+ {
2314
+ _, _, expr, _ = val
2315
+
2316
+ pop_pktbl
2317
+ result = expr
2318
+ }
2319
+
2320
+ p_args: p_expr
2321
+ {
2322
+ expr, = val
2323
+
2324
+ ary = s(:array_TAIL, expr).line expr.line
2325
+ result = new_array_pattern_tail(ary, nil, nil, nil).line expr.line
2326
+ }
2327
+ | p_args_head
2328
+ {
2329
+ head, = val
2330
+
2331
+ result = new_array_pattern_tail head, true, nil, nil
2332
+ }
2333
+ | p_args_head p_arg
2334
+ {
2335
+ head, tail = val
2336
+
2337
+ both = array_pat_concat head, tail
2338
+
2339
+ result = new_array_pattern_tail both, nil, nil, nil
2340
+ result.line head.line
2341
+ }
2342
+ | p_args_head tSTAR tIDENTIFIER
2343
+ {
2344
+ head, _, (id, _line) = val
2345
+
2346
+ result = new_array_pattern_tail head, true, id.to_sym, nil
2347
+ result.line head.line
2348
+ }
2349
+ | p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
2350
+ {
2351
+ head, _, (id, _line), _, post = val
2352
+
2353
+ result = new_array_pattern_tail head, true, id.to_sym, post
2354
+ result.line head.line
2355
+ }
2356
+ | p_args_head tSTAR
2357
+ {
2358
+ expr, _ = val
2359
+
2360
+ result = new_array_pattern_tail(expr, true, nil, nil).line expr.line
2361
+ }
2362
+ | p_args_head tSTAR tCOMMA p_args_post
2363
+ {
2364
+ head, _, _, post = val
2365
+
2366
+ result = new_array_pattern_tail(head, true, nil, post).line head.line
2367
+ }
2368
+ | p_args_tail
2369
+
2370
+ p_args_head: p_arg tCOMMA
2371
+ {
2372
+ arg, _ = val
2373
+ result = arg
2374
+ }
2375
+ | p_args_head p_arg tCOMMA
2376
+ {
2377
+ head, tail, _ = val
2378
+
2379
+ result = s(:PATTERN, *head.sexp_body, *tail.sexp_body)
2380
+ result.line head.line
2381
+ }
2382
+
2383
+ p_args_tail: p_rest
2384
+ {
2385
+ (id, line), = val
2386
+
2387
+ result = new_array_pattern_tail nil, true, id, nil
2388
+ result.line line
2389
+ }
2390
+ | p_rest tCOMMA p_args_post
2391
+ {
2392
+ (id, line), _, rhs = val
2393
+
2394
+ result = new_array_pattern_tail nil, true, id, rhs
2395
+ result.line line
2396
+ }
2397
+
2398
+ p_find: p_rest tCOMMA p_args_post tCOMMA p_rest
2399
+ {
2400
+ lhs, _, mid, _, rhs = val
2401
+
2402
+ result = new_find_pattern_tail lhs, mid, rhs
2403
+ }
2404
+
2405
+ p_rest: tSTAR tIDENTIFIER
2406
+ {
2407
+ _, (id, line) = val
2408
+
2409
+ result = [id.to_sym, line]
2410
+ }
2411
+ | tSTAR
2412
+ {
2413
+ (_id, line), = val
2414
+
2415
+ result = [nil, line]
2416
+ }
2417
+
2418
+ p_args_post: p_arg
2419
+ | p_args_post tCOMMA p_arg
2420
+ {
2421
+ lhs, _, rhs = val
2422
+
2423
+ result = array_pat_concat lhs, rhs
2424
+ }
2425
+
2426
+ p_arg: p_expr
2427
+ {
2428
+ expr, = val
2429
+ expr = s(:array_TAIL, expr).line expr.line unless
2430
+ expr.sexp_type == :array_TAIL
2431
+ result = expr
2432
+ }
2433
+
2434
+ p_kwargs: p_kwarg tCOMMA p_any_kwrest
2435
+ {
2436
+ kw_arg, _, rest = val
2437
+ # TODO? new_unique_key_hash(p, $1, &@$)
2438
+ result = new_hash_pattern_tail kw_arg, rest, kw_arg.line
2439
+ }
2440
+ | p_kwarg
2441
+ {
2442
+ kwarg, = val
2443
+ # TODO? new_unique_key_hash(p, $1, &@$)
2444
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2445
+ }
2446
+ | p_kwarg tCOMMA
2447
+ {
2448
+ kwarg, _ = val
2449
+ # TODO? new_unique_key_hash(p, $1, &@$)
2450
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2451
+ }
2452
+ | p_any_kwrest
2453
+ {
2454
+ rest, = val
2455
+
2456
+ result = new_hash_pattern_tail nil, rest, rest.line
2457
+ }
2458
+
2459
+ p_kwarg: p_kw # TODO? rb_ary_new_from_args(1, $1)
2460
+ | p_kwarg tCOMMA p_kw
2461
+ {
2462
+ kwarg, _, kw = val
2463
+ kwarg.concat kw.sexp_body
2464
+ result = kwarg
2465
+ }
2466
+
2467
+ p_kw: p_kw_label p_expr
2468
+ {
2469
+ # TODO: error_duplicate_pattern_key(p, get_id($1), &@1);
2470
+ lhs, rhs = val
2471
+
2472
+ result = s(:PAIR, lhs, rhs).line lhs.line
2473
+ }
2474
+ | p_kw_label
2475
+ {
2476
+ lhs, = val
2477
+
2478
+ # TODO: error_duplicate_pattern_variable(p, get_id($1), &@1);
2479
+
2480
+ # TODO: if ($1 && !is_local_id(get_id($1))) {
2481
+ # yyerror1(&@1, "key must be valid as local variables");
2482
+ # }
2483
+
2484
+ # $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$),
2485
+ # assignable(p, $1, 0, &@$));
2486
+
2487
+ case lhs.sexp_type
2488
+ when :lit then
2489
+ assignable [lhs.value, lhs.line]
2490
+ else
2491
+ # TODO or done?
2492
+ debug 10
2493
+ end
2494
+
2495
+ # TODO PAIR -> LIST ?
2496
+ result = s(:PAIR, lhs, nil).line lhs.line
2497
+ }
2498
+
2499
+ p_kw_label: tLABEL
2500
+ {
2501
+ result = wrap :lit, val[0]
2502
+ }
2503
+ #if V > 30
2504
+ | tSTRING_BEG string_contents tLABEL_END
2505
+ {
2506
+ # you can't actually get here the way I lex labels
2507
+ debug 11
2508
+ }
2509
+ #endif
2510
+
2511
+ p_kwrest: kwrest_mark tIDENTIFIER
2512
+ {
2513
+ _, (id, line) = val
2514
+
2515
+ name = id.to_sym
2516
+ self.assignable [name, line]
2517
+ result = s(:kwrest, :"**#{name}").line line
2518
+ }
2519
+ | kwrest_mark
2520
+ {
2521
+ (_, line), = val
2522
+
2523
+ result = s(:kwrest, :"**").line line
2524
+ }
2525
+
2526
+ p_kwnorest: kwrest_mark kNIL
2527
+ {
2528
+ (_, line), _ = val
2529
+
2530
+ # TODO: or s(:norest)? s(:**nil)?
2531
+ result = s(:kwrest, :"**nil").line line
2532
+ }
2533
+
2534
+ p_any_kwrest: p_kwrest
2535
+ | p_kwnorest
2536
+
2537
+ p_value: p_primitive
2538
+ | p_primitive tDOT2 p_primitive
2539
+ {
2540
+ lhs, _, rhs = val
2541
+
2542
+ lhs = value_expr lhs
2543
+ rhs = value_expr rhs
2544
+
2545
+ result = s(:dot2, lhs, rhs).line lhs.line
2546
+ }
2547
+ | p_primitive tDOT3 p_primitive
2548
+ {
2549
+ lhs, _, rhs = val
2550
+
2551
+ lhs = value_expr lhs
2552
+ rhs = value_expr rhs
2553
+
2554
+ result = s(:dot3, lhs, rhs).line lhs.line
2555
+ }
2556
+ | p_primitive tDOT2
2557
+ {
2558
+ v1, _ = val
2559
+
2560
+ result = s(:dot2, v1, nil).line v1.line
2561
+ }
2562
+ | p_primitive tDOT3
2563
+ {
2564
+ v1, _ = val
2565
+
2566
+ result = s(:dot3, v1, nil).line v1.line
2567
+ }
2568
+ #if V == 30
2569
+ | p_variable
2570
+ #endif
2571
+ | p_var_ref
2572
+ #if V > 30
2573
+ | p_expr_ref
2574
+ #endif
2575
+ | p_const
2576
+ | tBDOT2 p_primitive
2577
+ {
2578
+ _, v1 = val
2579
+
2580
+ result = s(:dot2, nil, v1).line v1.line
2581
+ }
2582
+ | tBDOT3 p_primitive
2583
+ {
2584
+ _, v1 = val
2585
+
2586
+ result = s(:dot3, nil, v1).line v1.line
2587
+ }
2588
+
2589
+ p_primitive: literal
2590
+ | strings
2591
+ | xstring
2592
+ | regexp
2593
+ | words
2594
+ | qwords
2595
+ | symbols
2596
+ | qsymbols
2597
+ | keyword_variable
2598
+ {
2599
+ # TODO? if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
2600
+ var, = val
2601
+
2602
+ result = var
2603
+ }
2604
+ | lambda
2605
+
2606
+ p_variable: tIDENTIFIER
2607
+ {
2608
+ # TODO: error_duplicate_pattern_variable(p, $1, &@1);
2609
+ # TODO: assignable(p, $1, 0, &@$);
2610
+ result = wrap :lvar, val[0]
2611
+ }
2612
+
2613
+ p_var_ref: tCARET tIDENTIFIER
2614
+ {
2615
+ # TODO: check id against env for lvar or dvar
2616
+ result = wrap :lvar, val[1]
2617
+ }
2618
+ #if V > 30
2619
+ | tCARET nonlocal_var
2620
+ {
2621
+ _, var = val
2622
+ result = var
2623
+ }
2624
+ #endif
2625
+
2626
+ #if V > 30
2627
+ p_expr_ref: tCARET tLPAREN expr_value rparen
2628
+ {
2629
+ _, _, expr, _ = val
2630
+ result = expr # TODO? s(:begin, expr).line expr.line
2631
+ }
2632
+ #endif
2633
+
2634
+ p_const: tCOLON3 cname
2635
+ {
2636
+ result = wrap :colon3, val[1]
2637
+ }
2638
+ | p_const tCOLON2 cname
2639
+ {
2640
+ lhs, _, (id, _line) = val
2641
+
2642
+ l = lhs.line
2643
+ result = s(:const, s(:colon2, lhs, id.to_sym).line(l)).line l
2644
+ }
2645
+ | tCONSTANT
2646
+ {
2647
+ # TODO $$ = gettable(p, $1, &@$);
2648
+ result = wrap :const, val[0]
2649
+ }
2650
+ ######################################################################
2651
+
2652
+ opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
2653
+ {
2654
+ (_, line), klasses, var, _, body, rest = val
2655
+
2656
+ klasses ||= s(:array)
2657
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
2658
+ klasses.line line
2659
+
2660
+ result = new_resbody(klasses, body)
2661
+ result << rest if rest # UGH, rewritten above
2662
+ }
2663
+ |
2664
+ {
2665
+ result = nil
2666
+ }
2667
+
2668
+ exc_list: arg_value
2669
+ {
2670
+ arg, = val
2671
+ result = s(:array, arg).line arg.line
2672
+ }
2673
+ | mrhs
2674
+ | none
2675
+
2676
+ exc_var: tASSOC lhs
2677
+ {
2678
+ result = val[1]
2679
+ }
2680
+ | none
2681
+
2682
+ opt_ensure: k_ensure compstmt
2683
+ {
2684
+ (_, line), body = val
2685
+
2686
+ result = body || s(:nil).line(line)
2687
+ }
2688
+ | none
2689
+
2690
+ literal: numeric
2691
+ {
2692
+ (lit, line), = val
2693
+ result = s(:lit, lit).line line
2694
+ }
2695
+ | symbol
2696
+
2697
+ strings: string
2698
+ {
2699
+ str, = val
2700
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
2701
+ result = str
2702
+ }
2703
+
2704
+ string: tCHAR
2705
+ {
2706
+ debug 12
2707
+ }
2708
+ | string1
2709
+ | string string1
2710
+ {
2711
+ result = self.literal_concat val[0], val[1]
2712
+ }
2713
+
2714
+ string1: tSTRING_BEG string_contents tSTRING_END
2715
+ {
2716
+ (_, line), str, (_, func) = val
2717
+
2718
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
2719
+
2720
+ result = str.line line
2721
+ }
2722
+ | tSTRING
2723
+ {
2724
+ result = new_string val
2725
+ }
2726
+
2727
+ xstring: tXSTRING_BEG xstring_contents tSTRING_END
2728
+ {
2729
+ result = new_xstring val
2730
+ # TODO: dedent?!?! SERIOUSLY?!?
2731
+ }
2732
+
2733
+ regexp: tREGEXP_BEG regexp_contents tREGEXP_END
2734
+ {
2735
+ result = new_regexp val
2736
+ }
2737
+
2738
+ words: tWORDS_BEG tSPACE tSTRING_END
2739
+ {
2740
+ (_, line), _, _ = val
2741
+
2742
+ result = s(:array).line line
2743
+ }
2744
+ | tWORDS_BEG word_list tSTRING_END
2745
+ {
2746
+ (_, line), list, _ = val
2747
+
2748
+ result = list.line line
2749
+ }
2750
+
2751
+ word_list: none
2752
+ {
2753
+ result = new_word_list
2754
+ }
2755
+ | word_list word tSPACE
2756
+ {
2757
+ result = val[0].dup << new_word_list_entry(val)
2758
+ }
2759
+
2760
+ word: string_content
2761
+ | word string_content
2762
+ {
2763
+ result = self.literal_concat val[0], val[1]
2764
+ }
2765
+
2766
+ symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2767
+ {
2768
+ (_, line), _, _ = val
2769
+
2770
+ result = s(:array).line line
2771
+ }
2772
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2773
+ {
2774
+ (_, line), list, _, = val
2775
+ list.line line
2776
+ result = list
2777
+ }
2778
+
2779
+ symbol_list: none
2780
+ {
2781
+ result = new_symbol_list
2782
+ }
2783
+ | symbol_list word tSPACE
2784
+ {
2785
+ list, * = val
2786
+ result = list.dup << new_symbol_list_entry(val)
2787
+ }
2788
+
2789
+ qwords: tQWORDS_BEG tSPACE tSTRING_END
2790
+ {
2791
+ (_, line), _, _ = val
2792
+
2793
+ result = s(:array).line line
2794
+ }
2795
+ | tQWORDS_BEG qword_list tSTRING_END
2796
+ {
2797
+ (_, line), list, _ = val
2798
+
2799
+ result = list.line line
2800
+ }
2801
+
2802
+ qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2803
+ {
2804
+ (_, line), _, _ = val
2805
+
2806
+ result = s(:array).line line
2807
+ }
2808
+ | tQSYMBOLS_BEG qsym_list tSTRING_END
2809
+ {
2810
+ (_, line), list, _ = val
2811
+
2812
+ result = list.line line
2813
+ }
2814
+
2815
+ qword_list: none
2816
+ {
2817
+ result = new_qword_list
2818
+ }
2819
+ | qword_list tSTRING_CONTENT tSPACE
2820
+ {
2821
+ result = val[0].dup << new_qword_list_entry(val)
2822
+ }
2823
+
2824
+ qsym_list: none
2825
+ {
2826
+ result = new_qsym_list
2827
+ }
2828
+ | qsym_list tSTRING_CONTENT tSPACE
2829
+ {
2830
+ result = val[0].dup << new_qsym_list_entry(val)
2831
+ }
2832
+
2833
+ string_contents: none
2834
+ {
2835
+ line = prev_value_to_lineno _values.last
2836
+ result = s(:str, +"").line line
2837
+ }
2838
+ | string_contents string_content
2839
+ {
2840
+ v1, v2 = val
2841
+ result = literal_concat v1, v2
2842
+ }
2843
+
2844
+ xstring_contents: none
2845
+ {
2846
+ result = nil
2847
+ }
2848
+ | xstring_contents string_content
2849
+ {
2850
+ v1, v2 = val
2851
+ result = literal_concat v1, v2
2852
+ }
2853
+
2854
+ regexp_contents: none
2855
+ {
2856
+ result = nil
2857
+ }
2858
+ | regexp_contents string_content
2859
+ {
2860
+ v1, v2 = val
2861
+ result = literal_concat v1, v2
2862
+ }
2863
+
2864
+ string_content: tSTRING_CONTENT
2865
+ {
2866
+ result = new_string val
2867
+ }
2868
+ | tSTRING_DVAR
2869
+ {
2870
+ result = lexer.lex_strterm
2871
+
2872
+ lexer.lex_strterm = nil
2873
+ lexer.lex_state = EXPR_BEG
2874
+ }
2875
+ string_dvar
2876
+ {
2877
+ _, strterm, str = val
2878
+ lexer.lex_strterm = strterm
2879
+ result = s(:evstr, str).line str.line
2880
+ }
2881
+ | tSTRING_DBEG
2882
+ {
2883
+ result = [lexer.lex_strterm,
2884
+ lexer.brace_nest,
2885
+ lexer.string_nest, # TODO: remove
2886
+ lexer.lex_state,
2887
+ lexer.lineno,
2888
+ ]
2889
+
2890
+ lexer.cmdarg.push false
2891
+ lexer.cond.push false
2892
+
2893
+ lexer.lex_strterm = nil
2894
+ lexer.brace_nest = 0
2895
+ lexer.string_nest = 0
2896
+
2897
+ lexer.lex_state = EXPR_BEG
2898
+ }
2899
+ compstmt
2900
+ tSTRING_DEND
2901
+ {
2902
+ _, memo, stmt, _ = val
2903
+
2904
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2905
+ # TODO: heredoc_indent
2906
+
2907
+ lexer.lex_strterm = lex_strterm
2908
+ lexer.brace_nest = brace_nest
2909
+ lexer.string_nest = string_nest
2910
+
2911
+ lexer.cond.pop
2912
+ lexer.cmdarg.pop
2913
+
2914
+ lexer.lex_state = oldlex_state
2915
+
2916
+ case stmt
2917
+ when Sexp then
2918
+ case stmt.sexp_type
2919
+ when :str, :dstr, :evstr then
2920
+ result = stmt
2921
+ else
2922
+ result = s(:evstr, stmt).line line
2923
+ end
2924
+ when nil then
2925
+ result = s(:evstr).line line
2926
+ else
2927
+ debug 13
2928
+ raise "unknown string body: #{stmt.inspect}"
2929
+ end
2930
+ }
2931
+
2932
+ string_dvar: tGVAR
2933
+ {
2934
+ result = wrap :gvar, val[0]
2935
+ }
2936
+ | tIVAR
2937
+ {
2938
+ result = wrap :ivar, val[0]
2939
+ }
2940
+ | tCVAR
2941
+ {
2942
+ result = wrap :cvar, val[0]
2943
+ }
2944
+ | backref
2945
+
2946
+ symbol: ssym
2947
+ | dsym
2948
+
2949
+ ssym: tSYMBEG sym
2950
+ {
2951
+ lexer.lex_state = EXPR_END
2952
+ result = wrap :lit, val[1]
2953
+ }
2954
+ | tSYMBOL
2955
+ {
2956
+ lexer.lex_state = EXPR_END
2957
+ result = wrap :lit, val[0]
2958
+ }
2959
+
2960
+ sym: fname | tIVAR | tGVAR | tCVAR
2961
+
2962
+ dsym: tSYMBEG string_contents tSTRING_END
2963
+ {
2964
+ _, result, _ = val
2965
+
2966
+ lexer.lex_state = EXPR_END
2967
+
2968
+ result ||= s(:str, "").line lexer.lineno
2969
+
2970
+ case result.sexp_type
2971
+ when :dstr then
2972
+ result.sexp_type = :dsym
2973
+ when :str then
2974
+ result = s(:lit, result.last.to_sym).line result.line
2975
+ when :evstr then
2976
+ result = s(:dsym, "", result).line result.line
2977
+ else
2978
+ debug 14
2979
+ end
2980
+ }
2981
+
2982
+ numeric: simple_numeric
2983
+ | tUMINUS_NUM simple_numeric =tLOWEST
2984
+ {
2985
+ _, (num, line) = val
2986
+ result = [-num, line]
2987
+ }
2988
+
2989
+ simple_numeric: tINTEGER
2990
+ | tFLOAT
2991
+ | tRATIONAL
2992
+ | tIMAGINARY
2993
+
2994
+ #if V > 30
2995
+ nonlocal_var: tIVAR { result = wrap :ivar, val[0] }
2996
+ | tGVAR { result = wrap :gvar, val[0] }
2997
+ | tCVAR { result = wrap :cvar, val[0] }
2998
+ #endif
2999
+
3000
+ user_variable: tIDENTIFIER
3001
+ | tIVAR
3002
+ | tGVAR
3003
+ | tCONSTANT
3004
+ | tCVAR
3005
+
3006
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
3007
+ | kSELF { result = s(:self).line lexer.lineno }
3008
+ | kTRUE { result = s(:true).line lexer.lineno }
3009
+ | kFALSE { result = s(:false).line lexer.lineno }
3010
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
3011
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
3012
+ | k__ENCODING__
3013
+ {
3014
+ l = lexer.lineno
3015
+ result =
3016
+ if defined? Encoding then
3017
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
3018
+ else
3019
+ s(:str, "Unsupported!").line l
3020
+ end
3021
+ }
3022
+
3023
+ var_ref: user_variable
3024
+ {
3025
+ raise "NO: #{val.inspect}" if Sexp === val.first
3026
+ (var, line), = val
3027
+ result = Sexp === var ? var : self.gettable(var)
3028
+
3029
+ result.line line
3030
+ }
3031
+ | keyword_variable
3032
+ {
3033
+ var = val[0]
3034
+ result = Sexp === var ? var : self.gettable(var)
3035
+ }
3036
+
3037
+ var_lhs: user_variable
3038
+ {
3039
+ result = self.assignable val[0]
3040
+ }
3041
+ | keyword_variable
3042
+ {
3043
+ result = self.assignable val[0]
3044
+ debug 15
3045
+ }
3046
+
3047
+ backref: tNTH_REF
3048
+ {
3049
+ (ref, line), = val
3050
+ result = s(:nth_ref, ref).line line
3051
+ }
3052
+ | tBACK_REF
3053
+ {
3054
+ (ref, line), = val
3055
+ result = s(:back_ref, ref).line line
3056
+ }
3057
+
3058
+ superclass: tLT
3059
+ {
3060
+ lexer.lex_state = EXPR_BEG
3061
+ lexer.command_start = true
3062
+ }
3063
+ expr_value term
3064
+ {
3065
+ result = val[2]
3066
+ }
3067
+ | none
3068
+ {
3069
+ result = nil
3070
+ }
3071
+
3072
+ f_opt_paren_args: f_paren_args
3073
+ | none
3074
+ {
3075
+ result = end_args val
3076
+ }
3077
+
3078
+ f_paren_args: tLPAREN2 f_args rparen
3079
+ {
3080
+ result = end_args val
3081
+ }
3082
+ #if V == 30
3083
+ | tLPAREN2 f_arg tCOMMA args_forward rparen
3084
+ {
3085
+ result = end_args val
3086
+ }
3087
+ | tLPAREN2 args_forward rparen
3088
+ {
3089
+ result = end_args val
3090
+ }
3091
+ #endif
3092
+
3093
+ f_arglist: f_paren_args
3094
+ | {
3095
+ result = self.in_kwarg
3096
+ self.in_kwarg = true
3097
+ self.lexer.lex_state |= EXPR_LABEL
3098
+ }
3099
+ f_args term
3100
+ {
3101
+ result = end_args val
3102
+ }
3103
+
3104
+ args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
3105
+ {
3106
+ result = args val
3107
+ }
3108
+ | f_kwarg opt_f_block_arg
3109
+ {
3110
+ result = args val
3111
+ }
3112
+ | f_any_kwrest opt_f_block_arg
3113
+ {
3114
+ result = args val
3115
+ }
3116
+ | f_block_arg
3117
+ #if V > 30
3118
+ | args_forward
3119
+ #endif
3120
+
3121
+ opt_args_tail: tCOMMA args_tail
3122
+ {
3123
+ result = val[1]
3124
+ }
3125
+ |
3126
+ {
3127
+ result = nil
3128
+ }
3129
+
3130
+ f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail
3131
+ {
3132
+ result = args val
3133
+ }
3134
+ | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
3135
+ {
3136
+ result = args val
3137
+ }
3138
+ | f_arg tCOMMA f_optarg opt_args_tail
3139
+ {
3140
+ result = args val
3141
+ }
3142
+ | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail
3143
+ {
3144
+ result = args val
3145
+ }
3146
+ | f_arg tCOMMA f_rest_arg opt_args_tail
3147
+ {
3148
+ result = args val
3149
+ }
3150
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
3151
+ {
3152
+ result = args val
3153
+ }
3154
+ | f_arg opt_args_tail
3155
+ {
3156
+ result = args val
3157
+ }
3158
+ | f_optarg tCOMMA f_rest_arg opt_args_tail
3159
+ {
3160
+ result = args val
3161
+ }
3162
+ | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
3163
+ {
3164
+ result = args val
3165
+ }
3166
+ | f_optarg opt_args_tail
3167
+ {
3168
+ result = args val
3169
+ }
3170
+ | f_optarg tCOMMA f_arg opt_args_tail
3171
+ {
3172
+ result = args val
3173
+ }
3174
+ | f_rest_arg opt_args_tail
3175
+ {
3176
+ result = args val
3177
+ }
3178
+ | f_rest_arg tCOMMA f_arg opt_args_tail
3179
+ {
3180
+ result = args val
3181
+ }
3182
+ | args_tail
3183
+ {
3184
+ result = args val
3185
+ }
3186
+ |
3187
+ {
3188
+ result = args val
3189
+ # result.line lexer.lineno
3190
+ }
3191
+
3192
+ args_forward: tBDOT3
3193
+ {
3194
+ result = s(:forward_args).line lexer.lineno
3195
+ }
3196
+
3197
+ f_bad_arg: tCONSTANT
3198
+ {
3199
+ yyerror "formal argument cannot be a constant"
3200
+ }
3201
+ | tIVAR
3202
+ {
3203
+ yyerror "formal argument cannot be an instance variable"
3204
+ }
3205
+ | tGVAR
3206
+ {
3207
+ yyerror "formal argument cannot be a global variable"
3208
+ }
3209
+ | tCVAR
3210
+ {
3211
+ yyerror "formal argument cannot be a class variable"
3212
+ }
3213
+
3214
+ f_norm_arg: f_bad_arg
3215
+ | tIDENTIFIER
3216
+ {
3217
+ (id, line), = val
3218
+ identifier = id.to_sym
3219
+ self.env[identifier] = :lvar
3220
+
3221
+ result = [identifier, line]
3222
+ }
3223
+
3224
+ f_arg_asgn: f_norm_arg
3225
+
3226
+ f_arg_item: f_arg_asgn
3227
+ | tLPAREN f_margs rparen
3228
+ {
3229
+ _, margs, _ = val
3230
+
3231
+ result = margs
3232
+ }
3233
+
3234
+ f_arg: f_arg_item
3235
+ {
3236
+ result = new_arg val
3237
+ }
3238
+ | f_arg tCOMMA f_arg_item
3239
+ {
3240
+ list, _, item = val
3241
+
3242
+ if list.sexp_type == :args then
3243
+ result = list
3244
+ else
3245
+ result = s(:args, list).line list.line
3246
+ end
3247
+
3248
+ result << (Sexp === item ? item : item.first)
3249
+ }
3250
+
3251
+ f_label: tLABEL
3252
+
3253
+ f_kw: f_label arg_value
3254
+ {
3255
+ # TODO: new_kw_arg
3256
+ (label, line), arg = val
3257
+
3258
+ identifier = label.to_sym
3259
+ self.env[identifier] = :lvar
3260
+
3261
+ kwarg = s(:kwarg, identifier, arg).line line
3262
+ result = s(:array, kwarg).line line
3263
+ }
3264
+ | f_label
3265
+ {
3266
+ (label, line), = val
3267
+
3268
+ id = label.to_sym
3269
+ self.env[id] = :lvar
3270
+
3271
+ result = s(:array, s(:kwarg, id).line(line)).line line
3272
+ }
3273
+
3274
+ f_block_kw: f_label primary_value
3275
+ {
3276
+ # TODO: new_kw_arg
3277
+ (label, line), expr = val
3278
+ id = label.to_sym
3279
+ self.env[id] = :lvar
3280
+
3281
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
3282
+ }
3283
+ | f_label
3284
+ {
3285
+ # TODO: new_kw_arg
3286
+ (label, line), = val
3287
+ id = label.to_sym
3288
+ self.env[id] = :lvar
3289
+
3290
+ result = s(:array, s(:kwarg, id).line(line)).line line
3291
+ }
3292
+
3293
+ f_block_kwarg: f_block_kw
3294
+ | f_block_kwarg tCOMMA f_block_kw
3295
+ {
3296
+ list, _, item = val
3297
+ result = list << item.last
3298
+ }
3299
+
3300
+ f_kwarg: f_kw
3301
+ | f_kwarg tCOMMA f_kw
3302
+ {
3303
+ result = args val
3304
+ }
3305
+
3306
+ kwrest_mark: tPOW
3307
+ | tDSTAR
3308
+
3309
+ f_no_kwarg: kwrest_mark kNIL
3310
+ {
3311
+ (_, line), _ = val
3312
+ result = [:"**nil", line]
3313
+ }
3314
+
3315
+ f_kwrest: kwrest_mark tIDENTIFIER
3316
+ {
3317
+ _, (id, line) = val
3318
+
3319
+ name = id.to_sym
3320
+ self.assignable [name, line]
3321
+ result = [:"**#{name}", line]
3322
+ }
3323
+ | kwrest_mark
3324
+ {
3325
+ id = :"**"
3326
+ self.env[id] = :lvar # TODO: needed?!?
3327
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
3328
+ }
3329
+
3330
+ f_opt: f_arg_asgn
3331
+ #if V > 30
3332
+ f_eq
3333
+ #else
3334
+ tEQL
3335
+ #endif
3336
+ arg_value
3337
+ {
3338
+ lhs, _, rhs = val
3339
+ result = self.assignable lhs, rhs
3340
+ # TODO: detect duplicate names
3341
+ # TODO? p->cur_arg = 0;
3342
+ # TODO? p->ctxt.in_argdef = 1;
3343
+ }
3344
+
3345
+ f_block_opt: f_arg_asgn
3346
+ #if V > 30
3347
+ f_eq
3348
+ #else
3349
+ tEQL
3350
+ #endif
3351
+ primary_value
3352
+ {
3353
+ lhs, _, rhs = val
3354
+ result = self.assignable lhs, rhs
3355
+ # TODO? p->cur_arg = 0;
3356
+ # TODO? p->ctxt.in_argdef = 1;
3357
+ }
3358
+
3359
+ f_block_optarg: f_block_opt
3360
+ {
3361
+ optblk, = val
3362
+ result = s(:block, optblk).line optblk.line
3363
+ }
3364
+ | f_block_optarg tCOMMA f_block_opt
3365
+ {
3366
+ optarg, _, optblk = val
3367
+ result = optarg
3368
+ result << optblk
3369
+ }
3370
+
3371
+ f_optarg: f_opt
3372
+ {
3373
+ opt, = val
3374
+ result = s(:block, opt).line opt.line
3375
+ }
3376
+ | f_optarg tCOMMA f_opt
3377
+ {
3378
+ result = self.block_append val[0], val[2]
3379
+ }
3380
+
3381
+ restarg_mark: tSTAR2 | tSTAR
3382
+
3383
+ f_rest_arg: restarg_mark tIDENTIFIER
3384
+ {
3385
+ # TODO: differs from parse.y - needs tests
3386
+ _, (id, line) = val
3387
+ name = id.to_sym
3388
+ self.assignable [name, line]
3389
+ result = [:"*#{name}", line]
3390
+ }
3391
+ | restarg_mark
3392
+ {
3393
+ name = :"*"
3394
+ self.env[name] = :lvar
3395
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
3396
+ }
3397
+
3398
+ blkarg_mark: tAMPER2 | tAMPER
3399
+
3400
+ f_block_arg: blkarg_mark tIDENTIFIER
3401
+ {
3402
+ _, (id, line) = val
3403
+ identifier = id.to_sym
3404
+
3405
+ self.env[identifier] = :lvar
3406
+ result = ["&#{identifier}".to_sym, line]
3407
+ }
3408
+ | blkarg_mark
3409
+ {
3410
+ (_, line), = val
3411
+
3412
+ result = [:&, line]
3413
+ }
3414
+
3415
+ opt_f_block_arg: tCOMMA f_block_arg
3416
+ {
3417
+ _, arg = val
3418
+ result = arg
3419
+ }
3420
+ |
3421
+ {
3422
+ result = nil
3423
+ }
3424
+
3425
+ singleton: var_ref
3426
+ | tLPAREN2
3427
+ {
3428
+ lexer.lex_state = EXPR_BEG
3429
+ }
3430
+ expr rparen
3431
+ {
3432
+ result = val[2]
3433
+ yyerror "Can't define single method for literals." if
3434
+ result.sexp_type == :lit
3435
+ }
3436
+
3437
+ assoc_list: none
3438
+ {
3439
+ result = s(:array).line lexer.lineno
3440
+ }
3441
+ | assocs trailer
3442
+
3443
+ assocs: assoc
3444
+ | assocs tCOMMA assoc
3445
+ {
3446
+ list = val[0].dup
3447
+ more = val[2].sexp_body
3448
+ list.push(*more) unless more.empty?
3449
+ result = list
3450
+ result.sexp_type = :hash
3451
+ }
3452
+
3453
+ assoc: arg_value tASSOC arg_value
3454
+ {
3455
+ v1, _, v2 = val
3456
+ result = s(:array, v1, v2).line v1.line
3457
+ }
3458
+ | tLABEL arg_value
3459
+ {
3460
+ label, arg = val
3461
+
3462
+ lit = wrap :lit, label
3463
+ result = s(:array, lit, arg).line lit.line
3464
+ }
3465
+ | tLABEL
3466
+ {
3467
+ lit = wrap :lit, val[0]
3468
+ arg = nil
3469
+
3470
+ result = s(:array, lit, arg).line lit.line
3471
+ }
3472
+ | tSTRING_BEG string_contents tLABEL_END arg_value
3473
+ {
3474
+ (_, line), sym, _, value = val
3475
+
3476
+ sym.sexp_type = :dsym
3477
+
3478
+ result = s(:array, sym, value).line line
3479
+ }
3480
+ | tDSTAR arg_value
3481
+ {
3482
+ _, arg = val
3483
+ line = arg.line
3484
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
3485
+ }
3486
+
3487
+ operation: tIDENTIFIER | tCONSTANT | tFID
3488
+ operation2: tIDENTIFIER | tCONSTANT | tFID | op
3489
+ operation3: tIDENTIFIER | tFID | op
3490
+ dot_or_colon: tDOT | tCOLON2
3491
+ call_op: tDOT
3492
+ | tLONELY # TODO: rename tANDDOT?
3493
+
3494
+ call_op2: call_op
3495
+ | tCOLON2
3496
+
3497
+ opt_terms: | terms
3498
+ opt_nl: | tNL
3499
+ rparen: opt_nl tRPAREN
3500
+ # TODO:
3501
+ # {
3502
+ # _, close = val
3503
+ # result = [close, lexer.lineno]
3504
+ # }
3505
+ rbracket: opt_nl tRBRACK
3506
+ {
3507
+ _, close = val
3508
+ result = [close, lexer.lineno]
3509
+ }
3510
+ rbrace: opt_nl tRCURLY
3511
+ {
3512
+ _, close = val
3513
+ result = [close, lexer.lineno]
3514
+ }
3515
+ trailer: | tNL | tCOMMA
3516
+
3517
+ term: tSEMI { yyerrok }
3518
+ | tNL
3519
+
3520
+ terms: term
3521
+ | terms tSEMI { yyerrok }
3522
+
3523
+ none: { result = nil; }
3524
+ end
3525
+
3526
+ ---- inner
3527
+
3528
+ require "ruby_lexer"
3529
+ require "ruby_parser_extras"
3530
+ include RubyLexer::State::Values
3531
+
3532
+ # :stopdoc:
3533
+
3534
+ # Local Variables: **
3535
+ # racc-token-length-max:14 **
3536
+ # End: **