aboutsummaryrefslogtreecommitdiffstats
path: root/test/racc/assets/macruby.y
diff options
context:
space:
mode:
Diffstat (limited to 'test/racc/assets/macruby.y')
-rw-r--r--test/racc/assets/macruby.y2197
1 files changed, 2197 insertions, 0 deletions
diff --git a/test/racc/assets/macruby.y b/test/racc/assets/macruby.y
new file mode 100644
index 0000000000..5ede008308
--- /dev/null
+++ b/test/racc/assets/macruby.y
@@ -0,0 +1,2197 @@
+# 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::MacRuby
+
+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
+ tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
+ tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT
+ tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
+ tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG
+ tCHARACTER
+
+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
+ {
+ result = [ val[0] ]
+ }
+ | stmts terms stmt
+ {
+ result = val[0] << val[2]
+ }
+ | error stmt
+ {
+ result = [ val[1] ]
+ }
+
+ 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])
+ }
+ | lhs tEQL command_call
+ {
+ result = @builder.assign(val[0], val[1], val[2])
+ }
+ | 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 arg_value
+ {
+ result = @builder.multi_assign(val[0], val[1], val[2])
+ }
+ | mlhs tEQL mrhs
+ {
+ result = @builder.multi_assign(val[0], val[1],
+ @builder.array(nil, val[2], nil))
+ }
+ | expr
+
+ 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 tDOT operation2 command_args
+ {
+ result = @builder.call_method(val[0], val[1], val[2],
+ *val[3])
+ }
+ | block_call tCOLON2 operation2 command_args
+ {
+ result = @builder.call_method(val[0], val[1], val[2],
+ *val[3])
+ }
+
+ 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
+ }
+
+ command: operation command_args =tLOWEST
+ {
+ result = @builder.call_method(nil, nil, val[0],
+ *val[1])
+ }
+ | operation command_args cmd_brace_block
+ {
+ method_call = @builder.call_method(nil, nil, val[0],
+ *val[1])
+
+ 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],
+ *val[3])
+ }
+ | primary_value tDOT operation2 command_args cmd_brace_block
+ {
+ method_call = @builder.call_method(val[0], val[1], val[2],
+ *val[3])
+
+ 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],
+ *val[3])
+ }
+ | primary_value tCOLON2 operation2 command_args cmd_brace_block
+ {
+ method_call = @builder.call_method(val[0], val[1], val[2],
+ *val[3])
+
+ 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],
+ *val[1])
+ }
+ | kYIELD command_args
+ {
+ result = @builder.keyword_cmd(:yield, val[0],
+ *val[1])
+ }
+ | 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: 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: 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 | 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
+ {
+ diagnostic :error, :dynamic_const, nil, val[2], [ val[3] ]
+ }
+ | tCOLON3 tCONSTANT tOP_ASGN arg
+ {
+ diagnostic :error, :dynamic_const, nil, val[1], [ val[2] ]
+ }
+ | 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 tINTEGER tPOW arg
+ {
+ result = @builder.unary_op(val[0],
+ @builder.binary_op(
+ @builder.integer(val[1]),
+ val[2], val[3]))
+ }
+ | tUMINUS_NUM tFLOAT tPOW arg
+ {
+ result = @builder.unary_op(val[0],
+ @builder.binary_op(
+ @builder.float(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)
+ }
+
+ | arg tEH arg opt_nl tCOLON arg
+ {
+ result = @builder.ternary(val[0], val[1],
+ val[2], val[4], val[5])
+ }
+ | 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
+
+ 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])
+ }
+ | args tCOMMA assocs tCOMMA args opt_block_arg
+ {
+ val[2][-1] = @builder.objc_varargs(val[2][-1], val[4])
+ assocs = @builder.associate(nil, val[2], nil)
+ result = val[0] << assocs
+ result.concat(val[5])
+ }
+ | block_arg
+ {
+ result = [ val[0] ]
+ }
+
+ call_args2: arg_value tCOMMA args opt_block_arg
+ {
+ result = [ val[0], *val[2].concat(val[3]) ]
+ }
+ | arg_value tCOMMA block_arg
+ {
+ result = [ val[0], val[2] ]
+ }
+ | assocs opt_block_arg
+ {
+ result = [ @builder.associate(nil, val[0], nil),
+ *val[1] ]
+ }
+ | arg_value tCOMMA assocs opt_block_arg
+ {
+ result = [ val[0],
+ @builder.associate(nil, val[2], nil),
+ *val[3] ]
+ }
+ | arg_value tCOMMA args tCOMMA assocs opt_block_arg
+ {
+ result = [ val[0],
+ *val[2].
+ push(@builder.associate(nil, val[4], nil)).
+ concat(val[5]) ]
+ }
+ | block_arg
+ {
+ result = [ val[0] ]
+ }
+
+ command_args: {
+ result = @lexer.cmdarg.dup
+ @lexer.cmdarg.push(true)
+ }
+ open_args
+ {
+ @lexer.cmdarg = val[0]
+
+ result = val[1]
+ }
+
+ open_args: call_args
+ {
+ result = [ nil, val[0], nil ]
+ }
+ | tLPAREN_ARG
+ {
+ @lexer.state = :expr_endarg
+ }
+ rparen
+ {
+ result = [ val[0], [], val[2] ]
+ }
+ | tLPAREN_ARG call_args2
+ {
+ @lexer.state = :expr_endarg
+ }
+ rparen
+ {
+ result = [ val[0], val[1], val[3] ]
+ }
+
+ block_arg: tAMPER arg_value
+ {
+ result = @builder.block_pass(val[0], val[1])
+ }
+
+ opt_block_arg: tCOMMA block_arg
+ {
+ result = [ val[1] ]
+ }
+ | tCOMMA
+ {
+ result = []
+ }
+ | # 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: 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
+ | var_ref
+ | backref
+ | tFID
+ {
+ result = @builder.call_method(nil, nil, val[0])
+ }
+ | kBEGIN bodystmt kEND
+ {
+ result = @builder.begin_keyword(val[0], val[1], val[2])
+ }
+ | tLPAREN_ARG expr
+ {
+ @lexer.state = :expr_endarg
+ }
+ rparen
+ {
+ result = @builder.begin(val[0], val[1], 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])
+ }
+ | operation 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
+ | 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.objc_restarg(val[2], val[3]))
+ }
+ | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
+ {
+ result = val[0].
+ push(@builder.objc_restarg(val[2], val[3])).
+ concat(val[5])
+ }
+ | f_marg_list tCOMMA tSTAR
+ {
+ result = val[0].
+ push(@builder.objc_restarg(val[2]))
+ }
+ | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
+ {
+ result = val[0].
+ push(@builder.objc_restarg(val[2])).
+ concat(val[4])
+ }
+ | tSTAR f_norm_arg
+ {
+ result = [ @builder.objc_restarg(val[0], val[1]) ]
+ }
+ | tSTAR f_norm_arg tCOMMA f_marg_list
+ {
+ result = [ @builder.objc_restarg(val[0], val[1]),
+ *val[3] ]
+ }
+ | tSTAR
+ {
+ result = [ @builder.objc_restarg(val[0]) ]
+ }
+ | tSTAR tCOMMA f_marg_list
+ {
+ result = [ @builder.objc_restarg(val[0]),
+ *val[2] ]
+ }
+
+ block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_f_block_arg
+ {
+ 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_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[6]).
+ concat(val[7])
+ }
+ | f_arg tCOMMA f_block_optarg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[5])
+ }
+ | f_arg tCOMMA f_rest_arg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_arg tCOMMA
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[5])
+ }
+ | f_arg opt_f_block_arg
+ {
+ result = val[0].concat(val[1])
+ }
+ | f_block_optarg tCOMMA f_rest_arg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[5])
+ }
+ | f_block_optarg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[1])
+ }
+ | f_block_optarg tCOMMA f_arg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_rest_arg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[1])
+ }
+ | f_rest_arg tCOMMA f_arg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_block_arg
+ {
+ result = [ val[0] ]
+ }
+
+ 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: # nothing
+ {
+ result = []
+ }
+ | tSEMI bv_decls
+ {
+ result = val[1]
+ }
+
+ 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 lambda_body
+ {
+ result = [ val[1], val[2] ]
+
+ @static_env.unextend
+ }
+
+ f_larglist: tLPAREN2 f_args opt_bv_decl rparen
+ {
+ 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 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)
+ }
+ | block_call tCOLON2 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)
+ }
+
+ method_call: operation 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]
+ }
+
+ qwords: tQWORDS_BEG qword_list tSTRING_END
+ {
+ result = @builder.words_compose(val[0], val[1], val[2])
+ }
+
+ qword_list: # nothing
+ {
+ result = []
+ }
+ | qword_list tSTRING_CONTENT tSPACE
+ {
+ result = val[0] << @builder.string_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 tRCURLY
+ {
+ @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: tINTEGER
+ {
+ result = @builder.integer(val[0])
+ }
+ | tFLOAT
+ {
+ result = @builder.float(val[0])
+ }
+ | tUMINUS_NUM tINTEGER =tLOWEST
+ {
+ result = @builder.negate(val[0],
+ @builder.integer(val[1]))
+ }
+ | tUMINUS_NUM tFLOAT =tLOWEST
+ {
+ result = @builder.negate(val[0],
+ @builder.float(val[1]))
+ }
+
+ 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])
+ }
+ | 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: variable
+ {
+ result = @builder.accessible(val[0])
+ }
+
+ var_lhs: 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 expr_value term
+ {
+ result = [ val[0], val[1] ]
+ }
+ | error term
+ {
+ yyerrok
+ result = nil
+ }
+
+ f_arglist: tLPAREN2 f_args rparen
+ {
+ result = @builder.args(val[0], val[1], val[2])
+
+ @lexer.state = :expr_value
+ }
+ | f_args term
+ {
+ result = @builder.args(nil, val[0], nil)
+ }
+
+ f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_f_block_arg
+ {
+ 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_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[6]).
+ concat(val[7])
+ }
+ | f_arg tCOMMA f_optarg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_arg tCOMMA f_optarg tCOMMA f_arg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[5])
+ }
+ | f_arg tCOMMA f_rest_arg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[5])
+ }
+ | f_arg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[1])
+ }
+ | f_optarg tCOMMA f_rest_arg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[4]).
+ concat(val[5])
+ }
+ | f_optarg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[1])
+ }
+ | f_optarg tCOMMA f_arg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_rest_arg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[1])
+ }
+ | f_rest_arg tCOMMA f_arg opt_f_block_arg
+ {
+ result = val[0].
+ concat(val[2]).
+ concat(val[3])
+ }
+ | f_block_arg
+ {
+ 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 = @builder.arg(val[0])
+ }
+ | tIDENTIFIER tASSOC tIDENTIFIER
+ {
+ @static_env.declare val[2][0]
+
+ result = @builder.objc_kwarg(val[0], val[1], val[2])
+ }
+ | tLABEL tIDENTIFIER
+ {
+ @static_env.declare val[1][0]
+
+ result = @builder.objc_kwarg(val[0], nil, val[1])
+ }
+
+ f_arg_item: f_norm_arg
+ | 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_opt: tIDENTIFIER tEQL arg_value
+ {
+ @static_env.declare val[0][0]
+
+ result = @builder.optarg(val[0], val[1], val[2])
+ }
+
+ f_block_opt: tIDENTIFIER tEQL primary_value
+ {
+ @static_env.declare val[0][0]
+
+ 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] ]
+ }
+ | # nothing
+ {
+ 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])
+ }
+
+ 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
+ 19 # closest released match: v1_9_0_2
+ end
+
+ def default_encoding
+ Encoding::BINARY
+ end