From: Nobuyoshi Nakada Date: 2007-04-12T04:19:02+09:00 Subject: Re: memory exhausted Hi, At Wed, 11 Apr 2007 04:56:23 +0900, Tim Pease wrote in [ruby-talk:247418]: > Probably hitting a lex/yacc semantic stack limit. Yes, it will work by increasing YYMAXDEPTH. > I wonder if you could do the same kind of thing with a > begin/rescue/ensure/end clause? > > Hmmm .... > > eval < begin > raise > #{ (0..1999).map { "rescue;\n" }.join('') } > end > EOS > > (eval):2003: compile error (SyntaxError) > (eval):2003: memory exhausted A patch to inverse the order of shift/reduce. Index: parse.y =================================================================== --- parse.y (revision 12169) +++ parse.y (working copy) @@ -273,5 +273,5 @@ static void top_local_setup(); %type bodystmt compstmt stmts stmt expr arg primary command command_call method_call %type expr_value arg_value primary_value -%type if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure +%type if_tail opt_else case_body cases opt_rescue rescue exc_list exc_var opt_ensure %type args when_args call_args call_args2 open_args paren_args opt_paren_args %type command_args aref_args opt_block_arg block_arg var_ref var_lhs @@ -376,5 +376,7 @@ bodystmt : compstmt $$ = $1; if ($2) { - $$ = NEW_RESCUE($1, $2, $3); + $$ = $2; + $$->nd_head = $1; + $$->nd_else = $3; } else if ($3) { @@ -1599,14 +1601,16 @@ primary : literal } } - | kCASE expr_value opt_terms - case_body - kEND + | kCASE expr_value opt_terms cases opt_else kEND { - $$ = NEW_CASE($2, $4); + $4->nd_head->nd_next = $5; + $4->nd_head = $2; + $$ = $4; fixpos($$, $2); } - | kCASE opt_terms case_body kEND + | kCASE opt_terms cases opt_else kEND { - $$ = $3; + $3->nd_head->nd_next = $4; + $$ = $3->nd_body; + rb_gc_force_recycle((VALUE)$3); } | kCASE opt_terms kELSE compstmt kEND @@ -1871,7 +1875,6 @@ brace_block : '{' case_body : kWHEN when_args then compstmt - cases { - $$ = NEW_WHEN($2, $4, $5); + $$ = NEW_WHEN($2, $4, 0); } ; @@ -1887,11 +1890,34 @@ when_args : args ; -cases : opt_else - | case_body +cases : case_body + { + $$ = NEW_CASE($1, $1); + } + | cases + case_body + { + $$ = $1; + $$->nd_head->nd_next = $2; + $$->nd_head = $2; + } + ; + +opt_rescue : none + | opt_rescue + rescue + { + if ($1) { + $1->nd_head->nd_head = $$; + $1->nd_head = $$; + $$ = $1; + } + else { + $$ = NEW_RESCUE($2, $2, 0); + } + } ; -opt_rescue : kRESCUE exc_list exc_var then +rescue : kRESCUE exc_list exc_var then compstmt - opt_rescue { if ($3) { @@ -1899,8 +1925,7 @@ opt_rescue : kRESCUE exc_list exc_var th $5 = block_append($3, $5); } - $$ = NEW_RESBODY($2, $5, $6); + $$ = NEW_RESBODY($2, $5, 0); fixpos($$, $2?$2:$5); } - | none ; -- Nobu Nakada