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,2718 @@
1
+ # -*- racc -*-
2
+
3
+ class Ruby22Parser
4
+
5
+ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
6
+ kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
7
+ kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
8
+ kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
9
+ kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
10
+ k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
11
+ tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
12
+ tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
13
+ tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
14
+ tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
15
+ tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
16
+ tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
17
+ tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
18
+ tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
19
+ tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
20
+ tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
21
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
22
+ tRATIONAL tIMAGINARY
23
+ tLABEL_END
24
+
25
+ preclow
26
+ nonassoc tLOWEST
27
+ nonassoc tLBRACE_ARG
28
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
29
+ left kOR kAND
30
+ right kNOT
31
+ nonassoc kDEFINED
32
+ right tEQL tOP_ASGN
33
+ left kRESCUE_MOD
34
+ right tEH tCOLON
35
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
36
+ left tOROP
37
+ left tANDOP
38
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
39
+ left tGT tGEQ tLT tLEQ
40
+ left tPIPE tCARET
41
+ left tAMPER2
42
+ left tLSHFT tRSHFT
43
+ left tPLUS tMINUS
44
+ left tSTAR2 tDIVIDE tPERCENT # TODO: tSTAR2 -> tMULT
45
+ right tUMINUS_NUM tUMINUS
46
+ right tPOW
47
+ right tBANG tTILDE tUPLUS
48
+ prechigh
49
+
50
+ rule
51
+
52
+ program: {
53
+ self.lexer.lex_state = EXPR_BEG
54
+ }
55
+ top_compstmt
56
+ {
57
+ result = new_compstmt val
58
+
59
+ lexer.cond.pop # local_pop
60
+ lexer.cmdarg.pop
61
+ }
62
+
63
+ top_compstmt: top_stmts opt_terms
64
+ {
65
+ stmt, _ = val
66
+ result = stmt
67
+ }
68
+
69
+ top_stmts: none
70
+ | top_stmt
71
+ | top_stmts terms top_stmt
72
+ {
73
+ result = self.block_append val[0], val[2]
74
+ }
75
+ | error top_stmt
76
+
77
+ top_stmt: stmt
78
+ | klBEGIN
79
+ {
80
+ if (self.in_def || self.in_single > 0) then
81
+ debug 11
82
+ yyerror "BEGIN in method"
83
+ end
84
+ self.env.extend
85
+ }
86
+ begin_block
87
+ {
88
+ (_, lineno), _, iter = val
89
+ iter.line lineno
90
+
91
+ (_, preexe,) = iter
92
+ preexe.line lineno
93
+
94
+ result = iter
95
+ }
96
+
97
+ begin_block: tLCURLY { result = lexer.lineno } top_compstmt tRCURLY
98
+ {
99
+ _, line, stmt, _ = val
100
+ result = new_iter s(:preexe).line(line), 0, stmt
101
+ }
102
+
103
+ bodystmt: compstmt opt_rescue k_else
104
+ {
105
+ res = _values[-2]
106
+ # TODO: move down to main match so I can just use val
107
+
108
+ warn "else without rescue is useless" unless res
109
+ }
110
+ compstmt
111
+ opt_ensure
112
+ {
113
+ body, resc, _, _, els, ens = val
114
+
115
+ result = new_body [body, resc, els, ens]
116
+ }
117
+ | compstmt opt_rescue opt_ensure
118
+ {
119
+ body, resc, ens = val
120
+
121
+ result = new_body [body, resc, nil, ens]
122
+ }
123
+
124
+ compstmt: stmts opt_terms
125
+ {
126
+ result = new_compstmt val
127
+ }
128
+
129
+ stmts: none
130
+ | stmt_or_begin # TODO: newline_node ?
131
+ | stmts terms stmt_or_begin
132
+ {
133
+ result = self.block_append val[0], val[2]
134
+ }
135
+ | error stmt
136
+ {
137
+ result = val[1]
138
+ debug 12
139
+ }
140
+
141
+ stmt_or_begin: stmt
142
+ | klBEGIN
143
+ {
144
+ yyerror "BEGIN is permitted only at toplevel"
145
+ }
146
+ begin_block
147
+ {
148
+ result = val[2] # wtf?
149
+ }
150
+
151
+ stmt: kALIAS fitem
152
+ {
153
+ lexer.lex_state = EXPR_FNAME
154
+ }
155
+ fitem
156
+ {
157
+ (_, line), lhs, _, rhs = val
158
+ result = s(:alias, lhs, rhs).line(line).line line
159
+ }
160
+ | kALIAS tGVAR tGVAR
161
+ {
162
+ (_, line), (lhs, _), (rhs, _) = val
163
+ result = s(:valias, lhs.to_sym, rhs.to_sym).line line
164
+ }
165
+ | kALIAS tGVAR tBACK_REF
166
+ {
167
+ (_, line), (lhs, _), (rhs, _) = val
168
+ result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
169
+ }
170
+ | kALIAS tGVAR tNTH_REF
171
+ {
172
+ yyerror "can't make alias for the number variables"
173
+ }
174
+ | kUNDEF undef_list
175
+ {
176
+ result = val[1]
177
+ }
178
+ | stmt kIF_MOD expr_value
179
+ {
180
+ t, _, c = val
181
+ result = new_if c, t, nil
182
+ }
183
+ | stmt kUNLESS_MOD expr_value
184
+ {
185
+ f, _, c = val
186
+ result = new_if c, nil, f
187
+ }
188
+ | stmt kWHILE_MOD expr_value
189
+ {
190
+ e, _, c = val
191
+ result = new_while e, c, true
192
+ }
193
+ | stmt kUNTIL_MOD expr_value
194
+ {
195
+ e, _, c = val
196
+ result = new_until e, c, true
197
+ }
198
+ | stmt kRESCUE_MOD stmt
199
+ {
200
+ body, _, resbody = val
201
+
202
+ resbody = new_resbody s(:array).line(resbody.line), resbody
203
+ result = new_rescue body, resbody
204
+ }
205
+ | klEND tLCURLY compstmt tRCURLY
206
+ {
207
+ (_, line), _, stmt, _ = val
208
+
209
+ if (self.in_def || self.in_single > 0) then
210
+ debug 13
211
+ yyerror "END in method; use at_exit"
212
+ end
213
+
214
+ result = new_iter s(:postexe).line(line), 0, stmt
215
+ }
216
+ | command_asgn
217
+ | mlhs tEQL command_call
218
+ {
219
+ result = new_masgn val[0], val[2], :wrap
220
+ }
221
+ | lhs tEQL mrhs
222
+ {
223
+ lhs, _, rhs = val
224
+ result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
225
+ }
226
+ | mlhs tEQL mrhs_arg
227
+ {
228
+ result = new_masgn val[0], val[2]
229
+ }
230
+ | expr
231
+
232
+ command_asgn: lhs tEQL command_rhs
233
+ {
234
+ result = new_assign val[0], val[2]
235
+ }
236
+ # | lhs tEQL command_asgn
237
+ # {
238
+ # result = new_assign val[0], val[2]
239
+ # }
240
+ | var_lhs tOP_ASGN command_rhs
241
+ {
242
+ result = new_op_asgn val
243
+ }
244
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_rhs
245
+ {
246
+ result = new_op_asgn1 val
247
+ }
248
+ | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
249
+ {
250
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
251
+
252
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
253
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
254
+ result.line prim.line
255
+ }
256
+ | primary_value call_op tCONSTANT tOP_ASGN command_rhs
257
+ {
258
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
259
+
260
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
261
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
262
+ result.line prim.line
263
+ }
264
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
265
+ {
266
+ lhs1, _, (lhs2, line), (id, _), rhs = val
267
+
268
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
269
+ }
270
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
271
+ {
272
+ lhs1, _, (lhs2, line), (id, _), rhs = val
273
+
274
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
275
+ }
276
+ | backref tOP_ASGN command_rhs
277
+ {
278
+ self.backref_assign_error val[0]
279
+ }
280
+
281
+ command_rhs: command_call =tOP_ASGN
282
+ {
283
+ expr, = val
284
+ result = value_expr expr
285
+ }
286
+ | command_asgn
287
+
288
+ expr: command_call
289
+ | expr kAND expr
290
+ {
291
+ lhs, _, rhs = val
292
+ result = logical_op :and, lhs, rhs
293
+ }
294
+ | expr kOR expr
295
+ {
296
+ lhs, _, rhs = val
297
+ result = logical_op :or, lhs, rhs
298
+ }
299
+ | kNOT opt_nl expr
300
+ {
301
+ (_, line), _, expr = val
302
+ result = new_call(expr, :"!").line line
303
+ # REFACTOR: call_uni_op
304
+ }
305
+ | tBANG command_call
306
+ {
307
+ _, cmd = val
308
+ result = new_call(cmd, :"!").line cmd.line
309
+ # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
310
+ # REFACTOR: call_uni_op -- see parse26.y
311
+ }
312
+ | arg =tLBRACE_ARG
313
+
314
+ expr_value: expr
315
+ {
316
+ result = value_expr(val[0])
317
+ }
318
+
319
+ expr_value_do: {
320
+ lexer.cond.push true
321
+ }
322
+ expr_value do
323
+ {
324
+ lexer.cond.pop
325
+ }
326
+ {
327
+ _, expr, _, _ = val
328
+ result = expr
329
+ }
330
+
331
+ command_call: command
332
+ | block_command
333
+
334
+ block_command: block_call
335
+ | block_call call_op2 operation2 command_args
336
+ {
337
+ blk, _, (msg, _line), args = val
338
+ result = new_call(blk, msg.to_sym, args).line blk.line
339
+ }
340
+
341
+ cmd_brace_block: tLBRACE_ARG
342
+ {
343
+ # self.env.extend(:dynamic)
344
+ result = self.lexer.lineno
345
+ }
346
+ brace_body tRCURLY
347
+ {
348
+ _, line, body, _ = val
349
+
350
+ result = body
351
+ result.line line
352
+
353
+ # self.env.unextend
354
+ }
355
+
356
+ fcall: operation
357
+ {
358
+ (msg, line), = val
359
+ result = new_call(nil, msg.to_sym).line line
360
+ }
361
+
362
+ command: fcall command_args =tLOWEST
363
+ {
364
+ call, args = val
365
+ result = call.concat args.sexp_body
366
+ }
367
+ | fcall command_args cmd_brace_block
368
+ {
369
+ call, args, block = val
370
+
371
+ result = call.concat args.sexp_body
372
+
373
+ if block then
374
+ block_dup_check result, block
375
+
376
+ result, operation = block, result
377
+ result.insert 1, operation
378
+ end
379
+ }
380
+ | primary_value call_op operation2 command_args =tLOWEST
381
+ {
382
+ lhs, callop, (op, _), args = val
383
+
384
+ result = new_call lhs, op.to_sym, args, callop
385
+ result.line lhs.line
386
+ }
387
+ | primary_value call_op operation2 command_args cmd_brace_block
388
+ {
389
+ recv, _, (msg, _line), args, block = val
390
+ call = new_call recv, msg.to_sym, args, val[1]
391
+
392
+ block_dup_check call, block
393
+
394
+ block.insert 1, call
395
+ result = block
396
+ }
397
+ | primary_value tCOLON2 operation2 command_args =tLOWEST
398
+ {
399
+ lhs, _, (id, line), args = val
400
+
401
+ result = new_call lhs, id.to_sym, args
402
+ result.line line
403
+ }
404
+ | primary_value tCOLON2 operation2 command_args cmd_brace_block
405
+ {
406
+ recv, _, (msg, _line), args, block = val
407
+ call = new_call recv, msg.to_sym, args
408
+
409
+ block_dup_check call, block
410
+
411
+ block.insert 1, call
412
+ result = block
413
+ }
414
+ | kSUPER command_args
415
+ {
416
+ result = new_super val[1]
417
+ }
418
+ | kYIELD command_args
419
+ {
420
+ (_, line), args = val
421
+ result = new_yield args
422
+ result.line line # TODO: push to new_yield
423
+ }
424
+ | k_return call_args
425
+ {
426
+ line = val[0].last
427
+ result = s(:return, ret_args(val[1])).line(line)
428
+ }
429
+ | kBREAK call_args
430
+ {
431
+ (_, line), args = val
432
+ result = s(:break, ret_args(args)).line line
433
+ }
434
+ | kNEXT call_args
435
+ {
436
+ line = val[0].last
437
+ result = s(:next, ret_args(val[1])).line(line)
438
+ }
439
+
440
+ mlhs: mlhs_basic
441
+ | tLPAREN mlhs_inner rparen
442
+ {
443
+ result = val[1]
444
+ }
445
+
446
+ mlhs_inner: mlhs_basic
447
+ | tLPAREN mlhs_inner rparen
448
+ {
449
+ _, arg, _ = val
450
+ l = arg.line
451
+
452
+ result = s(:masgn, s(:array, arg).line(l)).line l
453
+ }
454
+
455
+ mlhs_basic: mlhs_head
456
+ {
457
+ head, = val
458
+ result = s(:masgn, head).line head.line
459
+ }
460
+ | mlhs_head mlhs_item
461
+ {
462
+ lhs, rhs = val
463
+ result = s(:masgn, lhs << rhs.compact).line lhs.line
464
+ }
465
+ | mlhs_head tSTAR mlhs_node
466
+ {
467
+ head, _, tail = val
468
+ head << s(:splat, tail).line(tail.line)
469
+ result = s(:masgn, head).line head.line
470
+ }
471
+ | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
472
+ {
473
+ ary1, _, splat, _, ary2 = val
474
+
475
+ result = list_append ary1, s(:splat, splat).line(splat.line)
476
+ result.concat ary2.sexp_body
477
+ result = s(:masgn, result).line result.line
478
+ }
479
+ | mlhs_head tSTAR
480
+ {
481
+ head, _ = val
482
+ l = head.line
483
+ result = s(:masgn, head << s(:splat).line(l)).line l
484
+ }
485
+ | mlhs_head tSTAR tCOMMA mlhs_post
486
+ {
487
+ head, _, _, post = val
488
+ ary = list_append head, s(:splat).line(head.line)
489
+ ary.concat post.sexp_body
490
+ result = s(:masgn, ary).line ary.line
491
+ }
492
+ | tSTAR mlhs_node
493
+ {
494
+ _, node = val
495
+ l = node.line
496
+ splat = s(:splat, node).line l
497
+ ary = s(:array, splat).line l
498
+ result = s(:masgn, ary).line l
499
+ }
500
+ | tSTAR mlhs_node tCOMMA mlhs_post
501
+ {
502
+ _, node, _, post = val
503
+
504
+ splat = s(:splat, node).line node.line
505
+ ary = s(:array, splat).line splat.line
506
+ ary.concat post.sexp_body
507
+ result = s(:masgn, ary).line ary.line
508
+ }
509
+ | tSTAR
510
+ {
511
+ l = lexer.lineno
512
+ result = s(:masgn, s(:array, s(:splat).line(l)).line(l)).line l
513
+ }
514
+ | tSTAR tCOMMA mlhs_post
515
+ {
516
+ _, _, post = val
517
+ l = post.line
518
+
519
+ splat = s(:splat).line l
520
+ ary = s(:array, splat, *post.sexp_body).line l
521
+ result = s(:masgn, ary).line l
522
+ }
523
+
524
+ mlhs_item: mlhs_node
525
+ | tLPAREN mlhs_inner rparen
526
+ {
527
+ result = val[1]
528
+ }
529
+
530
+ mlhs_head: mlhs_item tCOMMA
531
+ {
532
+ lhs, _ = val
533
+ result = s(:array, lhs).line lhs.line
534
+ }
535
+ | mlhs_head mlhs_item tCOMMA
536
+ {
537
+ result = val[0] << val[1].compact
538
+ }
539
+
540
+ mlhs_post: mlhs_item
541
+ {
542
+ item, = val
543
+ result = s(:array, item).line item.line
544
+ }
545
+ | mlhs_post tCOMMA mlhs_item
546
+ {
547
+ result = list_append val[0], val[2]
548
+ }
549
+
550
+ mlhs_node: user_variable
551
+ {
552
+ result = self.assignable val[0]
553
+ }
554
+ | keyword_variable
555
+ {
556
+ result = self.assignable val[0]
557
+ }
558
+ | primary_value tLBRACK2 opt_call_args rbracket
559
+ {
560
+ result = self.aryset val[0], val[2]
561
+ }
562
+ | primary_value call_op tIDENTIFIER
563
+ {
564
+ lhs, call_op, (id, _line) = val
565
+
566
+ result = new_attrasgn lhs, id, call_op
567
+ }
568
+ | primary_value tCOLON2 tIDENTIFIER
569
+ {
570
+ recv, _, (id, _line) = val
571
+ result = new_attrasgn recv, id
572
+ }
573
+ | primary_value call_op tCONSTANT
574
+ {
575
+ lhs, call_op, (id, _line) = val
576
+
577
+ result = new_attrasgn lhs, id, call_op
578
+ }
579
+ | primary_value tCOLON2 tCONSTANT
580
+ {
581
+ if (self.in_def || self.in_single > 0) then
582
+ debug 14
583
+ yyerror "dynamic constant assignment"
584
+ end
585
+
586
+ expr, _, (id, _line) = val
587
+ l = expr.line
588
+
589
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
590
+ }
591
+ | tCOLON3 tCONSTANT
592
+ {
593
+ if (self.in_def || self.in_single > 0) then
594
+ debug 15
595
+ yyerror "dynamic constant assignment"
596
+ end
597
+
598
+ _, (id, l) = val
599
+
600
+ result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
601
+ }
602
+ | backref
603
+ {
604
+ ref, = val
605
+
606
+ self.backref_assign_error ref
607
+ }
608
+
609
+ lhs: user_variable
610
+ {
611
+ var, = val
612
+
613
+ result = self.assignable var
614
+ }
615
+ | keyword_variable
616
+ {
617
+ var, = val
618
+
619
+ result = self.assignable var
620
+
621
+ debug 16
622
+ }
623
+ | primary_value tLBRACK2 opt_call_args rbracket
624
+ {
625
+ lhs, _, args, _ = val
626
+
627
+ result = self.aryset lhs, args
628
+ }
629
+ | primary_value call_op tIDENTIFIER # REFACTOR
630
+ {
631
+ lhs, op, (id, _line) = val
632
+
633
+ result = new_attrasgn lhs, id, op
634
+ }
635
+ | primary_value tCOLON2 tIDENTIFIER
636
+ {
637
+ lhs, _, (id, _line) = val
638
+
639
+ result = new_attrasgn lhs, id
640
+ }
641
+ | primary_value call_op tCONSTANT # REFACTOR?
642
+ {
643
+ lhs, call_op, (id, _line) = val
644
+
645
+ result = new_attrasgn lhs, id, call_op
646
+ }
647
+ | primary_value tCOLON2 tCONSTANT
648
+ {
649
+ expr, _, (id, _line) = val
650
+
651
+ if (self.in_def || self.in_single > 0) then
652
+ debug 17
653
+ yyerror "dynamic constant assignment"
654
+ end
655
+
656
+ l = expr.line
657
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l)).line l
658
+ }
659
+ | tCOLON3 tCONSTANT
660
+ {
661
+ _, (id, l) = val
662
+
663
+ if (self.in_def || self.in_single > 0) then
664
+ debug 18
665
+ yyerror "dynamic constant assignment"
666
+ end
667
+
668
+ result = s(:const, s(:colon3, id.to_sym).line(l)).line l
669
+ }
670
+ | backref
671
+ {
672
+ self.backref_assign_error val[0]
673
+ }
674
+
675
+ cname: tIDENTIFIER
676
+ {
677
+ yyerror "class/module name must be CONSTANT"
678
+ }
679
+ | tCONSTANT
680
+
681
+ cpath: tCOLON3 cname
682
+ {
683
+ _, (name, line) = val
684
+ result = s(:colon3, name.to_sym).line line
685
+ }
686
+ | cname
687
+ {
688
+ (id, line), = val
689
+ result = [id.to_sym, line] # TODO: sexp?
690
+ }
691
+ | primary_value tCOLON2 cname
692
+ {
693
+ pval, _, (name, _line) = val
694
+
695
+ result = s(:colon2, pval, name.to_sym)
696
+ result.line pval.line
697
+ }
698
+
699
+ fname: tIDENTIFIER | tCONSTANT | tFID
700
+ | op
701
+ {
702
+ lexer.lex_state = EXPR_END
703
+ }
704
+
705
+ | reswords
706
+
707
+ fitem: fname
708
+ {
709
+ (id, line), = val
710
+
711
+ result = s(:lit, id.to_sym).line line
712
+ }
713
+ | symbol
714
+
715
+ undef_list: fitem
716
+ {
717
+ result = new_undef val[0]
718
+ }
719
+ |
720
+ undef_list tCOMMA
721
+ {
722
+ lexer.lex_state = EXPR_FNAME
723
+ }
724
+ fitem
725
+ {
726
+ result = new_undef val[0], val[3]
727
+ }
728
+
729
+ op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
730
+ | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ
731
+ | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
732
+ | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
733
+ | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
734
+
735
+ reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
736
+ | kALIAS | kAND | kBEGIN | kBREAK | kCASE
737
+ | kCLASS | kDEF | kDEFINED | kDO | kELSE
738
+ | kELSIF | kEND | kENSURE | kFALSE | kFOR
739
+ | kIN | kMODULE | kNEXT | kNIL | kNOT
740
+ | kOR | kREDO | kRESCUE | kRETRY | kRETURN
741
+ | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF
742
+ | kWHEN | kYIELD | kIF | kUNLESS | kWHILE
743
+ | kUNTIL
744
+
745
+ arg: lhs tEQL arg_rhs
746
+ {
747
+ result = new_assign val[0], val[2]
748
+ }
749
+ | var_lhs tOP_ASGN arg_rhs
750
+ {
751
+ result = new_op_asgn val
752
+ }
753
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
754
+ {
755
+ result = new_op_asgn1 val
756
+ }
757
+ | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
758
+ {
759
+ result = new_op_asgn2 val
760
+ }
761
+ | primary_value call_op tCONSTANT tOP_ASGN arg_rhs
762
+ {
763
+ result = new_op_asgn2 val
764
+ }
765
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
766
+ {
767
+ lhs, _, (id, _line), (op, _), rhs = val
768
+
769
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
770
+ }
771
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
772
+ {
773
+ lhs1, _, (lhs2, _line), op, rhs = val
774
+
775
+ lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
776
+ result = new_const_op_asgn [lhs, op, rhs]
777
+ }
778
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
779
+ {
780
+ _, (lhs, line), op, rhs = val
781
+
782
+ lhs = s(:colon3, lhs.to_sym).line line
783
+ result = new_const_op_asgn [lhs, op, rhs]
784
+ }
785
+ | backref tOP_ASGN arg_rhs
786
+ {
787
+ # TODO: lhs = var_field val[0]
788
+ asgn = new_op_asgn val
789
+ result = self.backref_assign_error asgn
790
+ }
791
+ | arg tDOT2 arg
792
+ {
793
+ v1, v2 = val[0], val[2]
794
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
795
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
796
+ else
797
+ result = s(:dot2, v1, v2).line v1.line
798
+ end
799
+ }
800
+ | arg tDOT3 arg
801
+ {
802
+ v1, v2 = val[0], val[2]
803
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
804
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
805
+ else
806
+ result = s(:dot3, v1, v2).line v1.line
807
+ end
808
+ }
809
+
810
+
811
+ | arg tPLUS arg
812
+ {
813
+ result = new_call val[0], :+, argl(val[2])
814
+ }
815
+ | arg tMINUS arg
816
+ {
817
+ result = new_call val[0], :-, argl(val[2])
818
+ }
819
+ | arg tSTAR2 arg # TODO: rename
820
+ {
821
+ result = new_call val[0], :*, argl(val[2])
822
+ }
823
+ | arg tDIVIDE arg
824
+ {
825
+ result = new_call val[0], :"/", argl(val[2])
826
+ }
827
+ | arg tPERCENT arg
828
+ {
829
+ result = new_call val[0], :"%", argl(val[2])
830
+ }
831
+ | arg tPOW arg
832
+ {
833
+ result = new_call val[0], :**, argl(val[2])
834
+ }
835
+ | tUMINUS_NUM simple_numeric tPOW arg
836
+ {
837
+ _, (num, line), _, arg = val
838
+ lit = s(:lit, num).line line
839
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
840
+
841
+ }
842
+ | tUPLUS arg
843
+ {
844
+ result = new_call val[1], :"+@"
845
+ }
846
+ | tUMINUS arg
847
+ {
848
+ result = new_call val[1], :"-@"
849
+ }
850
+ | arg tPIPE arg
851
+ {
852
+ result = new_call val[0], :"|", argl(val[2])
853
+ }
854
+ | arg tCARET arg
855
+ {
856
+ result = new_call val[0], :"^", argl(val[2])
857
+ }
858
+ | arg tAMPER2 arg
859
+ {
860
+ result = new_call val[0], :"&", argl(val[2])
861
+ }
862
+ | arg tCMP arg
863
+ {
864
+ result = new_call val[0], :"<=>", argl(val[2])
865
+ }
866
+ | rel_expr =tCMP
867
+ | arg tEQ arg
868
+ {
869
+ result = new_call val[0], :"==", argl(val[2])
870
+ }
871
+ | arg tEQQ arg
872
+ {
873
+ result = new_call val[0], :"===", argl(val[2])
874
+ }
875
+ | arg tNEQ arg
876
+ {
877
+ result = new_call val[0], :"!=", argl(val[2])
878
+ }
879
+ | arg tMATCH arg
880
+ {
881
+ lhs, _, rhs = val
882
+ result = new_match lhs, rhs
883
+ }
884
+ | arg tNMATCH arg
885
+ {
886
+ lhs, _, rhs = val
887
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
888
+ }
889
+ | tBANG arg
890
+ {
891
+ _, arg = val
892
+ result = new_call arg, :"!"
893
+ result.line arg.line
894
+ }
895
+ | tTILDE arg
896
+ {
897
+ result = new_call value_expr(val[1]), :"~"
898
+ }
899
+ | arg tLSHFT arg
900
+ {
901
+ val[0] = value_expr val[0]
902
+ val[2] = value_expr val[2]
903
+ result = new_call val[0], :"\<\<", argl(val[2])
904
+ }
905
+ | arg tRSHFT arg
906
+ {
907
+ val[0] = value_expr val[0]
908
+ val[2] = value_expr val[2]
909
+ result = new_call val[0], :">>", argl(val[2])
910
+ }
911
+ | arg tANDOP arg
912
+ {
913
+ result = logical_op :and, val[0], val[2]
914
+ }
915
+ | arg tOROP arg
916
+ {
917
+ result = logical_op :or, val[0], val[2]
918
+ }
919
+ | kDEFINED opt_nl arg
920
+ {
921
+ (_, line), _, arg = val
922
+ result = s(:defined, arg).line line
923
+ }
924
+ | arg tEH arg opt_nl tCOLON arg
925
+ {
926
+ c, _, t, _, _, f = val
927
+ result = s(:if, c, t, f).line c.line
928
+ }
929
+ | primary
930
+
931
+ relop: tGT
932
+ | tLT
933
+ | tGEQ
934
+ | tLEQ
935
+
936
+ rel_expr: arg relop arg =tGT
937
+ {
938
+ lhs, (op, _), rhs = val
939
+ result = new_call lhs, op.to_sym, argl(rhs)
940
+ }
941
+ | rel_expr relop arg =tGT
942
+ {
943
+ lhs, (op, _), rhs = val
944
+ warn "comparison '%s' after comparison", op
945
+ result = new_call lhs, op.to_sym, argl(rhs)
946
+ }
947
+
948
+ arg_value: arg
949
+ {
950
+ result = value_expr(val[0])
951
+ }
952
+
953
+ aref_args: none
954
+ | args trailer
955
+ {
956
+ result = args [val[0]]
957
+ }
958
+ | args tCOMMA assocs trailer
959
+ {
960
+ result = args [val[0], array_to_hash(val[2])]
961
+ }
962
+ | assocs trailer
963
+ {
964
+ result = args [array_to_hash(val[0])]
965
+ }
966
+
967
+ arg_rhs: arg =tOP_ASGN
968
+ | arg kRESCUE_MOD arg
969
+ {
970
+ body, (_, line), resbody = val
971
+ body = value_expr body
972
+ resbody = remove_begin resbody
973
+
974
+ ary = s(:array).line line
975
+ result = new_rescue(body, new_resbody(ary, resbody))
976
+ }
977
+
978
+ paren_args: tLPAREN2 opt_call_args rparen
979
+ {
980
+ _, args, _ = val
981
+ result = args
982
+ }
983
+
984
+ opt_paren_args: none
985
+ | paren_args
986
+
987
+ opt_call_args: none
988
+ | call_args
989
+ | args tCOMMA
990
+ {
991
+ result = args val
992
+ }
993
+ | args tCOMMA assocs tCOMMA
994
+ {
995
+ result = args [val[0], array_to_hash(val[2])]
996
+ }
997
+ | assocs tCOMMA
998
+ {
999
+ result = args [array_to_hash(val[0])]
1000
+ }
1001
+
1002
+ call_args: command
1003
+ {
1004
+ warning "parenthesize argument(s) for future version"
1005
+ result = call_args val
1006
+ }
1007
+ | args opt_block_arg
1008
+ {
1009
+ result = call_args val
1010
+ }
1011
+ | assocs opt_block_arg
1012
+ {
1013
+ result = call_args [array_to_hash(val[0]), val[1]]
1014
+ }
1015
+ | args tCOMMA assocs opt_block_arg
1016
+ {
1017
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
1018
+ }
1019
+ | block_arg
1020
+ {
1021
+ result = call_args val
1022
+ }
1023
+
1024
+ command_args: {
1025
+ # parse26.y line 2200
1026
+
1027
+ # If call_args starts with a open paren '(' or
1028
+ # '[', look-ahead reading of the letters calls
1029
+ # CMDARG_PUSH(0), but the push must be done
1030
+ # after CMDARG_PUSH(1). So this code makes them
1031
+ # consistent by first cancelling the premature
1032
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1033
+ # finally redoing CMDARG_PUSH(0).
1034
+
1035
+ result = yychar = self.last_token_type.first
1036
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1037
+ lexer.cmdarg.pop if lookahead
1038
+ lexer.cmdarg.push true
1039
+ lexer.cmdarg.push false if lookahead
1040
+ }
1041
+ call_args
1042
+ {
1043
+ yychar, args = val
1044
+
1045
+ # call_args can be followed by tLBRACE_ARG (that
1046
+ # does CMDARG_PUSH(0) in the lexer) but the push
1047
+ # must be done after CMDARG_POP() in the parser.
1048
+ # So this code does CMDARG_POP() to pop 0 pushed
1049
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1050
+ # by command_args, and CMDARG_PUSH(0) to restore
1051
+ # back the flag set by tLBRACE_ARG.
1052
+
1053
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1054
+ lexer.cmdarg.pop if lookahead
1055
+ lexer.cmdarg.pop
1056
+ lexer.cmdarg.push false if lookahead
1057
+ result = args
1058
+ }
1059
+
1060
+ block_arg: tAMPER arg_value
1061
+ {
1062
+ _, arg = val
1063
+ result = s(:block_pass, arg).line arg.line
1064
+ }
1065
+
1066
+ opt_block_arg: tCOMMA block_arg
1067
+ {
1068
+ result = val[1]
1069
+ }
1070
+ | none
1071
+
1072
+ args: arg_value
1073
+ {
1074
+ arg, = val
1075
+ lineno = arg.line || lexer.lineno # HACK
1076
+
1077
+ result = s(:array, arg).line lineno
1078
+ }
1079
+ | tSTAR arg_value
1080
+ {
1081
+ _, arg = val
1082
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1083
+ }
1084
+ | args tCOMMA arg_value
1085
+ {
1086
+ args, _, id = val
1087
+ result = self.list_append args, id
1088
+ }
1089
+ | args tCOMMA tSTAR arg_value
1090
+ {
1091
+ # TODO: the line number from tSTAR has been dropped
1092
+ args, _, _, id = val
1093
+ line = lexer.lineno
1094
+ result = self.list_append args, s(:splat, id).line(line)
1095
+ }
1096
+
1097
+ mrhs_arg: mrhs
1098
+ {
1099
+ result = new_masgn_arg val[0]
1100
+ }
1101
+ | arg_value
1102
+ {
1103
+ result = new_masgn_arg val[0], :wrap
1104
+ }
1105
+
1106
+ mrhs: args tCOMMA arg_value
1107
+ {
1108
+ result = val[0] << val[2]
1109
+ }
1110
+ | args tCOMMA tSTAR arg_value
1111
+ {
1112
+ # TODO: make all tXXXX terminals include lexer.lineno
1113
+ arg, _, _, splat = val
1114
+ result = self.arg_concat arg, splat
1115
+ }
1116
+ | tSTAR arg_value
1117
+ {
1118
+ _, arg = val
1119
+ result = s(:splat, arg).line arg.line
1120
+ }
1121
+
1122
+ primary: literal
1123
+ | strings
1124
+ | xstring
1125
+ | regexp
1126
+ | words
1127
+ | qwords
1128
+ | symbols
1129
+ | qsymbols
1130
+ | var_ref
1131
+ | backref
1132
+ | tFID
1133
+ {
1134
+ (msg, line), = val
1135
+ result = new_call nil, msg.to_sym
1136
+ result.line line
1137
+ }
1138
+ | k_begin
1139
+ {
1140
+ lexer.cmdarg.push false
1141
+ result = self.lexer.lineno
1142
+ }
1143
+ bodystmt k_end
1144
+ {
1145
+ lexer.cmdarg.pop
1146
+ result = new_begin val
1147
+ }
1148
+ | tLPAREN_ARG
1149
+ {
1150
+ lexer.lex_state = EXPR_ENDARG
1151
+ result = lexer.lineno
1152
+ }
1153
+ rparen
1154
+ {
1155
+ _, line, _ = val
1156
+ result = s(:begin).line line
1157
+ }
1158
+ | tLPAREN_ARG
1159
+ stmt
1160
+ {
1161
+ lexer.lex_state = EXPR_ENDARG
1162
+ }
1163
+ rparen
1164
+ {
1165
+ _, stmt, _, _, = val
1166
+ # warning "(...) interpreted as grouped expression"
1167
+ result = stmt
1168
+ }
1169
+ | tLPAREN compstmt tRPAREN
1170
+ {
1171
+ _, stmt, _ = val
1172
+ result = stmt
1173
+ result ||= s(:nil).line lexer.lineno
1174
+ result.paren = true
1175
+ }
1176
+ | primary_value tCOLON2 tCONSTANT
1177
+ {
1178
+ expr, _, (id, _line) = val
1179
+
1180
+ result = s(:colon2, expr, id.to_sym).line expr.line
1181
+ }
1182
+ | tCOLON3 tCONSTANT
1183
+ {
1184
+ _, (id, line) = val
1185
+
1186
+ result = s(:colon3, id.to_sym).line line
1187
+ }
1188
+ | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1189
+ {
1190
+ _, line, args, _ = val
1191
+ result = args || s(:array)
1192
+ result.sexp_type = :array # aref_args is :args
1193
+ result.line line
1194
+ }
1195
+ | tLBRACE
1196
+ {
1197
+ result = self.lexer.lineno
1198
+ }
1199
+ assoc_list tRCURLY
1200
+ {
1201
+ result = new_hash val
1202
+ }
1203
+ | k_return
1204
+ {
1205
+ (_, line), = val
1206
+ result = s(:return).line line
1207
+ }
1208
+ | kYIELD tLPAREN2 call_args rparen
1209
+ {
1210
+ result = new_yield val[2]
1211
+ }
1212
+ | kYIELD tLPAREN2 rparen
1213
+ {
1214
+ result = new_yield
1215
+ }
1216
+ | kYIELD
1217
+ {
1218
+ result = new_yield
1219
+ }
1220
+ | kDEFINED opt_nl tLPAREN2 expr rparen
1221
+ {
1222
+ (_, line), _, _, arg, _ = val
1223
+
1224
+ result = s(:defined, arg).line line
1225
+ }
1226
+ | kNOT tLPAREN2 expr rparen
1227
+ {
1228
+ _, _, lhs, _ = val
1229
+ result = new_call lhs, :"!"
1230
+ }
1231
+ | kNOT tLPAREN2 rparen
1232
+ {
1233
+ debug 20
1234
+ }
1235
+ | fcall brace_block
1236
+ {
1237
+ call, iter = val
1238
+
1239
+ iter.insert 1, call
1240
+ result = iter
1241
+ # FIX: probably not: call.line = iter.line
1242
+ }
1243
+ | method_call
1244
+ | method_call brace_block
1245
+ {
1246
+ call, iter = val[0], val[1]
1247
+ block_dup_check call, iter
1248
+ iter.insert 1, call # FIX
1249
+ result = iter
1250
+ }
1251
+ | lambda
1252
+ {
1253
+ expr, = val
1254
+ result = expr
1255
+ }
1256
+ | k_if expr_value then compstmt if_tail k_end
1257
+ {
1258
+ _, c, _, t, f, _ = val
1259
+ result = new_if c, t, f
1260
+ }
1261
+ | k_unless expr_value then compstmt opt_else k_end
1262
+ {
1263
+ _, c, _, t, f, _ = val
1264
+ result = new_if c, f, t
1265
+ }
1266
+ | k_while expr_value_do compstmt k_end
1267
+ {
1268
+ _, cond, body, _ = val
1269
+ result = new_while body, cond, true
1270
+ }
1271
+ | k_until expr_value_do compstmt k_end
1272
+ {
1273
+ _, cond, body, _ = val
1274
+ result = new_until body, cond, true
1275
+ }
1276
+ | k_case expr_value opt_terms case_body k_end
1277
+ {
1278
+ (_, line), expr, _, body, _ = val
1279
+ result = new_case expr, body, line
1280
+ }
1281
+ | k_case opt_terms case_body k_end
1282
+ {
1283
+ (_, line), _, body, _ = val
1284
+ result = new_case nil, body, line
1285
+ }
1286
+ | k_for for_var kIN expr_value_do compstmt k_end
1287
+ {
1288
+ _, var, _, iter, body, _ = val
1289
+ result = new_for iter, var, body
1290
+ }
1291
+ | k_class
1292
+ {
1293
+ result = self.lexer.lineno
1294
+ }
1295
+ cpath superclass
1296
+ {
1297
+ if (self.in_def || self.in_single > 0) then
1298
+ yyerror "class definition in method body"
1299
+ end
1300
+ self.env.extend
1301
+ }
1302
+ bodystmt k_end
1303
+ {
1304
+ result = new_class val
1305
+ self.env.unextend
1306
+ self.lexer.ignore_body_comments
1307
+ }
1308
+ | k_class tLSHFT
1309
+ {
1310
+ result = self.lexer.lineno
1311
+ }
1312
+ expr
1313
+ {
1314
+ result = self.in_def
1315
+ self.in_def = false
1316
+ }
1317
+ term
1318
+ {
1319
+ result = self.in_single
1320
+ self.in_single = 0
1321
+ self.env.extend
1322
+ }
1323
+ bodystmt k_end
1324
+ {
1325
+ result = new_sclass val
1326
+ self.env.unextend
1327
+ self.lexer.ignore_body_comments
1328
+ }
1329
+ | k_module
1330
+ {
1331
+ result = self.lexer.lineno
1332
+ }
1333
+ cpath
1334
+ {
1335
+ yyerror "module definition in method body" if
1336
+ self.in_def or self.in_single > 0
1337
+
1338
+ self.env.extend
1339
+ }
1340
+ bodystmt k_end
1341
+ {
1342
+ result = new_module val
1343
+ self.env.unextend
1344
+ self.lexer.ignore_body_comments
1345
+ }
1346
+ | k_def fname
1347
+ {
1348
+ result = self.in_def
1349
+
1350
+ self.in_def = true # group = local_push
1351
+ self.env.extend
1352
+ lexer.cmdarg.push false
1353
+ lexer.cond.push false
1354
+ }
1355
+ f_arglist bodystmt k_end
1356
+ {
1357
+ result, in_def = new_defn val
1358
+
1359
+ lexer.cond.pop # group = local_pop
1360
+ lexer.cmdarg.pop
1361
+ self.env.unextend
1362
+ self.in_def = in_def
1363
+
1364
+ self.lexer.ignore_body_comments
1365
+ }
1366
+ | k_def singleton dot_or_colon
1367
+ {
1368
+ lexer.lex_state = EXPR_FNAME
1369
+ }
1370
+ fname
1371
+ {
1372
+ result = self.in_def
1373
+
1374
+ self.in_single += 1 # TODO: remove?
1375
+
1376
+ self.in_def = true # local_push
1377
+ self.env.extend
1378
+ lexer.cmdarg.push false
1379
+ lexer.cond.push false
1380
+
1381
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1382
+ }
1383
+ f_arglist bodystmt k_end
1384
+ {
1385
+
1386
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1387
+ # =>
1388
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1389
+
1390
+ val.delete_at 3
1391
+ val.delete_at 2
1392
+
1393
+ result, in_def = new_defs val
1394
+
1395
+ lexer.cond.pop # group = local_pop
1396
+ lexer.cmdarg.pop
1397
+ self.env.unextend
1398
+ self.in_def = in_def
1399
+
1400
+ self.in_single -= 1
1401
+
1402
+ # TODO: restore cur_arg ? what's cur_arg?
1403
+
1404
+ self.lexer.ignore_body_comments
1405
+ }
1406
+ | kBREAK
1407
+ {
1408
+ (_, line), = val
1409
+ result = s(:break).line line
1410
+ }
1411
+ | kNEXT
1412
+ {
1413
+ (_, line), = val
1414
+ result = s(:next).line line
1415
+ }
1416
+ | kREDO
1417
+ {
1418
+ (_, line), = val
1419
+ result = s(:redo).line line
1420
+ }
1421
+ | kRETRY
1422
+ {
1423
+ (_, line), = val
1424
+ result = s(:retry).line line
1425
+ }
1426
+
1427
+ primary_value: primary
1428
+ {
1429
+ result = value_expr(val[0])
1430
+ }
1431
+
1432
+ # These are really stupid
1433
+ k_begin: kBEGIN
1434
+ k_if: kIF
1435
+ k_unless: kUNLESS
1436
+ k_while: kWHILE
1437
+ k_until: kUNTIL
1438
+ k_case: kCASE
1439
+ k_for: kFOR
1440
+ k_class: kCLASS
1441
+ {
1442
+ self.comments.push self.lexer.comments
1443
+ }
1444
+ k_module: kMODULE
1445
+ {
1446
+ self.comments.push self.lexer.comments
1447
+ }
1448
+ k_def: kDEF
1449
+ {
1450
+ self.comments.push self.lexer.comments
1451
+ }
1452
+ k_do: kDO
1453
+ k_do_block: kDO_BLOCK
1454
+ k_rescue: kRESCUE
1455
+ k_ensure: kENSURE
1456
+ k_when: kWHEN
1457
+ k_else: kELSE
1458
+ k_elsif: kELSIF
1459
+ k_end: kEND
1460
+ k_return: kRETURN
1461
+
1462
+ then: term
1463
+ | kTHEN
1464
+ | term kTHEN
1465
+
1466
+ do: term
1467
+ | kDO_COND
1468
+
1469
+ if_tail: opt_else
1470
+ | k_elsif expr_value then compstmt if_tail
1471
+ {
1472
+ (_, line), c, _, t, rest = val
1473
+
1474
+ result = s(:if, c, t, rest).line line
1475
+ }
1476
+
1477
+ opt_else: none
1478
+ | kELSE compstmt
1479
+ {
1480
+ result = val[1]
1481
+ }
1482
+
1483
+ for_var: lhs
1484
+ | mlhs
1485
+ {
1486
+ val[0].delete_at 1 if val[0][1].nil? # HACK
1487
+ }
1488
+
1489
+ f_marg: f_norm_arg
1490
+ | tLPAREN f_margs rparen
1491
+ {
1492
+ result = val[1]
1493
+ }
1494
+
1495
+ f_marg_list: f_marg
1496
+ {
1497
+ sym, = val
1498
+
1499
+ result = s(:array, sym).line lexer.lineno
1500
+ }
1501
+ | f_marg_list tCOMMA f_marg
1502
+ {
1503
+ result = list_append val[0], val[2]
1504
+ }
1505
+
1506
+ f_margs: f_marg_list
1507
+ {
1508
+ args, = val
1509
+
1510
+ result = block_var args
1511
+ }
1512
+ | f_marg_list tCOMMA f_rest_marg
1513
+ {
1514
+ args, _, rest = val
1515
+
1516
+ result = block_var args, rest
1517
+ }
1518
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1519
+ {
1520
+ lhs, _, splat, _, rhs = val
1521
+
1522
+ result = block_var lhs, splat, rhs
1523
+ }
1524
+ | f_rest_marg
1525
+ {
1526
+ rest, = val
1527
+
1528
+ result = block_var rest
1529
+ }
1530
+ | f_rest_marg tCOMMA f_marg_list
1531
+ {
1532
+ splat, _, rest = val
1533
+
1534
+ result = block_var splat, rest
1535
+ }
1536
+
1537
+ f_rest_marg: tSTAR f_norm_arg
1538
+ {
1539
+ _, (id, line) = val
1540
+
1541
+ result = args ["*#{id}".to_sym]
1542
+ result.line line
1543
+ }
1544
+ | tSTAR
1545
+ {
1546
+ result = args [:*]
1547
+ result.line lexer.lineno # FIX: tSTAR -> line
1548
+ }
1549
+
1550
+ block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
1551
+ {
1552
+ result = call_args val
1553
+ }
1554
+ | f_block_kwarg opt_f_block_arg
1555
+ {
1556
+ result = call_args val
1557
+ }
1558
+ | f_kwrest opt_f_block_arg
1559
+ {
1560
+ result = call_args val
1561
+ }
1562
+ | f_block_arg
1563
+ {
1564
+ (id, line), = val
1565
+ result = call_args [id]
1566
+ result.line line
1567
+ }
1568
+
1569
+ opt_block_args_tail: tCOMMA block_args_tail
1570
+ {
1571
+ result = args val
1572
+ }
1573
+ | none
1574
+
1575
+ block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1576
+ {
1577
+ result = args val
1578
+ }
1579
+ | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1580
+ {
1581
+ result = args val
1582
+ }
1583
+ | f_arg tCOMMA f_block_optarg opt_block_args_tail
1584
+ {
1585
+ result = args val
1586
+ }
1587
+ | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail
1588
+ {
1589
+ result = args val
1590
+ }
1591
+ | f_arg tCOMMA f_rest_arg opt_block_args_tail
1592
+ {
1593
+ result = args val
1594
+ }
1595
+ | f_arg tCOMMA
1596
+ {
1597
+ result = args(val) << nil
1598
+ }
1599
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1600
+ {
1601
+ result = args val
1602
+ }
1603
+ | f_arg opt_block_args_tail
1604
+ {
1605
+ result = args val
1606
+ }
1607
+ | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1608
+ {
1609
+ result = args val
1610
+ }
1611
+ | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1612
+ {
1613
+ result = args val
1614
+ }
1615
+ | f_block_optarg opt_block_args_tail
1616
+ {
1617
+ result = args val
1618
+ }
1619
+ | f_block_optarg tCOMMA f_arg opt_block_args_tail
1620
+ {
1621
+ result = args val
1622
+ }
1623
+ | f_rest_arg opt_block_args_tail
1624
+ {
1625
+ result = args val
1626
+ }
1627
+ | f_rest_arg tCOMMA f_arg opt_block_args_tail
1628
+ {
1629
+ result = args val
1630
+ }
1631
+ | block_args_tail
1632
+ {
1633
+ result = args val
1634
+ }
1635
+
1636
+ opt_block_param: none { result = 0 }
1637
+ | block_param_def
1638
+ {
1639
+ self.lexer.command_start = true
1640
+ }
1641
+
1642
+ block_param_def: tPIPE opt_bv_decl tPIPE
1643
+ {
1644
+ # TODO: current_arg = 0
1645
+ result = args val
1646
+ }
1647
+ | tOROP
1648
+ {
1649
+ result = s(:args).line lexer.lineno
1650
+ }
1651
+ | tPIPE block_param opt_bv_decl tPIPE
1652
+ {
1653
+ # TODO: current_arg = 0
1654
+ result = args val
1655
+ }
1656
+
1657
+ opt_bv_decl: opt_nl
1658
+ | opt_nl tSEMI bv_decls opt_nl
1659
+ {
1660
+ result = args val
1661
+ }
1662
+
1663
+ bv_decls: bvar
1664
+ {
1665
+ result = args val
1666
+ }
1667
+ | bv_decls tCOMMA bvar
1668
+ {
1669
+ result = args val
1670
+ }
1671
+
1672
+ bvar: tIDENTIFIER
1673
+ {
1674
+ (id, line), = val
1675
+ result = s(:shadow, id.to_sym).line line
1676
+ }
1677
+ | f_bad_arg
1678
+
1679
+ lambda: tLAMBDA
1680
+ {
1681
+ self.env.extend :dynamic
1682
+ result = [lexer.lineno, lexer.lpar_beg]
1683
+ lexer.paren_nest += 1
1684
+ lexer.lpar_beg = lexer.paren_nest
1685
+ }
1686
+ f_larglist
1687
+ {
1688
+ lexer.cmdarg.push false
1689
+ }
1690
+ lambda_body
1691
+ {
1692
+ _, (line, lpar), args, _cmdarg, body = val
1693
+ lexer.lpar_beg = lpar
1694
+
1695
+ lexer.cmdarg.pop
1696
+
1697
+ call = s(:lambda).line line
1698
+ result = new_iter call, args, body
1699
+ result.line line
1700
+ self.env.unextend # TODO: dynapush & dynapop
1701
+ }
1702
+
1703
+ f_larglist: tLPAREN2 f_args opt_bv_decl rparen
1704
+ {
1705
+ result = args val
1706
+ }
1707
+ | f_args
1708
+ {
1709
+ result = val[0]
1710
+ result = 0 if result == s(:args)
1711
+ }
1712
+
1713
+ lambda_body: tLAMBEG compstmt tRCURLY
1714
+ {
1715
+ result = val[1]
1716
+ }
1717
+ | kDO_LAMBDA bodystmt kEND
1718
+ {
1719
+ result = val[1]
1720
+ }
1721
+
1722
+ do_block: k_do_block do_body kEND
1723
+ {
1724
+ (_, line), iter, _ = val
1725
+ result = iter.line line
1726
+ }
1727
+
1728
+ block_call: command do_block
1729
+ {
1730
+ # TODO:
1731
+ ## if (nd_type($1) == NODE_YIELD) {
1732
+ ## compile_error(PARSER_ARG "block given to yield");
1733
+
1734
+ cmd, blk = val
1735
+
1736
+ syntax_error "Both block arg and actual block given." if
1737
+ cmd.block_pass?
1738
+
1739
+ if inverted? val then
1740
+ val = invert_block_call val
1741
+ cmd, blk = val
1742
+ end
1743
+
1744
+ result = blk
1745
+ result.insert 1, cmd
1746
+ }
1747
+ | block_call call_op2 operation2 opt_paren_args
1748
+ {
1749
+ lhs, _, (id, _line), args = val
1750
+
1751
+ result = new_call lhs, id.to_sym, args
1752
+ }
1753
+ | block_call call_op2 operation2 opt_paren_args brace_block
1754
+ {
1755
+ iter1, _, (name, _line), args, iter2 = val
1756
+
1757
+ call = new_call iter1, name.to_sym, args
1758
+ iter2.insert 1, call
1759
+
1760
+ result = iter2
1761
+ }
1762
+ | block_call call_op2 operation2 command_args do_block
1763
+ {
1764
+ iter1, _, (name, _line), args, iter2 = val
1765
+
1766
+ call = new_call iter1, name.to_sym, args
1767
+ iter2.insert 1, call
1768
+
1769
+ result = iter2
1770
+ }
1771
+
1772
+ method_call: fcall paren_args
1773
+ {
1774
+ call, args = val
1775
+
1776
+ result = call.concat args.sexp_body if args
1777
+ }
1778
+ | primary_value call_op operation2 opt_paren_args
1779
+ {
1780
+ recv, call_op, (op, _line), args = val
1781
+
1782
+ result = new_call recv, op.to_sym, args, call_op
1783
+ }
1784
+ | primary_value tCOLON2 operation2 paren_args
1785
+ {
1786
+ recv, _, (op, _line), args = val
1787
+
1788
+ result = new_call recv, op.to_sym, args
1789
+ }
1790
+ | primary_value tCOLON2 operation3
1791
+ {
1792
+ lhs, _, (id, _line) = val
1793
+
1794
+ result = new_call lhs, id.to_sym
1795
+ }
1796
+ | primary_value call_op paren_args
1797
+ {
1798
+ result = new_call val[0], :call, val[2], val[1]
1799
+ }
1800
+ | primary_value tCOLON2 paren_args
1801
+ {
1802
+ result = new_call val[0], :call, val[2]
1803
+ }
1804
+ | kSUPER paren_args
1805
+ {
1806
+ result = new_super val[1]
1807
+ }
1808
+ | kSUPER
1809
+ {
1810
+ result = s(:zsuper).line lexer.lineno
1811
+ }
1812
+ | primary_value tLBRACK2 opt_call_args rbracket
1813
+ {
1814
+ result = new_aref val
1815
+ }
1816
+
1817
+ brace_block: tLCURLY
1818
+ {
1819
+ self.env.extend :dynamic
1820
+ result = self.lexer.lineno
1821
+ }
1822
+ brace_body tRCURLY
1823
+ {
1824
+ _, line, body, _ = val
1825
+
1826
+ result = body
1827
+ result.line line
1828
+
1829
+ self.env.unextend
1830
+ }
1831
+ | k_do
1832
+ {
1833
+ self.env.extend :dynamic
1834
+ result = self.lexer.lineno
1835
+ }
1836
+ do_body kEND
1837
+ {
1838
+ _, line, body, _ = val
1839
+
1840
+ result = body
1841
+ result.line line
1842
+
1843
+ self.env.unextend
1844
+ }
1845
+
1846
+ brace_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1847
+ { result = lexer.cmdarg.store(false) }
1848
+ opt_block_param compstmt
1849
+ {
1850
+ line, cmdarg, param, cmpstmt = val
1851
+
1852
+ result = new_brace_body param, cmpstmt, line
1853
+ self.env.unextend
1854
+ lexer.cmdarg.restore cmdarg
1855
+ lexer.cmdarg.pop # because of: cmdarg_stack >> 1 ?
1856
+ }
1857
+
1858
+ do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1859
+ { lexer.cmdarg.push false }
1860
+ opt_block_param
1861
+ compstmt
1862
+ {
1863
+ line, _cmdarg, param, cmpstmt = val
1864
+
1865
+ result = new_do_body param, cmpstmt, line
1866
+ lexer.cmdarg.pop
1867
+ self.env.unextend
1868
+ }
1869
+
1870
+ case_args: arg_value
1871
+ {
1872
+ arg, = val
1873
+
1874
+ result = s(:array, arg).line arg.line
1875
+ }
1876
+ | tSTAR arg_value
1877
+ {
1878
+ _, arg = val
1879
+
1880
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1881
+ }
1882
+ | case_args tCOMMA arg_value
1883
+ {
1884
+ args, _, id = val
1885
+
1886
+ result = self.list_append args, id
1887
+ }
1888
+ | case_args tCOMMA tSTAR arg_value
1889
+ {
1890
+ args, _, _, id = val
1891
+
1892
+ result = self.list_append args, s(:splat, id).line(id.line)
1893
+ }
1894
+
1895
+ case_body: k_when
1896
+ {
1897
+ result = self.lexer.lineno
1898
+ }
1899
+ case_args then compstmt cases
1900
+ {
1901
+ result = new_when(val[2], val[4])
1902
+ result.line val[1]
1903
+ result << val[5] if val[5]
1904
+ }
1905
+
1906
+ cases: opt_else | case_body
1907
+
1908
+ opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
1909
+ {
1910
+ (_, line), klasses, var, _, body, rest = val
1911
+
1912
+ klasses ||= s(:array)
1913
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1914
+ klasses.line line
1915
+
1916
+ result = new_resbody(klasses, body)
1917
+ result << rest if rest # UGH, rewritten above
1918
+ }
1919
+ |
1920
+ {
1921
+ result = nil
1922
+ }
1923
+
1924
+ exc_list: arg_value
1925
+ {
1926
+ arg, = val
1927
+ result = s(:array, arg).line arg.line
1928
+ }
1929
+ | mrhs
1930
+ | none
1931
+
1932
+ exc_var: tASSOC lhs
1933
+ {
1934
+ result = val[1]
1935
+ }
1936
+ | none
1937
+
1938
+ opt_ensure: k_ensure compstmt
1939
+ {
1940
+ (_, line), body = val
1941
+
1942
+ result = body || s(:nil).line(line)
1943
+ }
1944
+ | none
1945
+
1946
+ literal: numeric
1947
+ {
1948
+ (lit, line), = val
1949
+ result = s(:lit, lit).line line
1950
+ }
1951
+ | symbol
1952
+
1953
+ strings: string
1954
+ {
1955
+ str, = val
1956
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
1957
+ result = str
1958
+ }
1959
+
1960
+ string: tCHAR
1961
+ {
1962
+ debug 37
1963
+ }
1964
+ | string1
1965
+ | string string1
1966
+ {
1967
+ result = self.literal_concat val[0], val[1]
1968
+ }
1969
+
1970
+ string1: tSTRING_BEG string_contents tSTRING_END
1971
+ {
1972
+ (_, line), str, (_, func) = val
1973
+
1974
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1975
+
1976
+ result = str.line line
1977
+ }
1978
+ | tSTRING
1979
+ {
1980
+ result = new_string val
1981
+ }
1982
+
1983
+ xstring: tXSTRING_BEG xstring_contents tSTRING_END
1984
+ {
1985
+ result = new_xstring val
1986
+ # TODO: dedent?!?! SERIOUSLY?!?
1987
+ }
1988
+
1989
+ regexp: tREGEXP_BEG regexp_contents tREGEXP_END
1990
+ {
1991
+ result = new_regexp val
1992
+ }
1993
+
1994
+ words: tWORDS_BEG tSPACE tSTRING_END
1995
+ {
1996
+ (_, line), _, _ = val
1997
+
1998
+ result = s(:array).line line
1999
+ }
2000
+ | tWORDS_BEG word_list tSTRING_END
2001
+ {
2002
+ (_, line), list, _ = val
2003
+
2004
+ result = list.line line
2005
+ }
2006
+
2007
+ word_list: none
2008
+ {
2009
+ result = new_word_list
2010
+ }
2011
+ | word_list word tSPACE
2012
+ {
2013
+ result = val[0].dup << new_word_list_entry(val)
2014
+ }
2015
+
2016
+ word: string_content
2017
+ | word string_content
2018
+ {
2019
+ result = self.literal_concat val[0], val[1]
2020
+ }
2021
+
2022
+ symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2023
+ {
2024
+ (_, line), _, _ = val
2025
+
2026
+ result = s(:array).line line
2027
+ }
2028
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2029
+ {
2030
+ (_, line), list, _, = val
2031
+ list.line line
2032
+ result = list
2033
+ }
2034
+
2035
+ symbol_list: none
2036
+ {
2037
+ result = new_symbol_list
2038
+ }
2039
+ | symbol_list word tSPACE
2040
+ {
2041
+ list, * = val
2042
+ result = list.dup << new_symbol_list_entry(val)
2043
+ }
2044
+
2045
+ qwords: tQWORDS_BEG tSPACE tSTRING_END
2046
+ {
2047
+ (_, line), _, _ = val
2048
+
2049
+ result = s(:array).line line
2050
+ }
2051
+ | tQWORDS_BEG qword_list tSTRING_END
2052
+ {
2053
+ (_, line), list, _ = val
2054
+
2055
+ result = list.line line
2056
+ }
2057
+
2058
+ qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2059
+ {
2060
+ (_, line), _, _ = val
2061
+
2062
+ result = s(:array).line line
2063
+ }
2064
+ | tQSYMBOLS_BEG qsym_list tSTRING_END
2065
+ {
2066
+ (_, line), list, _ = val
2067
+
2068
+ result = list.line line
2069
+ }
2070
+
2071
+ qword_list: none
2072
+ {
2073
+ result = new_qword_list
2074
+ }
2075
+ | qword_list tSTRING_CONTENT tSPACE
2076
+ {
2077
+ result = val[0].dup << new_qword_list_entry(val)
2078
+ }
2079
+
2080
+ qsym_list: none
2081
+ {
2082
+ result = new_qsym_list
2083
+ }
2084
+ | qsym_list tSTRING_CONTENT tSPACE
2085
+ {
2086
+ result = val[0].dup << new_qsym_list_entry(val)
2087
+ }
2088
+
2089
+ string_contents: none
2090
+ {
2091
+ line = prev_value_to_lineno _values.last
2092
+ result = s(:str, +"").line line
2093
+ }
2094
+ | string_contents string_content
2095
+ {
2096
+ v1, v2 = val
2097
+ result = literal_concat v1, v2
2098
+ }
2099
+
2100
+ xstring_contents: none
2101
+ {
2102
+ result = nil
2103
+ }
2104
+ | xstring_contents string_content
2105
+ {
2106
+ v1, v2 = val
2107
+ result = literal_concat v1, v2
2108
+ }
2109
+
2110
+ regexp_contents: none
2111
+ {
2112
+ result = nil
2113
+ }
2114
+ | regexp_contents string_content
2115
+ {
2116
+ v1, v2 = val
2117
+ result = literal_concat v1, v2
2118
+ }
2119
+
2120
+ string_content: tSTRING_CONTENT
2121
+ {
2122
+ result = new_string val
2123
+ }
2124
+ | tSTRING_DVAR
2125
+ {
2126
+ result = lexer.lex_strterm
2127
+
2128
+ lexer.lex_strterm = nil
2129
+ lexer.lex_state = EXPR_BEG
2130
+ }
2131
+ string_dvar
2132
+ {
2133
+ _, strterm, str = val
2134
+ lexer.lex_strterm = strterm
2135
+ result = s(:evstr, str).line str.line
2136
+ }
2137
+ | tSTRING_DBEG
2138
+ {
2139
+ result = [lexer.lex_strterm,
2140
+ lexer.brace_nest,
2141
+ lexer.string_nest, # TODO: remove
2142
+ lexer.lex_state,
2143
+ lexer.lineno,
2144
+ ]
2145
+
2146
+ lexer.cmdarg.push false
2147
+ lexer.cond.push false
2148
+
2149
+ lexer.lex_strterm = nil
2150
+ lexer.brace_nest = 0
2151
+ lexer.string_nest = 0
2152
+
2153
+ lexer.lex_state = EXPR_BEG
2154
+ }
2155
+ compstmt
2156
+ tSTRING_DEND
2157
+ {
2158
+ _, memo, stmt, _ = val
2159
+
2160
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2161
+ # TODO: heredoc_indent
2162
+
2163
+ lexer.lex_strterm = lex_strterm
2164
+ lexer.brace_nest = brace_nest
2165
+ lexer.string_nest = string_nest
2166
+
2167
+ lexer.cond.pop
2168
+ lexer.cmdarg.pop
2169
+
2170
+ lexer.lex_state = oldlex_state
2171
+
2172
+ case stmt
2173
+ when Sexp then
2174
+ case stmt.sexp_type
2175
+ when :str, :dstr, :evstr then
2176
+ result = stmt
2177
+ else
2178
+ result = s(:evstr, stmt).line line
2179
+ end
2180
+ when nil then
2181
+ result = s(:evstr).line line
2182
+ else
2183
+ debug 38
2184
+ raise "unknown string body: #{stmt.inspect}"
2185
+ end
2186
+ }
2187
+
2188
+ string_dvar: tGVAR
2189
+ {
2190
+ (id, line), = val
2191
+ result = s(:gvar, id.to_sym).line line
2192
+ }
2193
+ | tIVAR
2194
+ {
2195
+ (id, line), = val
2196
+ result = s(:ivar, id.to_sym).line line
2197
+ }
2198
+ | tCVAR
2199
+ {
2200
+ (id, line), = val
2201
+ result = s(:cvar, id.to_sym).line line
2202
+ }
2203
+ | backref
2204
+
2205
+ symbol: ssym
2206
+ | dsym
2207
+
2208
+ ssym: tSYMBEG sym
2209
+ {
2210
+ _, (id, line) = val
2211
+
2212
+ lexer.lex_state = EXPR_END
2213
+ result = s(:lit, id.to_sym).line line
2214
+ }
2215
+ | tSYMBOL
2216
+ {
2217
+ (id, line), = val
2218
+
2219
+ lexer.lex_state = EXPR_END
2220
+ result = s(:lit, id.to_sym).line line
2221
+ }
2222
+
2223
+ sym: fname | tIVAR | tGVAR | tCVAR
2224
+
2225
+ dsym: tSYMBEG string_contents tSTRING_END
2226
+ {
2227
+ _, result, _ = val
2228
+
2229
+ lexer.lex_state = EXPR_END
2230
+
2231
+ result ||= s(:str, "").line lexer.lineno
2232
+
2233
+ case result.sexp_type
2234
+ when :dstr then
2235
+ result.sexp_type = :dsym
2236
+ when :str then
2237
+ result = s(:lit, result.last.to_sym).line result.line
2238
+ when :evstr then
2239
+ result = s(:dsym, "", result).line result.line
2240
+ else
2241
+ debug 39
2242
+ end
2243
+ }
2244
+
2245
+ numeric: simple_numeric
2246
+ | tUMINUS_NUM simple_numeric =tLOWEST
2247
+ {
2248
+ _, (num, line) = val
2249
+ result = [-num, line]
2250
+ }
2251
+
2252
+ simple_numeric: tINTEGER
2253
+ | tFLOAT
2254
+ | tRATIONAL
2255
+ | tIMAGINARY
2256
+
2257
+ user_variable: tIDENTIFIER
2258
+ | tIVAR
2259
+ | tGVAR
2260
+ | tCONSTANT
2261
+ | tCVAR
2262
+
2263
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2264
+ | kSELF { result = s(:self).line lexer.lineno }
2265
+ | kTRUE { result = s(:true).line lexer.lineno }
2266
+ | kFALSE { result = s(:false).line lexer.lineno }
2267
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2268
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
2269
+ | k__ENCODING__
2270
+ {
2271
+ l = lexer.lineno
2272
+ result =
2273
+ if defined? Encoding then
2274
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2275
+ else
2276
+ s(:str, "Unsupported!").line l
2277
+ end
2278
+ }
2279
+
2280
+ var_ref: user_variable
2281
+ {
2282
+ raise "NO: #{val.inspect}" if Sexp === val.first
2283
+ (var, line), = val
2284
+ result = Sexp === var ? var : self.gettable(var)
2285
+ result.line line
2286
+ }
2287
+ | keyword_variable
2288
+ {
2289
+ var = val[0]
2290
+ result = Sexp === var ? var : self.gettable(var)
2291
+ }
2292
+
2293
+ var_lhs: user_variable
2294
+ {
2295
+ result = self.assignable val[0]
2296
+ }
2297
+ | keyword_variable
2298
+ {
2299
+ result = self.assignable val[0]
2300
+ debug 40
2301
+ }
2302
+
2303
+ backref: tNTH_REF
2304
+ {
2305
+ (ref, line), = val
2306
+ result = s(:nth_ref, ref).line line
2307
+ }
2308
+ | tBACK_REF
2309
+ {
2310
+ (ref, line), = val
2311
+ result = s(:back_ref, ref).line line
2312
+ }
2313
+
2314
+ superclass: tLT
2315
+ {
2316
+ lexer.lex_state = EXPR_BEG
2317
+ lexer.command_start = true
2318
+ }
2319
+ expr_value term
2320
+ {
2321
+ result = val[2]
2322
+ }
2323
+ | none
2324
+ {
2325
+ result = nil
2326
+ }
2327
+
2328
+ f_arglist: tLPAREN2 f_args rparen
2329
+ {
2330
+ result = end_args val
2331
+ }
2332
+ | {
2333
+ result = self.in_kwarg
2334
+ self.in_kwarg = true
2335
+ self.lexer.lex_state |= EXPR_LABEL
2336
+ }
2337
+ f_args term
2338
+ {
2339
+ result = end_args val
2340
+ }
2341
+
2342
+ args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
2343
+ {
2344
+ result = args val
2345
+ }
2346
+ | f_kwarg opt_f_block_arg
2347
+ {
2348
+ result = args val
2349
+ }
2350
+ | f_kwrest opt_f_block_arg
2351
+ {
2352
+ result = args val
2353
+ }
2354
+ | f_block_arg
2355
+
2356
+ opt_args_tail: tCOMMA args_tail
2357
+ {
2358
+ result = val[1]
2359
+ }
2360
+ |
2361
+ {
2362
+ result = nil
2363
+ }
2364
+
2365
+ f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail
2366
+ {
2367
+ result = args val
2368
+ }
2369
+ | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2370
+ {
2371
+ result = args val
2372
+ }
2373
+ | f_arg tCOMMA f_optarg opt_args_tail
2374
+ {
2375
+ result = args val
2376
+ }
2377
+ | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail
2378
+ {
2379
+ result = args val
2380
+ }
2381
+ | f_arg tCOMMA f_rest_arg opt_args_tail
2382
+ {
2383
+ result = args val
2384
+ }
2385
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2386
+ {
2387
+ result = args val
2388
+ }
2389
+ | f_arg opt_args_tail
2390
+ {
2391
+ result = args val
2392
+ }
2393
+ | f_optarg tCOMMA f_rest_arg opt_args_tail
2394
+ {
2395
+ result = args val
2396
+ }
2397
+ | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2398
+ {
2399
+ result = args val
2400
+ }
2401
+ | f_optarg opt_args_tail
2402
+ {
2403
+ result = args val
2404
+ }
2405
+ | f_optarg tCOMMA f_arg opt_args_tail
2406
+ {
2407
+ result = args val
2408
+ }
2409
+ | f_rest_arg opt_args_tail
2410
+ {
2411
+ result = args val
2412
+ }
2413
+ | f_rest_arg tCOMMA f_arg opt_args_tail
2414
+ {
2415
+ result = args val
2416
+ }
2417
+ | args_tail
2418
+ {
2419
+ result = args val
2420
+ }
2421
+ |
2422
+ {
2423
+ result = args val
2424
+ # result.line lexer.lineno
2425
+ }
2426
+
2427
+
2428
+ f_bad_arg: tCONSTANT
2429
+ {
2430
+ yyerror "formal argument cannot be a constant"
2431
+ }
2432
+ | tIVAR
2433
+ {
2434
+ yyerror "formal argument cannot be an instance variable"
2435
+ }
2436
+ | tGVAR
2437
+ {
2438
+ yyerror "formal argument cannot be a global variable"
2439
+ }
2440
+ | tCVAR
2441
+ {
2442
+ yyerror "formal argument cannot be a class variable"
2443
+ }
2444
+
2445
+ f_norm_arg: f_bad_arg
2446
+ | tIDENTIFIER
2447
+ {
2448
+ (id, line), = val
2449
+ identifier = id.to_sym
2450
+ self.env[identifier] = :lvar
2451
+
2452
+ result = [identifier, line]
2453
+ }
2454
+
2455
+ f_arg_asgn: f_norm_arg
2456
+
2457
+ f_arg_item: f_arg_asgn
2458
+ | tLPAREN f_margs rparen
2459
+ {
2460
+ _, margs, _ = val
2461
+
2462
+ result = margs
2463
+ }
2464
+
2465
+ f_arg: f_arg_item
2466
+ {
2467
+ result = new_arg val
2468
+ }
2469
+ | f_arg tCOMMA f_arg_item
2470
+ {
2471
+ list, _, item = val
2472
+
2473
+ if list.sexp_type == :args then
2474
+ result = list
2475
+ else
2476
+ result = s(:args, list).line list.line
2477
+ end
2478
+
2479
+ result << (Sexp === item ? item : item.first)
2480
+ }
2481
+
2482
+ f_label: tLABEL
2483
+
2484
+ f_kw: f_label arg_value
2485
+ {
2486
+ # TODO: new_kw_arg
2487
+ (label, line), arg = val
2488
+
2489
+ identifier = label.to_sym
2490
+ self.env[identifier] = :lvar
2491
+
2492
+ kwarg = s(:kwarg, identifier, arg).line line
2493
+ result = s(:array, kwarg).line line
2494
+ }
2495
+ | f_label
2496
+ {
2497
+ (label, line), = val
2498
+
2499
+ id = label.to_sym
2500
+ self.env[id] = :lvar
2501
+
2502
+ result = s(:array, s(:kwarg, id).line(line)).line line
2503
+ }
2504
+
2505
+ f_block_kw: f_label primary_value
2506
+ {
2507
+ # TODO: new_kw_arg
2508
+ (label, line), expr = val
2509
+ id = label.to_sym
2510
+ self.env[id] = :lvar
2511
+
2512
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
2513
+ }
2514
+ | f_label
2515
+ {
2516
+ # TODO: new_kw_arg
2517
+ (label, line), = val
2518
+ id = label.to_sym
2519
+ self.env[id] = :lvar
2520
+
2521
+ result = s(:array, s(:kwarg, id).line(line)).line line
2522
+ }
2523
+
2524
+ f_block_kwarg: f_block_kw
2525
+ | f_block_kwarg tCOMMA f_block_kw
2526
+ {
2527
+ list, _, item = val
2528
+ result = list << item.last
2529
+ }
2530
+
2531
+ f_kwarg: f_kw
2532
+ | f_kwarg tCOMMA f_kw
2533
+ {
2534
+ result = args val
2535
+ }
2536
+
2537
+ kwrest_mark: tPOW
2538
+ | tDSTAR
2539
+
2540
+
2541
+ f_kwrest: kwrest_mark tIDENTIFIER
2542
+ {
2543
+ _, (id, line) = val
2544
+
2545
+ name = id.to_sym
2546
+ self.assignable [name, line]
2547
+ result = [:"**#{name}", line]
2548
+ }
2549
+ | kwrest_mark
2550
+ {
2551
+ id = :"**"
2552
+ self.env[id] = :lvar # TODO: needed?!?
2553
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2554
+ }
2555
+
2556
+ f_opt: f_arg_asgn tEQL arg_value
2557
+ {
2558
+ lhs, _, rhs = val
2559
+ result = self.assignable lhs, rhs
2560
+ # TODO: detect duplicate names
2561
+ }
2562
+
2563
+ f_block_opt: f_arg_asgn tEQL primary_value
2564
+ {
2565
+ lhs, _, rhs = val
2566
+ result = self.assignable lhs, rhs
2567
+ }
2568
+
2569
+ f_block_optarg: f_block_opt
2570
+ {
2571
+ optblk, = val
2572
+ result = s(:block, optblk).line optblk.line
2573
+ }
2574
+ | f_block_optarg tCOMMA f_block_opt
2575
+ {
2576
+ optarg, _, optblk = val
2577
+ result = optarg
2578
+ result << optblk
2579
+ }
2580
+
2581
+ f_optarg: f_opt
2582
+ {
2583
+ opt, = val
2584
+ result = s(:block, opt).line opt.line
2585
+ }
2586
+ | f_optarg tCOMMA f_opt
2587
+ {
2588
+ result = self.block_append val[0], val[2]
2589
+ }
2590
+
2591
+ restarg_mark: tSTAR2 | tSTAR
2592
+
2593
+ f_rest_arg: restarg_mark tIDENTIFIER
2594
+ {
2595
+ # TODO: differs from parse.y - needs tests
2596
+ _, (id, line) = val
2597
+ name = id.to_sym
2598
+ self.assignable [name, line]
2599
+ result = [:"*#{name}", line]
2600
+ }
2601
+ | restarg_mark
2602
+ {
2603
+ name = :"*"
2604
+ self.env[name] = :lvar
2605
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2606
+ }
2607
+
2608
+ blkarg_mark: tAMPER2 | tAMPER
2609
+
2610
+ f_block_arg: blkarg_mark tIDENTIFIER
2611
+ {
2612
+ _, (id, line) = val
2613
+ identifier = id.to_sym
2614
+
2615
+ self.env[identifier] = :lvar
2616
+ result = ["&#{identifier}".to_sym, line]
2617
+ }
2618
+
2619
+ opt_f_block_arg: tCOMMA f_block_arg
2620
+ {
2621
+ _, arg = val
2622
+ result = arg
2623
+ }
2624
+ |
2625
+ {
2626
+ result = nil
2627
+ }
2628
+
2629
+ singleton: var_ref
2630
+ | tLPAREN2
2631
+ {
2632
+ lexer.lex_state = EXPR_BEG
2633
+ }
2634
+ expr rparen
2635
+ {
2636
+ result = val[2]
2637
+ yyerror "Can't define single method for literals." if
2638
+ result.sexp_type == :lit
2639
+ }
2640
+
2641
+ assoc_list: none
2642
+ {
2643
+ result = s(:array).line lexer.lineno
2644
+ }
2645
+ | assocs trailer
2646
+
2647
+ assocs: assoc
2648
+ | assocs tCOMMA assoc
2649
+ {
2650
+ list = val[0].dup
2651
+ more = val[2].sexp_body
2652
+ list.push(*more) unless more.empty?
2653
+ result = list
2654
+ result.sexp_type = :hash
2655
+ }
2656
+
2657
+ assoc: arg_value tASSOC arg_value
2658
+ {
2659
+ v1, _, v2 = val
2660
+ result = s(:array, v1, v2).line v1.line
2661
+ }
2662
+ | tLABEL arg_value
2663
+ {
2664
+ (label, line), arg = val
2665
+
2666
+ lit = s(:lit, label.to_sym).line line
2667
+ result = s(:array, lit, arg).line line
2668
+ }
2669
+ | tSTRING_BEG string_contents tLABEL_END arg_value
2670
+ {
2671
+ (_, line), sym, _, value = val
2672
+
2673
+ sym.sexp_type = :dsym
2674
+
2675
+ result = s(:array, sym, value).line line
2676
+ }
2677
+ | tDSTAR arg_value
2678
+ {
2679
+ _, arg = val
2680
+ line = arg.line
2681
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
2682
+ }
2683
+
2684
+ operation: tIDENTIFIER | tCONSTANT | tFID
2685
+ operation2: tIDENTIFIER | tCONSTANT | tFID | op
2686
+ operation3: tIDENTIFIER | tFID | op
2687
+ dot_or_colon: tDOT | tCOLON2
2688
+ call_op: tDOT
2689
+
2690
+ call_op2: call_op
2691
+ | tCOLON2
2692
+
2693
+ opt_terms: | terms
2694
+ opt_nl: | tNL
2695
+ rparen: opt_nl tRPAREN
2696
+ rbracket: opt_nl tRBRACK
2697
+ trailer: | tNL | tCOMMA
2698
+
2699
+ term: tSEMI { yyerrok }
2700
+ | tNL
2701
+
2702
+ terms: term
2703
+ | terms tSEMI { yyerrok }
2704
+
2705
+ none: { result = nil; }
2706
+ end
2707
+
2708
+ ---- inner
2709
+
2710
+ require "ruby_lexer"
2711
+ require "ruby_parser_extras"
2712
+ include RubyLexer::State::Values
2713
+
2714
+ # :stopdoc:
2715
+
2716
+ # Local Variables: **
2717
+ # racc-token-length-max:14 **
2718
+ # End: **