summaryrefslogtreecommitdiff
path: root/test/racc/assets/ruby22.y
diff options
context:
space:
mode:
Diffstat (limited to 'test/racc/assets/ruby22.y')
-rw-r--r--test/racc/assets/ruby22.y2381
1 files changed, 2381 insertions, 0 deletions
diff --git a/test/racc/assets/ruby22.y b/test/racc/assets/ruby22.y
new file mode 100644
index 0000000000..751c0e866b
--- /dev/null
+++ b/test/racc/assets/ruby22.y
@@ -0,0 +1,2381 @@
+# Copyright (c) 2013 Peter Zotov <whitequark@whitequark.org>
+#
+# Parts of the source are derived from ruby_parser:
+# Copyright (c) Ryan Davis, seattle.rb
+#
+# MIT License
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+class Parser::Ruby22
+
+token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
+ kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
+ kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
+ kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
+ kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
+ k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
+ tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
+ tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
+ tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
+ tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
+ tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
+ tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
+ tDSTAR tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
+ tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT
+ tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DBEG
+ tSTRING_DVAR tSTRING_END tSTRING_DEND tSTRING tSYMBOL
+ tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG tCHARACTER
+ tRATIONAL tIMAGINARY tLABEL_END
+
+prechigh
+ right tBANG tTILDE tUPLUS
+ right tPOW
+ right tUMINUS_NUM tUMINUS
+ left tSTAR2 tDIVIDE tPERCENT
+ left tPLUS tMINUS
+ left tLSHFT tRSHFT
+ left tAMPER2
+ left tPIPE tCARET
+ left tGT tGEQ tLT tLEQ
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
+ left tANDOP
+ left tOROP
+ nonassoc tDOT2 tDOT3
+ right tEH tCOLON
+ left kRESCUE_MOD
+ right tEQL tOP_ASGN
+ nonassoc kDEFINED
+ right kNOT
+ left kOR kAND
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
+ nonassoc tLBRACE_ARG
+ nonassoc tLOWEST
+preclow
+
+rule
+
+ program: top_compstmt
+
+ top_compstmt: top_stmts opt_terms
+ {
+ result = @builder.compstmt(val[0])
+ }
+
+ top_stmts: # nothing
+ {
+ result = []
+ }
+ | top_stmt
+ {
+ result = [ val[0] ]
+ }
+ | top_stmts terms top_stmt
+ {
+ result = val[0] << val[2]
+ }
+ | error top_stmt
+ {
+ result = [ val[1] ]
+ }
+
+ top_stmt: stmt
+ | klBEGIN tLCURLY top_compstmt tRCURLY
+ {
+ result = @builder.preexe(val[0], val[1], val[2], val[3])
+ }
+
+ bodystmt: compstmt opt_rescue opt_else opt_ensure
+ {
+ rescue_bodies = val[1]
+ else_t, else_ = val[2]
+ ensure_t, ensure_ = val[3]
+
+ if rescue_bodies.empty? && !else_.nil?
+ diagnostic :warning, :useless_else, nil, else_t
+ end
+
+ result = @builder.begin_body(val[0],
+ rescue_bodies,
+ else_t, else_,
+ ensure_t, ensure_)
+ }
+
+ compstmt: stmts opt_terms
+ {
+ result = @builder.compstmt(val[0])
+ }
+
+ stmts: # nothing
+ {
+ result = []
+ }
+ | stmt_or_begin
+ {
+ result = [ val[0] ]
+ }
+ | stmts terms stmt_or_begin
+ {
+ result = val[0] << val[2]
+ }
+ | error stmt
+ {
+ result = [ val[1] ]
+ }
+
+ stmt_or_begin: stmt
+ | klBEGIN tLCURLY top_compstmt tRCURLY
+ {
+ diagnostic :error, :begin_in_method, nil, val[0]
+ }
+
+ stmt: kALIAS fitem
+ {
+ @lexer.state = :expr_fname
+ }
+ fitem
+ {
+ result = @builder.alias(val[0], val[1], val[3])
+ }
+ | kALIAS tGVAR tGVAR
+ {
+ result = @builder.alias(val[0],
+ @builder.gvar(val[1]),
+ @builder.gvar(val[2]))
+ }
+ | kALIAS tGVAR tBACK_REF
+ {
+ result = @builder.alias(val[0],
+ @builder.gvar(val[1]),
+ @builder.back_ref(val[2]))
+ }
+ | kALIAS tGVAR tNTH_REF
+ {
+ diagnostic :error, :nth_ref_alias, nil, val[2]
+ }
+ | kUNDEF undef_list
+ {
+ result = @builder.undef_method(val[0], val[1])
+ }
+ | stmt kIF_MOD expr_value
+ {
+ result = @builder.condition_mod(val[0], nil,
+ val[1], val[2])
+ }
+ | stmt kUNLESS_MOD expr_value
+ {
+ result = @builder.condition_mod(nil, val[0],
+ val[1], val[2])
+ }
+ | stmt kWHILE_MOD expr_value
+ {
+ result = @builder.loop_mod(:while, val[0], val[1], val[2])
+ }
+ | stmt kUNTIL_MOD expr_value
+ {
+ result = @builder.loop_mod(:until, val[0], val[1], val[2])
+ }
+ | stmt kRESCUE_MOD stmt
+ {
+ rescue_body = @builder.rescue_body(val[1],
+ nil, nil, nil,
+ nil, val[2])
+
+ result = @builder.begin_body(val[0], [ rescue_body ])
+ }
+ | klEND tLCURLY compstmt tRCURLY
+ {
+ result = @builder.postexe(val[0], val[1], val[2], val[3])
+ }
+ | command_asgn
+ | mlhs tEQL command_call
+ {
+ result = @builder.multi_assign(val[0], val[1], val[2])
+ }
+ | var_lhs tOP_ASGN command_call
+ {
+ result = @builder.op_assign(val[0], val[1], val[2])
+ }
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call
+ {
+ result = @builder.op_assign(
+ @builder.index(
+ val[0], val[1], val[2], val[3]),
+ val[4], val[5])
+ }
+ | primary_value tDOT tIDENTIFIER tOP_ASGN command_call
+ {
+ result = @builder.op_assign(
+ @builder.call_method(
+ val[0], val[1], val[2]),
+ val[3], val[4])
+ }
+ | primary_value tDOT tCONSTANT tOP_ASGN command_call
+ {
+ result = @builder.op_assign(
+ @builder.call_method(
+ val[0], val[1], val[2]),
+ val[3], val[4])
+ }
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
+ {
+ result = @builder.op_assign(
+ @builder.call_method(
+ val[0], val[1], val[2]),
+ val[3], val[4])
+ }
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
+ {
+ result = @builder.op_assign(
+ @builder.call_method(
+ val[0], val[1], val[2]),
+ val[3], val[4])
+ }
+ | backref tOP_ASGN command_call
+ {
+ @builder.op_assign(val[0], val[1], val[2])
+ }
+ | lhs tEQL mrhs
+ {
+ result = @builder.assign(val[0], val[1],
+ @builder.array(nil, val[2], nil))
+ }
+ | mlhs tEQL mrhs_arg
+ {
+ result = @builder.multi_assign(val[0], val[1], val[2])
+ }
+ | expr
+
+ command_asgn: lhs tEQL command_call
+ {
+ result = @builder.assign(val[0], val[1], val[2])
+ }
+ | lhs tEQL command_asgn
+ {
+ result = @builder.assign(val[0], val[1], val[2])
+ }
+
+ expr: command_call
+ | expr kAND expr
+ {
+ result = @builder.logical_op(:and, val[0], val[1], val[2])
+ }
+ | expr kOR expr
+ {
+ result = @builder.logical_op(:or, val[0], val[1], val[2])
+ }
+ | kNOT opt_nl expr
+ {
+ result = @builder.not_op(val[0], nil, val[2], nil)
+ }
+ | tBANG command_call
+ {
+ result = @builder.not_op(val[0], nil, val[1], nil)
+ }
+ | arg
+
+ expr_value: expr
+
+ command_call: command
+ | block_command
+
+ block_command: block_call
+ | block_call dot_or_colon operation2 command_args
+ {
+ result = @builder.call_method(val[0], val[1], val[2],
+ nil, val[3], nil)
+ }
+
+ cmd_brace_block: tLBRACE_ARG
+ {
+ @static_env.extend_dynamic
+ }
+ opt_block_param compstmt tRCURLY
+ {
+ result = [ val[0], val[2], val[3], val[4] ]
+
+ @static_env.unextend
+ }
+
+ fcall: operation
+
+ command: fcall command_args =tLOWEST
+ {
+ result = @builder.call_method(nil, nil, val[0],
+ nil, val[1], nil)
+ }
+ | fcall command_args cmd_brace_block
+ {
+ method_call = @builder.call_method(nil, nil, val[0],
+ nil, val[1], nil)
+
+ begin_t, args, body, end_t = val[2]
+ result = @builder.block(method_call,
+ begin_t, args, body, end_t)
+ }
+ | primary_value tDOT operation2 command_args =tLOWEST
+ {
+ result = @builder.call_method(val[0], val[1], val[2],
+ nil, val[3], nil)
+ }
+ | primary_value tDOT operation2 command_args cmd_brace_block
+ {
+ method_call = @builder.call_method(val[0], val[1], val[2],
+ nil, val[3], nil)
+
+ begin_t, args, body, end_t = val[4]
+ result = @builder.block(method_call,
+ begin_t, args, body, end_t)
+ }
+ | primary_value tCOLON2 operation2 command_args =tLOWEST
+ {
+ result = @builder.call_method(val[0], val[1], val[2],
+ nil, val[3], nil)
+ }
+ | primary_value tCOLON2 operation2 command_args cmd_brace_block
+ {
+ method_call = @builder.call_method(val[0], val[1], val[2],
+ nil, val[3], nil)
+
+ begin_t, args, body, end_t = val[4]
+ result = @builder.block(method_call,
+ begin_t, args, body, end_t)
+ }
+ | kSUPER command_args
+ {
+ result = @builder.keyword_cmd(:super, val[0],
+ nil, val[1], nil)
+ }
+ | kYIELD command_args
+ {
+ result = @builder.keyword_cmd(:yield, val[0],
+ nil, val[1], nil)
+ }
+ | kRETURN call_args
+ {
+ result = @builder.keyword_cmd(:return, val[0],
+ nil, val[1], nil)
+ }
+ | kBREAK call_args
+ {
+ result = @builder.keyword_cmd(:break, val[0],
+ nil, val[1], nil)
+ }
+ | kNEXT call_args
+ {
+ result = @builder.keyword_cmd(:next, val[0],
+ nil, val[1], nil)
+ }
+
+ mlhs: mlhs_basic
+ {
+ result = @builder.multi_lhs(nil, val[0], nil)
+ }
+ | tLPAREN mlhs_inner rparen
+ {
+ result = @builder.begin(val[0], val[1], val[2])
+ }
+
+ mlhs_inner: mlhs_basic
+ {
+ result = @builder.multi_lhs(nil, val[0], nil)
+ }
+ | tLPAREN mlhs_inner rparen
+ {
+ result = @builder.multi_lhs(val[0], val[1], val[2])
+ }
+
+ mlhs_basic: mlhs_head
+ | mlhs_head mlhs_item
+ {
+ result = val[0].
+ push(val[1])
+ }
+ | mlhs_head tSTAR mlhs_node
+ {
+ result = val[0].
+ push(@builder.splat(val[1], val[2]))
+ }
+ | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
+ {
+ result = val[0].
+ push(@builder.splat(val[1], val[2])).
+ concat(val[4])
+ }
+ | mlhs_head tSTAR
+ {
+ result = val[0].
+ push(@builder.splat(val[1]))
+ }
+ | mlhs_head tSTAR tCOMMA mlhs_post
+ {
+ result = val[0].
+ push(@builder.splat(val[1])).
+ concat(val[3])
+ }
+ | tSTAR mlhs_node
+ {
+ result = [ @builder.splat(val[0], val[1]) ]
+ }
+ | tSTAR mlhs_node tCOMMA mlhs_post
+ {
+ result = [ @builder.splat(val[0], val[1]),
+ *val[3] ]
+ }
+ | tSTAR
+ {
+ result = [ @builder.splat(val[0]) ]
+ }
+ | tSTAR tCOMMA mlhs_post
+ {
+ result = [ @builder.splat(val[0]),
+ *val[2] ]
+ }
+
+ mlhs_item: mlhs_node
+ | tLPAREN mlhs_inner rparen
+ {
+ result = @builder.begin(val[0], val[1], val[2])
+ }
+
+ mlhs_head: mlhs_item tCOMMA
+ {
+ result = [ val[0] ]
+ }
+ | mlhs_head mlhs_item tCOMMA
+ {
+ result = val[0] << val[1]
+ }
+
+ mlhs_post: mlhs_item
+ {
+ result = [ val[0] ]
+ }
+ | mlhs_post tCOMMA mlhs_item
+ {
+ result = val[0] << val[2]
+ }
+
+ mlhs_node: user_variable
+ {
+ result = @builder.assignable(val[0])
+ }
+ | keyword_variable
+ {
+ result = @builder.assignable(val[0])
+ }
+ | primary_value tLBRACK2 opt_call_args rbracket
+ {
+ result = @builder.index_asgn(val[0], val[1], val[2], val[3])
+ }
+ | primary_value tDOT tIDENTIFIER
+ {
+ result = @builder.attr_asgn(val[0], val[1], val[2])
+ }
+ | primary_value tCOLON2 tIDENTIFIER
+ {
+ result = @builder.attr_asgn(val[0], val[1], val[2])
+ }
+ | primary_value tDOT tCONSTANT
+ {
+ result = @builder.attr_asgn(val[0], val[1], val[2])
+ }
+ | primary_value tCOLON2 tCONSTANT
+ {
+ result = @builder.assignable(
+ @builder.const_fetch(val[0], val[1], val[2]))
+ }
+ | tCOLON3 tCONSTANT
+ {
+ result = @builder.assignable(
+ @builder.const_global(val[0], val[1]))
+ }
+ | backref
+ {
+ result = @builder.assignable(val[0])
+ }
+
+ lhs: user_variable
+ {
+ result = @builder.assignable(val[0])
+ }
+ | keyword_variable
+ {
+ result = @builder.assignable(val[0])
+ }
+ | primary_value tLBRACK2 opt_call_args rbracket
+ {
+ result = @builder.index_asgn(val[0], val[1], val[2], val[3])
+ }
+ | primary_value tDOT tIDENTIFIER
+ {
+ result = @builder.attr_asgn(val[0], val[1], val[2])
+ }
+ | primary_value tCOLON2 tIDENTIFIER
+ {
+ result = @builder.attr_asgn(val[0], val[1], val[2])
+ }
+ | primary_value tDOT tCONSTANT
+ {
+ result = @builder.attr_asgn(val[0], val[1], val[2])
+ }
+ | primary_value tCOLON2 tCONSTANT
+ {
+ result = @builder.assignable(
+ @builder.const_fetch(val[0], val[1], val[2]))
+ }
+ | tCOLON3 tCONSTANT
+ {
+ result = @builder.assignable(
+ @builder.const_global(val[0], val[1]))
+ }
+ | backref
+ {
+ result = @builder.assignable(val[0])
+ }
+
+ cname: tIDENTIFIER
+ {
+ diagnostic :error, :module_name_const, nil, val[0]
+ }
+ | tCONSTANT
+
+ cpath: tCOLON3 cname
+ {
+ result = @builder.const_global(val[0], val[1])
+ }
+ | cname
+ {
+ result = @builder.const(val[0])
+ }
+ | primary_value tCOLON2 cname
+ {
+ result = @builder.const_fetch(val[0], val[1], val[2])
+ }
+
+ fname: tIDENTIFIER | tCONSTANT | tFID
+ | op
+ | reswords
+
+ fsym: fname
+ {
+ result = @builder.symbol(val[0])
+ }
+ | symbol
+
+ fitem: fsym
+ | dsym
+
+ undef_list: fitem
+ {
+ result = [ val[0] ]
+ }
+ | undef_list tCOMMA
+ {
+ @lexer.state = :expr_fname
+ }
+ fitem
+ {
+ result = val[0] << val[3]
+ }
+
+ op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
+ | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ
+ | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
+ | tSTAR | tDIVIDE | tPERCENT | tPOW | tBANG | tTILDE
+ | tUPLUS | tUMINUS | tAREF | tASET | tDSTAR | tBACK_REF2
+
+ reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
+ | kALIAS | kAND | kBEGIN | kBREAK | kCASE
+ | kCLASS | kDEF | kDEFINED | kDO | kELSE
+ | kELSIF | kEND | kENSURE | kFALSE | kFOR
+ | kIN | kMODULE | kNEXT | kNIL | kNOT
+ | kOR | kREDO | kRESCUE | kRETRY | kRETURN
+ | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF
+ | kWHEN | kYIELD | kIF | kUNLESS | kWHILE
+ | kUNTIL
+
+ arg: lhs tEQL arg
+ {
+ result = @builder.assign(val[0], val[1], val[2])
+ }
+ | lhs tEQL arg kRESCUE_MOD arg
+ {
+ rescue_body = @builder.rescue_body(val[3],
+ nil, nil, nil,
+ nil, val[4])
+
+ rescue_ = @builder.begin_body(val[2], [ rescue_body ])
+
+ result = @builder.assign(val[0], val[1], rescue_)
+ }
+ | var_lhs tOP_ASGN arg
+ {
+ result = @builder.op_assign(val[0], val[1], val[2])
+ }
+ | var_lhs tOP_ASGN arg kRESCUE_MOD arg
+ {
+ rescue_body = @builder.rescue_body(val[3],
+ nil, nil, nil,
+ nil, val[4])
+
+ rescue_ = @builder.begin_body(val[2], [ rescue_body ])
+
+ result = @builder.op_assign(val[0], val[1], rescue_)
+ }
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg
+ {
+ result = @builder.op_assign(
+ @builder.index(
+ val[0], val[1], val[2], val[3]),
+ val[4], val[5])
+ }
+ | primary_value tDOT tIDENTIFIER tOP_ASGN arg
+ {
+ result = @builder.op_assign(
+ @builder.call_method(
+ val[0], val[1], val[2]),
+ val[3], val[4])
+ }
+ | primary_value tDOT tCONSTANT tOP_ASGN arg
+ {
+ result = @builder.op_assign(
+ @builder.call_method(
+ val[0], val[1], val[2]),
+ val[3], val[4])
+ }
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
+ {
+ result = @builder.op_assign(
+ @builder.call_method(
+ val[0], val[1], val[2]),
+ val[3], val[4])
+ }
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
+ {
+ const = @builder.const_op_assignable(
+ @builder.const_fetch(val[0], val[1], val[2]))
+ result = @builder.op_assign(const, val[3], val[4])
+ }
+ | tCOLON3 tCONSTANT tOP_ASGN arg
+ {
+ const = @builder.const_op_assignable(
+ @builder.const_global(val[0], val[1]))
+ result = @builder.op_assign(const, val[2], val[3])
+ }
+ | backref tOP_ASGN arg
+ {
+ result = @builder.op_assign(val[0], val[1], val[2])
+ }
+ | arg tDOT2 arg
+ {
+ result = @builder.range_inclusive(val[0], val[1], val[2])
+ }
+ | arg tDOT3 arg
+ {
+ result = @builder.range_exclusive(val[0], val[1], val[2])
+ }
+ | arg tPLUS arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tMINUS arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tSTAR2 arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tDIVIDE arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tPERCENT arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tPOW arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | tUMINUS_NUM simple_numeric tPOW arg
+ {
+ result = @builder.unary_op(val[0],
+ @builder.binary_op(
+ val[1], val[2], val[3]))
+ }
+ | tUPLUS arg
+ {
+ result = @builder.unary_op(val[0], val[1])
+ }
+ | tUMINUS arg
+ {
+ result = @builder.unary_op(val[0], val[1])
+ }
+ | arg tPIPE arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tCARET arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tAMPER2 arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tCMP arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tGT arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tGEQ arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tLT arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tLEQ arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tEQ arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tEQQ arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tNEQ arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tMATCH arg
+ {
+ result = @builder.match_op(val[0], val[1], val[2])
+ }
+ | arg tNMATCH arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | tBANG arg
+ {
+ result = @builder.not_op(val[0], nil, val[1], nil)
+ }
+ | tTILDE arg
+ {
+ result = @builder.unary_op(val[0], val[1])
+ }
+ | arg tLSHFT arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tRSHFT arg
+ {
+ result = @builder.binary_op(val[0], val[1], val[2])
+ }
+ | arg tANDOP arg
+ {
+ result = @builder.logical_op(:and, val[0], val[1], val[2])
+ }
+ | arg tOROP arg
+ {
+ result = @builder.logical_op(:or, val[0], val[1], val[2])
+ }
+ | kDEFINED opt_nl arg
+ {
+ result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil)
+ }
+
+ # Note: MRI eventually came to rely on disambiguation based on
+ # the lexer state, but it is too contrived with the Ragel lexer,
+ # so we kept this approach. See ruby/ruby@b0c03f63e5 for
+ # the initial commit, and ruby/ruby@23352f62a for MRI revert,
+ # which we decided not to track.
+ | arg tEH
+ {
+ @lexer.push_cond
+ @lexer.cond.push(true)
+ }
+ arg opt_nl tCOLON
+ {
+ @lexer.pop_cond
+ }
+ arg
+ {
+ result = @builder.ternary(val[0], val[1],
+ val[3], val[5], val[7])
+ }
+ | primary
+
+ arg_value: arg
+
+ aref_args: none
+ | args trailer
+ | args tCOMMA assocs trailer
+ {
+ result = val[0] << @builder.associate(nil, val[2], nil)
+ }
+ | assocs trailer
+ {
+ result = [ @builder.associate(nil, val[0], nil) ]
+ }
+
+ paren_args: tLPAREN2 opt_call_args rparen
+ {
+ result = val
+ }
+
+ opt_paren_args: # nothing
+ {
+ result = [ nil, [], nil ]
+ }
+ | paren_args
+
+ opt_call_args: # nothing
+ {
+ result = []
+ }
+ | call_args
+ | args tCOMMA
+ | args tCOMMA assocs tCOMMA
+ {
+ result = val[0] << @builder.associate(nil, val[2], nil)
+ }
+ | assocs tCOMMA
+ {
+ result = [ @builder.associate(nil, val[0], nil) ]
+ }
+
+ call_args: command
+ {
+ result = [ val[0] ]
+ }
+ | args opt_block_arg
+ {
+ result = val[0].concat(val[1])
+ }
+ | assocs opt_block_arg
+ {
+ result = [ @builder.associate(nil, val[0], nil) ]
+ result.concat(val[1])
+ }
+ | args tCOMMA assocs opt_block_arg
+ {
+ assocs = @builder.associate(nil, val[2], nil)
+ result = val[0] << assocs
+ result.concat(val[3])
+ }
+ | block_arg
+ {
+ result = [ val[0] ]
+ }
+
+ command_args: {
+ result = @lexer.cmdarg.dup
+ @lexer.cmdarg.push(true)
+ }
+ call_args
+ {
+ @lexer.cmdarg = val[0]
+
+ result = val[1]
+ }
+
+ block_arg: tAMPER arg_value
+ {
+ result = @builder.block_pass(val[0], val[1])
+ }
+
+ opt_block_arg: tCOMMA block_arg
+ {
+ result = [ val[1] ]
+ }
+ | # nothing
+ {
+ result = []
+ }
+
+ args: arg_value
+ {
+ result = [ val[0] ]
+ }
+ | tSTAR arg_value
+ {
+ result = [ @builder.splat(val[0], val[1]) ]
+ }
+ | args tCOMMA arg_value
+ {
+ result = val[0] << val[2]
+ }
+ | args tCOMMA tSTAR arg_value
+ {
+ result = val[0] << @builder.splat(val[2], val[3])
+ }
+
+ mrhs_arg: mrhs
+ {
+ result = @builder.array(nil, val[0], nil)
+ }
+ | arg_value
+
+ mrhs: args tCOMMA arg_value
+ {
+ result = val[0] << val[2]
+ }
+ | args tCOMMA tSTAR arg_value
+ {
+ result = val[0] << @builder.splat(val[2], val[3])
+ }
+ | tSTAR arg_value
+ {
+ result = [ @builder.splat(val[0], val[1]) ]
+ }
+
+ primary: literal
+ | strings
+ | xstring
+ | regexp
+ | words
+ | qwords
+ | symbols
+ | qsymbols
+ | var_ref
+ | backref
+ | tFID
+ {
+ result = @builder.call_method(nil, nil, val[0])
+ }
+ | kBEGIN
+ {
+ result = @lexer.cmdarg.dup
+ @lexer.cmdarg.clear
+ }
+ bodystmt kEND
+ {
+ @lexer.cmdarg = val[1]
+
+ result = @builder.begin_keyword(val[0], val[2], val[3])
+ }
+ | tLPAREN_ARG
+ {
+ result = @lexer.cmdarg.dup
+ @lexer.cmdarg.clear
+ }
+ expr
+ {
+ @lexer.state = :expr_endarg
+ }
+ opt_nl tRPAREN
+ {
+ @lexer.cmdarg = val[1]
+
+ result = @builder.begin(val[0], val[2], val[5])
+ }
+ | tLPAREN_ARG
+ {
+ @lexer.state = :expr_endarg
+ }
+ opt_nl tRPAREN
+ {
+ result = @builder.begin(val[0], nil, val[3])
+ }
+ | tLPAREN compstmt tRPAREN
+ {
+ result = @builder.begin(val[0], val[1], val[2])
+ }
+ | primary_value tCOLON2 tCONSTANT
+ {
+ result = @builder.const_fetch(val[0], val[1], val[2])
+ }
+ | tCOLON3 tCONSTANT
+ {
+ result = @builder.const_global(val[0], val[1])
+ }
+ | tLBRACK aref_args tRBRACK
+ {
+ result = @builder.array(val[0], val[1], val[2])
+ }
+ | tLBRACE assoc_list tRCURLY
+ {
+ result = @builder.associate(val[0], val[1], val[2])
+ }
+ | kRETURN
+ {
+ result = @builder.keyword_cmd(:return, val[0])
+ }
+ | kYIELD tLPAREN2 call_args rparen
+ {
+ result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3])
+ }
+ | kYIELD tLPAREN2 rparen
+ {
+ result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2])
+ }
+ | kYIELD
+ {
+ result = @builder.keyword_cmd(:yield, val[0])
+ }
+ | kDEFINED opt_nl tLPAREN2 expr rparen
+ {
+ result = @builder.keyword_cmd(:defined?, val[0],
+ val[2], [ val[3] ], val[4])
+ }
+ | kNOT tLPAREN2 expr rparen
+ {
+ result = @builder.not_op(val[0], val[1], val[2], val[3])
+ }
+ | kNOT tLPAREN2 rparen
+ {
+ result = @builder.not_op(val[0], val[1], nil, val[2])
+ }
+ | fcall brace_block
+ {
+ method_call = @builder.call_method(nil, nil, val[0])
+
+ begin_t, args, body, end_t = val[1]
+ result = @builder.block(method_call,
+ begin_t, args, body, end_t)
+ }
+ | method_call
+ | method_call brace_block
+ {
+ begin_t, args, body, end_t = val[1]
+ result = @builder.block(val[0],
+ begin_t, args, body, end_t)
+ }
+ | tLAMBDA lambda
+ {
+ lambda_call = @builder.call_lambda(val[0])
+
+ args, (begin_t, body, end_t) = val[1]
+ result = @builder.block(lambda_call,
+ begin_t, args, body, end_t)
+ }
+ | kIF expr_value then compstmt if_tail kEND
+ {
+ else_t, else_ = val[4]
+ result = @builder.condition(val[0], val[1], val[2],
+ val[3], else_t,
+ else_, val[5])
+ }
+ | kUNLESS expr_value then compstmt opt_else kEND
+ {
+ else_t, else_ = val[4]
+ result = @builder.condition(val[0], val[1], val[2],
+ else_, else_t,
+ val[3], val[5])
+ }
+ | kWHILE
+ {
+ @lexer.cond.push(true)
+ }
+ expr_value do
+ {
+ @lexer.cond.pop
+ }
+ compstmt kEND
+ {
+ result = @builder.loop(:while, val[0], val[2], val[3],
+ val[5], val[6])
+ }
+ | kUNTIL
+ {
+ @lexer.cond.push(true)
+ }
+ expr_value do
+ {
+ @lexer.cond.pop
+ }
+ compstmt kEND
+ {
+ result = @builder.loop(:until, val[0], val[2], val[3],
+ val[5], val[6])
+ }
+ | kCASE expr_value opt_terms case_body kEND
+ {
+ *when_bodies, (else_t, else_body) = *val[3]
+
+ result = @builder.case(val[0], val[1],
+ when_bodies, else_t, else_body,
+ val[4])
+ }
+ | kCASE opt_terms case_body kEND
+ {
+ *when_bodies, (else_t, else_body) = *val[2]
+
+ result = @builder.case(val[0], nil,
+ when_bodies, else_t, else_body,
+ val[3])
+ }
+ | kFOR for_var kIN
+ {
+ @lexer.cond.push(true)
+ }
+ expr_value do
+ {
+ @lexer.cond.pop
+ }
+ compstmt kEND
+ {
+ result = @builder.for(val[0], val[1],
+ val[2], val[4],
+ val[5], val[7], val[8])
+ }
+ | kCLASS cpath superclass
+ {
+ @static_env.extend_static
+ @lexer.push_cmdarg
+ }
+ bodystmt kEND
+ {
+ if in_def?
+ diagnostic :error, :class_in_def, nil, val[0]
+ end
+
+ lt_t, superclass = val[2]
+ result = @builder.def_class(val[0], val[1],
+ lt_t, superclass,
+ val[4], val[5])
+
+ @lexer.pop_cmdarg
+ @static_env.unextend
+ }
+ | kCLASS tLSHFT expr term
+ {
+ result = @def_level
+ @def_level = 0
+
+ @static_env.extend_static
+ @lexer.push_cmdarg
+ }
+ bodystmt kEND
+ {
+ result = @builder.def_sclass(val[0], val[1], val[2],
+ val[5], val[6])
+
+ @lexer.pop_cmdarg
+ @static_env.unextend
+
+ @def_level = val[4]
+ }
+ | kMODULE cpath
+ {
+ @static_env.extend_static
+ @lexer.push_cmdarg
+ }
+ bodystmt kEND
+ {
+ if in_def?
+ diagnostic :error, :module_in_def, nil, val[0]
+ end
+
+ result = @builder.def_module(val[0], val[1],
+ val[3], val[4])
+
+ @lexer.pop_cmdarg
+ @static_env.unextend
+ }
+ | kDEF fname
+ {
+ @def_level += 1
+ @static_env.extend_static
+ @lexer.push_cmdarg
+ }
+ f_arglist bodystmt kEND
+ {
+ result = @builder.def_method(val[0], val[1],
+ val[3], val[4], val[5])
+
+ @lexer.pop_cmdarg
+ @static_env.unextend
+ @def_level -= 1
+ }
+ | kDEF singleton dot_or_colon
+ {
+ @lexer.state = :expr_fname
+ }
+ fname
+ {
+ @def_level += 1
+ @static_env.extend_static
+ @lexer.push_cmdarg
+ }
+ f_arglist bodystmt kEND
+ {
+ result = @builder.def_singleton(val[0], val[1], val[2],
+ val[4], val[6], val[7], val[8])
+
+ @lexer.pop_cmdarg
+ @static_env.unextend
+ @def_level -= 1
+ }
+ | kBREAK
+ {
+ result = @builder.keyword_cmd(:break, val[0])
+ }
+ | kNEXT
+ {
+ result = @builder.keyword_cmd(:next, val[0])
+ }
+ | kREDO
+ {
+ result = @builder.keyword_cmd(:redo, val[0])
+ }
+ | kRETRY
+ {
+ result = @builder.keyword_cmd(:retry, val[0])
+ }
+
+ primary_value: primary
+
+ then: term
+ | kTHEN
+ | term kTHEN
+ {
+ result = val[1]
+ }
+
+ do: term
+ | kDO_COND
+
+ if_tail: opt_else
+ | kELSIF expr_value then compstmt if_tail
+ {
+ else_t, else_ = val[4]
+ result = [ val[0],
+ @builder.condition(val[0], val[1], val[2],
+ val[3], else_t,
+ else_, nil),
+ ]
+ }
+
+ opt_else: none
+ | kELSE compstmt
+ {
+ result = val
+ }
+
+ for_var: lhs
+ | mlhs
+
+ f_marg: f_norm_arg
+ {
+ result = @builder.arg(val[0])
+ }
+ | tLPAREN f_margs rparen
+ {
+ result = @builder.multi_lhs(val[0], val[1], val[2])
+ }
+
+ f_marg_list: f_marg
+ {
+ result = [ val[0] ]
+ }
+ | f_marg_list tCOMMA f_marg
+ {
+ result = val[0] << val[2]
+ }
+
+ f_margs: f_marg_list
+ | f_marg_list tCOMMA tSTAR f_norm_arg
+ {
+ result = val[0].
+ push(@builder.restarg(val[2], val[3]))
+ }
+ | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
+ {
+ result = val[0].
+ push(@builder.restarg(val[2], val[3])).
+ concat(val[5])
+ }
+ | f_marg_list tCOMMA tSTAR
+ {
+ result = val[0].
+ push(@builder.restarg(val[2]))
+ }
+ | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
+ {
+ result = val[0].
+ push(@builder.restarg(val[2])).
+ concat(val[4])
+ }
+ | tSTAR f_norm_arg
+ {
+ result = [ @builder.restarg(val[0], val[1]) ]
+ }
+ | tSTAR f_norm_arg tCOMMA f_marg_list
+ {
+ result = [ @builder.restarg(val[0], val[1]),
+ *val[3] ]
+ }
+ | tSTAR
+ {
+ result = [ @builder.restarg(val[0]) ]
+ }
+ | tSTAR tCOMMA f_marg_list
+ {
+ result = [ @builder.restarg(val[0]),
+ *val[2] ]
+ }
+
+ block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
+ {
+ result = val[0].concat(val[2]).concat(val[3])
+ }
+ | f_block_kwarg opt_f_block_arg
+ {
+ result = val[0].concat(val[1])
+ }
+ | f_kwrest opt_f_block_arg
+ {
+ result = val[0].concat(val[1])
+ }
+ | f_block_arg
+ {
+ result = [ val[0] ]
+ }
+
+opt_block_args_tail:
+ tCOMMA block_args_tail
+ {
+ result = val[1]
+ }
+ | # nothing
+ {
+ result = []
+ }
+
+ block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[5])
+ }
+ | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[6]).
+ concat(val[7])
+ }
+ | f_arg tCOMMA f_block_optarg opt_block_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[5])
+ }
+ | f_arg tCOMMA f_rest_arg opt_block_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_arg tCOMMA
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[5])
+ }
+ | f_arg opt_block_args_tail
+ {
+ result = val[0].concat(val[1])
+ }
+ | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[5])
+ }
+ | f_block_optarg opt_block_args_tail
+ {
+ result = val[0].
+ concat(val[1])
+ }
+ | f_block_optarg tCOMMA f_arg opt_block_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_rest_arg opt_block_args_tail
+ {
+ result = val[0].
+ concat(val[1])
+ }
+ | f_rest_arg tCOMMA f_arg opt_block_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | block_args_tail
+
+ opt_block_param: # nothing
+ {
+ result = @builder.args(nil, [], nil)
+ }
+ | block_param_def
+ {
+ @lexer.state = :expr_value
+ }
+
+ block_param_def: tPIPE opt_bv_decl tPIPE
+ {
+ result = @builder.args(val[0], val[1], val[2])
+ }
+ | tOROP
+ {
+ result = @builder.args(val[0], [], val[0])
+ }
+ | tPIPE block_param opt_bv_decl tPIPE
+ {
+ result = @builder.args(val[0], val[1].concat(val[2]), val[3])
+ }
+
+ opt_bv_decl: opt_nl
+ {
+ result = []
+ }
+ | opt_nl tSEMI bv_decls opt_nl
+ {
+ result = val[2]
+ }
+
+ bv_decls: bvar
+ {
+ result = [ val[0] ]
+ }
+ | bv_decls tCOMMA bvar
+ {
+ result = val[0] << val[2]
+ }
+
+ bvar: tIDENTIFIER
+ {
+ result = @builder.shadowarg(val[0])
+ }
+ | f_bad_arg
+
+ lambda: {
+ @static_env.extend_dynamic
+ }
+ f_larglist
+ {
+ result = @lexer.cmdarg.dup
+ @lexer.cmdarg.clear
+ }
+ lambda_body
+ {
+ @lexer.cmdarg = val[2]
+ @lexer.cmdarg.lexpop
+
+ result = [ val[1], val[3] ]
+
+ @static_env.unextend
+ }
+
+ f_larglist: tLPAREN2 f_args opt_bv_decl tRPAREN
+ {
+ result = @builder.args(val[0], val[1].concat(val[2]), val[3])
+ }
+ | f_args
+ {
+ result = @builder.args(nil, val[0], nil)
+ }
+
+ lambda_body: tLAMBEG compstmt tRCURLY
+ {
+ result = [ val[0], val[1], val[2] ]
+ }
+ | kDO_LAMBDA compstmt kEND
+ {
+ result = [ val[0], val[1], val[2] ]
+ }
+
+ do_block: kDO_BLOCK
+ {
+ @static_env.extend_dynamic
+ }
+ opt_block_param compstmt kEND
+ {
+ result = [ val[0], val[2], val[3], val[4] ]
+
+ @static_env.unextend
+ }
+
+ block_call: command do_block
+ {
+ begin_t, block_args, body, end_t = val[1]
+ result = @builder.block(val[0],
+ begin_t, block_args, body, end_t)
+ }
+ | block_call dot_or_colon operation2 opt_paren_args
+ {
+ lparen_t, args, rparen_t = val[3]
+ result = @builder.call_method(val[0], val[1], val[2],
+ lparen_t, args, rparen_t)
+ }
+ | block_call dot_or_colon operation2 opt_paren_args brace_block
+ {
+ lparen_t, args, rparen_t = val[3]
+ method_call = @builder.call_method(val[0], val[1], val[2],
+ lparen_t, args, rparen_t)
+
+ begin_t, args, body, end_t = val[4]
+ result = @builder.block(method_call,
+ begin_t, args, body, end_t)
+ }
+ | block_call dot_or_colon operation2 command_args do_block
+ {
+ method_call = @builder.call_method(val[0], val[1], val[2],
+ nil, val[3], nil)
+
+ begin_t, args, body, end_t = val[4]
+ result = @builder.block(method_call,
+ begin_t, args, body, end_t)
+ }
+
+ method_call: fcall paren_args
+ {
+ lparen_t, args, rparen_t = val[1]
+ result = @builder.call_method(nil, nil, val[0],
+ lparen_t, args, rparen_t)
+ }
+ | primary_value tDOT operation2 opt_paren_args
+ {
+ lparen_t, args, rparen_t = val[3]
+ result = @builder.call_method(val[0], val[1], val[2],
+ lparen_t, args, rparen_t)
+ }
+ | primary_value tCOLON2 operation2 paren_args
+ {
+ lparen_t, args, rparen_t = val[3]
+ result = @builder.call_method(val[0], val[1], val[2],
+ lparen_t, args, rparen_t)
+ }
+ | primary_value tCOLON2 operation3
+ {
+ result = @builder.call_method(val[0], val[1], val[2])
+ }
+ | primary_value tDOT paren_args
+ {
+ lparen_t, args, rparen_t = val[2]
+ result = @builder.call_method(val[0], val[1], nil,
+ lparen_t, args, rparen_t)
+ }
+ | primary_value tCOLON2 paren_args
+ {
+ lparen_t, args, rparen_t = val[2]
+ result = @builder.call_method(val[0], val[1], nil,
+ lparen_t, args, rparen_t)
+ }
+ | kSUPER paren_args
+ {
+ lparen_t, args, rparen_t = val[1]
+ result = @builder.keyword_cmd(:super, val[0],
+ lparen_t, args, rparen_t)
+ }
+ | kSUPER
+ {
+ result = @builder.keyword_cmd(:zsuper, val[0])
+ }
+ | primary_value tLBRACK2 opt_call_args rbracket
+ {
+ result = @builder.index(val[0], val[1], val[2], val[3])
+ }
+
+ brace_block: tLCURLY
+ {
+ @static_env.extend_dynamic
+ }
+ opt_block_param compstmt tRCURLY
+ {
+ result = [ val[0], val[2], val[3], val[4] ]
+
+ @static_env.unextend
+ }
+ | kDO
+ {
+ @static_env.extend_dynamic
+ }
+ opt_block_param compstmt kEND
+ {
+ result = [ val[0], val[2], val[3], val[4] ]
+
+ @static_env.unextend
+ }
+
+ case_body: kWHEN args then compstmt cases
+ {
+ result = [ @builder.when(val[0], val[1], val[2], val[3]),
+ *val[4] ]
+ }
+
+ cases: opt_else
+ {
+ result = [ val[0] ]
+ }
+ | case_body
+
+ opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
+ {
+ assoc_t, exc_var = val[2]
+
+ if val[1]
+ exc_list = @builder.array(nil, val[1], nil)
+ end
+
+ result = [ @builder.rescue_body(val[0],
+ exc_list, assoc_t, exc_var,
+ val[3], val[4]),
+ *val[5] ]
+ }
+ |
+ {
+ result = []
+ }
+
+ exc_list: arg_value
+ {
+ result = [ val[0] ]
+ }
+ | mrhs
+ | none
+
+ exc_var: tASSOC lhs
+ {
+ result = [ val[0], val[1] ]
+ }
+ | none
+
+ opt_ensure: kENSURE compstmt
+ {
+ result = [ val[0], val[1] ]
+ }
+ | none
+
+ literal: numeric
+ | symbol
+ | dsym
+
+ strings: string
+ {
+ result = @builder.string_compose(nil, val[0], nil)
+ }
+
+ string: string1
+ {
+ result = [ val[0] ]
+ }
+ | string string1
+ {
+ result = val[0] << val[1]
+ }
+
+ string1: tSTRING_BEG string_contents tSTRING_END
+ {
+ result = @builder.string_compose(val[0], val[1], val[2])
+ }
+ | tSTRING
+ {
+ result = @builder.string(val[0])
+ }
+ | tCHARACTER
+ {
+ result = @builder.character(val[0])
+ }
+
+ xstring: tXSTRING_BEG xstring_contents tSTRING_END
+ {
+ result = @builder.xstring_compose(val[0], val[1], val[2])
+ }
+
+ regexp: tREGEXP_BEG regexp_contents tSTRING_END tREGEXP_OPT
+ {
+ opts = @builder.regexp_options(val[3])
+ result = @builder.regexp_compose(val[0], val[1], val[2], opts)
+ }
+
+ words: tWORDS_BEG word_list tSTRING_END
+ {
+ result = @builder.words_compose(val[0], val[1], val[2])
+ }
+
+ word_list: # nothing
+ {
+ result = []
+ }
+ | word_list word tSPACE
+ {
+ result = val[0] << @builder.word(val[1])
+ }
+
+ word: string_content
+ {
+ result = [ val[0] ]
+ }
+ | word string_content
+ {
+ result = val[0] << val[1]
+ }
+
+ symbols: tSYMBOLS_BEG symbol_list tSTRING_END
+ {
+ result = @builder.symbols_compose(val[0], val[1], val[2])
+ }
+
+ symbol_list: # nothing
+ {
+ result = []
+ }
+ | symbol_list word tSPACE
+ {
+ result = val[0] << @builder.word(val[1])
+ }
+
+ qwords: tQWORDS_BEG qword_list tSTRING_END
+ {
+ result = @builder.words_compose(val[0], val[1], val[2])
+ }
+
+ qsymbols: tQSYMBOLS_BEG qsym_list tSTRING_END
+ {
+ result = @builder.symbols_compose(val[0], val[1], val[2])
+ }
+
+ qword_list: # nothing
+ {
+ result = []
+ }
+ | qword_list tSTRING_CONTENT tSPACE
+ {
+ result = val[0] << @builder.string_internal(val[1])
+ }
+
+ qsym_list: # nothing
+ {
+ result = []
+ }
+ | qsym_list tSTRING_CONTENT tSPACE
+ {
+ result = val[0] << @builder.symbol_internal(val[1])
+ }
+
+ string_contents: # nothing
+ {
+ result = []
+ }
+ | string_contents string_content
+ {
+ result = val[0] << val[1]
+ }
+
+xstring_contents: # nothing
+ {
+ result = []
+ }
+ | xstring_contents string_content
+ {
+ result = val[0] << val[1]
+ }
+
+regexp_contents: # nothing
+ {
+ result = []
+ }
+ | regexp_contents string_content
+ {
+ result = val[0] << val[1]
+ }
+
+ string_content: tSTRING_CONTENT
+ {
+ result = @builder.string_internal(val[0])
+ }
+ | tSTRING_DVAR string_dvar
+ {
+ result = val[1]
+ }
+ | tSTRING_DBEG
+ {
+ @lexer.cond.push(false)
+ @lexer.cmdarg.push(false)
+ }
+ compstmt tSTRING_DEND
+ {
+ @lexer.cond.lexpop
+ @lexer.cmdarg.lexpop
+
+ result = @builder.begin(val[0], val[2], val[3])
+ }
+
+ string_dvar: tGVAR
+ {
+ result = @builder.gvar(val[0])
+ }
+ | tIVAR
+ {
+ result = @builder.ivar(val[0])
+ }
+ | tCVAR
+ {
+ result = @builder.cvar(val[0])
+ }
+ | backref
+
+
+ symbol: tSYMBOL
+ {
+ result = @builder.symbol(val[0])
+ }
+
+ dsym: tSYMBEG xstring_contents tSTRING_END
+ {
+ result = @builder.symbol_compose(val[0], val[1], val[2])
+ }
+
+ numeric: simple_numeric
+ {
+ result = val[0]
+ }
+ | tUMINUS_NUM simple_numeric =tLOWEST
+ {
+ result = @builder.negate(val[0], val[1])
+ }
+
+ simple_numeric: tINTEGER
+ {
+ result = @builder.integer(val[0])
+ }
+ | tFLOAT
+ {
+ result = @builder.float(val[0])
+ }
+ | tRATIONAL
+ {
+ result = @builder.rational(val[0])
+ }
+ | tIMAGINARY
+ {
+ result = @builder.complex(val[0])
+ }
+
+ user_variable: tIDENTIFIER
+ {
+ result = @builder.ident(val[0])
+ }
+ | tIVAR
+ {
+ result = @builder.ivar(val[0])
+ }
+ | tGVAR
+ {
+ result = @builder.gvar(val[0])
+ }
+ | tCONSTANT
+ {
+ result = @builder.const(val[0])
+ }
+ | tCVAR
+ {
+ result = @builder.cvar(val[0])
+ }
+
+keyword_variable: kNIL
+ {
+ result = @builder.nil(val[0])
+ }
+ | kSELF
+ {
+ result = @builder.self(val[0])
+ }
+ | kTRUE
+ {
+ result = @builder.true(val[0])
+ }
+ | kFALSE
+ {
+ result = @builder.false(val[0])
+ }
+ | k__FILE__
+ {
+ result = @builder.__FILE__(val[0])
+ }
+ | k__LINE__
+ {
+ result = @builder.__LINE__(val[0])
+ }
+ | k__ENCODING__
+ {
+ result = @builder.__ENCODING__(val[0])
+ }
+
+ var_ref: user_variable
+ {
+ result = @builder.accessible(val[0])
+ }
+ | keyword_variable
+ {
+ result = @builder.accessible(val[0])
+ }
+
+ var_lhs: user_variable
+ {
+ result = @builder.assignable(val[0])
+ }
+ | keyword_variable
+ {
+ result = @builder.assignable(val[0])
+ }
+
+ backref: tNTH_REF
+ {
+ result = @builder.nth_ref(val[0])
+ }
+ | tBACK_REF
+ {
+ result = @builder.back_ref(val[0])
+ }
+
+ superclass: term
+ {
+ result = nil
+ }
+ | tLT
+ {
+ @lexer.state = :expr_value
+ }
+ expr_value term
+ {
+ result = [ val[0], val[2] ]
+ }
+ | error term
+ {
+ yyerrok
+ result = nil
+ }
+
+ f_arglist: tLPAREN2 f_args rparen
+ {
+ result = @builder.args(val[0], val[1], val[2])
+
+ @lexer.state = :expr_value
+ }
+ | {
+ result = @lexer.in_kwarg
+ @lexer.in_kwarg = true
+ }
+ f_args term
+ {
+ @lexer.in_kwarg = val[0]
+ result = @builder.args(nil, val[1], nil)
+ }
+
+ args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
+ {
+ result = val[0].concat(val[2]).concat(val[3])
+ }
+ | f_kwarg opt_f_block_arg
+ {
+ result = val[0].concat(val[1])
+ }
+ | f_kwrest opt_f_block_arg
+ {
+ result = val[0].concat(val[1])
+ }
+ | f_block_arg
+ {
+ result = [ val[0] ]
+ }
+
+ opt_args_tail: tCOMMA args_tail
+ {
+ result = val[1]
+ }
+ | # nothing
+ {
+ result = []
+ }
+
+ f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[5])
+ }
+ | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[6]).
+ concat(val[7])
+ }
+ | f_arg tCOMMA f_optarg opt_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[5])
+ }
+ | f_arg tCOMMA f_rest_arg opt_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[5])
+ }
+ | f_arg opt_args_tail
+ {
+ result = val[0].
+ concat(val[1])
+ }
+ | f_optarg tCOMMA f_rest_arg opt_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[5])
+ }
+ | f_optarg opt_args_tail
+ {
+ result = val[0].
+ concat(val[1])
+ }
+ | f_optarg tCOMMA f_arg opt_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_rest_arg opt_args_tail
+ {
+ result = val[0].
+ concat(val[1])
+ }
+ | f_rest_arg tCOMMA f_arg opt_args_tail
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | args_tail
+ {
+ result = val[0]
+ }
+ | # nothing
+ {
+ result = []
+ }
+
+ f_bad_arg: tCONSTANT
+ {
+ diagnostic :error, :argument_const, nil, val[0]
+ }
+ | tIVAR
+ {
+ diagnostic :error, :argument_ivar, nil, val[0]
+ }
+ | tGVAR
+ {
+ diagnostic :error, :argument_gvar, nil, val[0]
+ }
+ | tCVAR
+ {
+ diagnostic :error, :argument_cvar, nil, val[0]
+ }
+
+ f_norm_arg: f_bad_arg
+ | tIDENTIFIER
+ {
+ @static_env.declare val[0][0]
+
+ result = val[0]
+ }
+
+ f_arg_asgn: f_norm_arg
+ {
+ result = val[0]
+ }
+
+ f_arg_item: f_arg_asgn
+ {
+ result = @builder.arg(val[0])
+ }
+ | tLPAREN f_margs rparen
+ {
+ result = @builder.multi_lhs(val[0], val[1], val[2])
+ }
+
+ f_arg: f_arg_item
+ {
+ result = [ val[0] ]
+ }
+ | f_arg tCOMMA f_arg_item
+ {
+ result = val[0] << val[2]
+ }
+
+ f_label: tLABEL
+ {
+ check_kwarg_name(val[0])
+
+ @static_env.declare val[0][0]
+
+ result = val[0]
+ }
+
+ f_kw: f_label arg_value
+ {
+ result = @builder.kwoptarg(val[0], val[1])
+ }
+ | f_label
+ {
+ result = @builder.kwarg(val[0])
+ }
+
+ f_block_kw: f_label primary_value
+ {
+ result = @builder.kwoptarg(val[0], val[1])
+ }
+ | f_label
+ {
+ result = @builder.kwarg(val[0])
+ }
+
+ f_block_kwarg: f_block_kw
+ {
+ result = [ val[0] ]
+ }
+ | f_block_kwarg tCOMMA f_block_kw
+ {
+ result = val[0] << val[2]
+ }
+
+ f_kwarg: f_kw
+ {
+ result = [ val[0] ]
+ }
+ | f_kwarg tCOMMA f_kw
+ {
+ result = val[0] << val[2]
+ }
+
+ kwrest_mark: tPOW | tDSTAR
+
+ f_kwrest: kwrest_mark tIDENTIFIER
+ {
+ @static_env.declare val[1][0]
+
+ result = [ @builder.kwrestarg(val[0], val[1]) ]
+ }
+ | kwrest_mark
+ {
+ result = [ @builder.kwrestarg(val[0]) ]
+ }
+
+ f_opt: f_arg_asgn tEQL arg_value
+ {
+ result = @builder.optarg(val[0], val[1], val[2])
+ }
+
+ f_block_opt: f_arg_asgn tEQL primary_value
+ {
+ result = @builder.optarg(val[0], val[1], val[2])
+ }
+
+ f_block_optarg: f_block_opt
+ {
+ result = [ val[0] ]
+ }
+ | f_block_optarg tCOMMA f_block_opt
+ {
+ result = val[0] << val[2]
+ }
+
+ f_optarg: f_opt
+ {
+ result = [ val[0] ]
+ }
+ | f_optarg tCOMMA f_opt
+ {
+ result = val[0] << val[2]
+ }
+
+ restarg_mark: tSTAR2 | tSTAR
+
+ f_rest_arg: restarg_mark tIDENTIFIER
+ {
+ @static_env.declare val[1][0]
+
+ result = [ @builder.restarg(val[0], val[1]) ]
+ }
+ | restarg_mark
+ {
+ result = [ @builder.restarg(val[0]) ]
+ }
+
+ blkarg_mark: tAMPER2 | tAMPER
+
+ f_block_arg: blkarg_mark tIDENTIFIER
+ {
+ @static_env.declare val[1][0]
+
+ result = @builder.blockarg(val[0], val[1])
+ }
+
+ opt_f_block_arg: tCOMMA f_block_arg
+ {
+ result = [ val[1] ]
+ }
+ |
+ {
+ result = []
+ }
+
+ singleton: var_ref
+ | tLPAREN2 expr rparen
+ {
+ result = val[1]
+ }
+
+ assoc_list: # nothing
+ {
+ result = []
+ }
+ | assocs trailer
+
+ assocs: assoc
+ {
+ result = [ val[0] ]
+ }
+ | assocs tCOMMA assoc
+ {
+ result = val[0] << val[2]
+ }
+
+ assoc: arg_value tASSOC arg_value
+ {
+ result = @builder.pair(val[0], val[1], val[2])
+ }
+ | tLABEL arg_value
+ {
+ result = @builder.pair_keyword(val[0], val[1])
+ }
+ | tSTRING_BEG string_contents tLABEL_END arg_value
+ {
+ result = @builder.pair_quoted(val[0], val[1], val[2], val[3])
+ }
+ | tDSTAR arg_value
+ {
+ result = @builder.kwsplat(val[0], val[1])
+ }
+
+ operation: tIDENTIFIER | tCONSTANT | tFID
+ operation2: tIDENTIFIER | tCONSTANT | tFID | op
+ operation3: tIDENTIFIER | tFID | op
+ dot_or_colon: tDOT | tCOLON2
+ opt_terms: | terms
+ opt_nl: | tNL
+ rparen: opt_nl tRPAREN
+ {
+ result = val[1]
+ }
+ rbracket: opt_nl tRBRACK
+ {
+ result = val[1]
+ }
+ trailer: | tNL | tCOMMA
+
+ term: tSEMI
+ {
+ yyerrok
+ }
+ | tNL
+
+ terms: term
+ | terms tSEMI
+
+ none: # nothing
+ {
+ result = nil
+ }
+end
+
+---- header
+
+require 'parser'
+
+Parser.check_for_encoding_support
+
+---- inner
+
+ def version
+ 22
+ end
+
+ def default_encoding
+ Encoding::UTF_8
+ end