brakeman 5.0.4 → 5.2.0

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