brakeman 5.0.2 → 5.1.2

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