diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-01-26 05:02:19 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-01-26 05:02:19 +0000 |
commit | 161e3313d20eb285c8cfc3288e92a6d2e533cf44 (patch) | |
tree | 44b4f063df201d6c550a491323543f80fd4a25df /parse.y | |
parent | 74273daffb0d9f1b17795c8b8bbe8e32e14229eb (diff) |
* parse.y: clarify do ambiguity, bit more complex but natural
from my point of view.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1151 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'parse.y')
-rw-r--r-- | parse.y | 109 |
1 files changed, 62 insertions, 47 deletions
@@ -68,6 +68,18 @@ static unsigned long cond_stack = 0; } while (0) #define COND_P() (cond_nest > 0 && (cond_stack&1)) +static int cmdarg_nest = 0; +static unsigned long cmdarg_stack = 0; +#define CMDARG_PUSH do {\ + cmdarg_nest++;\ + cmdarg_stack = (cmdarg_stack<<1)|1;\ +} while(0) +#define CMDARG_POP do {\ + cmdarg_nest--;\ + cmdarg_stack >>= 1;\ +} while (0) +#define CMDARG_P() (cmdarg_nest > 0 && (cmdarg_stack&1)) + static int class_nest = 0; static int in_single = 0; static int compile_for_eval = 0; @@ -154,7 +166,8 @@ static void top_local_setup(); kRETRY kIN kDO - kDO2 + kDO_COND + kDO_BLOCK kRETURN kYIELD kSUPER @@ -186,8 +199,8 @@ static void top_local_setup(); %type <node> compstmt stmts stmt expr arg primary command command_call method_call %type <node> if_tail opt_else case_body cases rescue exc_list exc_var ensure %type <node> args ret_args when_args call_args paren_args opt_paren_args -%type <node> aref_args opt_block_arg block_arg var_ref -%type <node> mrhs mrhs_basic superclass generic_call block_call call_block +%type <node> command_args aref_args opt_block_arg block_arg var_ref +%type <node> mrhs mrhs_basic superclass block_call block_command %type <node> f_arglist f_args f_optarg f_opt f_block_arg opt_f_block_arg %type <node> assoc_list assocs assoc undef_list backref %type <node> block_var opt_block_var brace_block do_block lhs none @@ -444,38 +457,38 @@ expr : mlhs '=' mrhs | arg command_call : command - | block_call + | block_command -block_call : call_block - | call_block '.' operation2 call_args +block_command : block_call + | block_call '.' operation2 command_args { value_expr($1); $$ = new_call($1, $3, $4); } - | call_block tCOLON2 operation2 call_args + | block_call tCOLON2 operation2 command_args { value_expr($1); $$ = new_call($1, $3, $4); } -command : operation call_args +command : operation command_args { $$ = new_fcall($1, $2); fixpos($$, $2); } - | primary '.' operation2 call_args + | primary '.' operation2 command_args { value_expr($1); $$ = new_call($1, $3, $4); fixpos($$, $1); } - | primary tCOLON2 operation2 call_args + | primary tCOLON2 operation2 command_args { value_expr($1); $$ = new_call($1, $3, $4); fixpos($$, $1); } - | kSUPER call_args + | kSUPER command_args { if (!compile_for_eval && !cur_mid && !in_single) yyerror("super called outside of method"); @@ -488,7 +501,6 @@ command : operation call_args fixpos($$, $2); } - mlhs : mlhs_basic | tLPAREN mlhs_entry ')' { @@ -996,6 +1008,12 @@ call_args : command } | block_arg +command_args : {CMDARG_PUSH;} call_args + { + CMDARG_POP; + $$ = $2; + } + block_arg : tAMPER arg { value_expr($2); @@ -1347,7 +1365,7 @@ then : term | term kTHEN do : term - | kDO2 + | kDO_COND if_tail : opt_else | kELSIF expr then @@ -1383,7 +1401,7 @@ opt_block_var : none } -do_block : kDO +do_block : kDO_BLOCK { $<vars>$ = dyna_push(); } @@ -1396,35 +1414,7 @@ do_block : kDO dyna_pop($<vars>2); } -brace_block : '{' - { - $<vars>$ = dyna_push(); - } - opt_block_var - compstmt '}' - { - $$ = NEW_ITER($3, 0, $4); - fixpos($$, $4); - dyna_pop($<vars>2); - } - -generic_call : tIDENTIFIER - { - $$ = NEW_VCALL($1); - } - | tCONSTANT - { - $$ = NEW_VCALL($1); - } - | tFID - { - $$ = NEW_VCALL($1); - } - | method_call - | command_call - - -call_block : generic_call do_block +block_call : command do_block { if ($1 && nd_type($1) == NODE_BLOCK_PASS) { rb_compile_error("both block arg and actual block given"); @@ -1433,12 +1423,12 @@ call_block : generic_call do_block $$ = $2; fixpos($$, $2); } - | call_block '.' operation2 opt_paren_args + | block_call '.' operation2 opt_paren_args { value_expr($1); $$ = new_call($1, $3, $4); } - | call_block tCOLON2 operation2 opt_paren_args + | block_call tCOLON2 operation2 opt_paren_args { value_expr($1); $$ = new_call($1, $3, $4); @@ -1481,6 +1471,29 @@ method_call : operation paren_args $$ = NEW_ZSUPER(); } +brace_block : '{' + { + $<vars>$ = dyna_push(); + } + opt_block_var + compstmt '}' + { + $$ = NEW_ITER($3, 0, $4); + fixpos($$, $4); + dyna_pop($<vars>2); + } + | kDO + { + $<vars>$ = dyna_push(); + } + opt_block_var + compstmt kEND + { + $$ = NEW_ITER($3, 0, $4); + fixpos($$, $4); + dyna_pop($<vars>2); + } + case_body : kWHEN when_args then compstmt cases @@ -3599,8 +3612,10 @@ yylex() if (state == EXPR_FNAME) { yylval.id = rb_intern(kw->name); } - if (kw->id[0] == kDO && COND_P()) { - return kDO2; + if (kw->id[0] == kDO) { + if (COND_P()) return kDO_COND; + if (CMDARG_P()) return kDO_BLOCK; + return kDO; } return kw->id[state != EXPR_BEG]; } |