Nobuyoshi Nakada
4/11/2007 7:19:00 PM
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 <<EOS
> 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 <node> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
%type <node> expr_value arg_value primary_value
-%type <node> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
+%type <node> if_tail opt_else case_body cases opt_rescue rescue exc_list exc_var opt_ensure
%type <node> args when_args call_args call_args2 open_args paren_args opt_paren_args
%type <node> 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