brakeman 5.0.4 → 5.2.1

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