From: nobu.nokada@... Date: 2005-02-07T23:19:21+09:00 Subject: Re: 'when (cond):' causes SyntaxError Hi, At Sun, 6 Feb 2005 10:13:41 +0900, Yukihiro Matsumoto wrote in [ruby-core:04369]: > |The following script causes SyntaxError under 1.9, only at 'when > |(cond):' case. 1.8.2 seems to allow both 'if (cond):' and 'when > |(cond):' cases. Whitespace(s) after ':' resolves the error. Accidental > |or unavoidable syntax abyss? > > A bug. A patch, to separate EXPR_BEG to 2 cases; beginning of expression a) which must be a pure value and b) which may not. Index: keywords =================================================================== RCS file: //queendom/nakada/cvs/ruby/keywords,v retrieving revision 1.8 diff -U2 -p -r1.8 keywords --- keywords 19 Sep 2004 18:48:28 -0000 1.8 +++ keywords 7 Feb 2005 06:37:56 -0000 @@ -9,8 +9,8 @@ BEGIN, {klBEGIN, klBEGIN}, EXPR_END END, {klEND, klEND}, EXPR_END alias, {kALIAS, kALIAS}, EXPR_FNAME -and, {kAND, kAND}, EXPR_BEG +and, {kAND, kAND}, EXPR_VALUE begin, {kBEGIN, kBEGIN}, EXPR_BEG break, {kBREAK, kBREAK}, EXPR_MID -case, {kCASE, kCASE}, EXPR_BEG +case, {kCASE, kCASE}, EXPR_VALUE class, {kCLASS, kCLASS}, EXPR_CLASS def, {kDEF, kDEF}, EXPR_FNAME @@ -18,16 +18,16 @@ defined?, {kDEFINED, kDEFINED}, EXPR_ARG do, {kDO, kDO}, EXPR_BEG else, {kELSE, kELSE}, EXPR_BEG -elsif, {kELSIF, kELSIF}, EXPR_BEG +elsif, {kELSIF, kELSIF}, EXPR_VALUE end, {kEND, kEND}, EXPR_END ensure, {kENSURE, kENSURE}, EXPR_BEG false, {kFALSE, kFALSE}, EXPR_END -for, {kFOR, kFOR}, EXPR_BEG -if, {kIF, kIF_MOD}, EXPR_BEG -in, {kIN, kIN}, EXPR_BEG -module, {kMODULE, kMODULE}, EXPR_BEG +for, {kFOR, kFOR}, EXPR_VALUE +if, {kIF, kIF_MOD}, EXPR_VALUE +in, {kIN, kIN}, EXPR_VALUE +module, {kMODULE, kMODULE}, EXPR_VALUE next, {kNEXT, kNEXT}, EXPR_MID nil, {kNIL, kNIL}, EXPR_END -not, {kNOT, kNOT}, EXPR_BEG -or, {kOR, kOR}, EXPR_BEG +not, {kNOT, kNOT}, EXPR_VALUE +or, {kOR, kOR}, EXPR_VALUE redo, {kREDO, kREDO}, EXPR_END rescue, {kRESCUE, kRESCUE_MOD}, EXPR_MID @@ -39,8 +39,8 @@ then, {kTHEN, kTHEN}, EXPR_BEG true, {kTRUE, kTRUE}, EXPR_END undef, {kUNDEF, kUNDEF}, EXPR_FNAME -unless, {kUNLESS, kUNLESS_MOD}, EXPR_BEG -until, {kUNTIL, kUNTIL_MOD}, EXPR_BEG -when, {kWHEN, kWHEN}, EXPR_BEG -while, {kWHILE, kWHILE_MOD}, EXPR_BEG +unless, {kUNLESS, kUNLESS_MOD}, EXPR_VALUE +until, {kUNTIL, kUNTIL_MOD}, EXPR_VALUE +when, {kWHEN, kWHEN}, EXPR_VALUE +while, {kWHILE, kWHILE_MOD}, EXPR_VALUE yield, {kYIELD, kYIELD}, EXPR_ARG %% Index: parse.y =================================================================== RCS file: //queendom/nakada/cvs/ruby/parse.y,v retrieving revision 1.366 diff -U2 -p -r1.366 parse.y --- parse.y 5 Jan 2005 08:00:48 -0000 1.366 +++ parse.y 7 Feb 2005 06:36:56 -0000 @@ -64,5 +64,5 @@ enum lex_state_e { EXPR_DOT, /* right after `.' or `::', no reserved words. */ EXPR_CLASS, /* immediate after `class', no here document. */ - EXPR_TERNARY, /* alike EXPR_BEG but immediate after ternary op. */ + EXPR_VALUE, /* alike EXPR_BEG but label is disallowed. */ }; @@ -489,5 +489,5 @@ static void ripper_compile_error _((stru %type mrhs superclass block_call block_command %type f_arglist f_args f_optarg f_opt f_block_arg opt_f_block_arg -%type assoc_list assocs assoc kwargs undef_list backref string_dvar +%type assoc_list assocs assoc undef_list backref string_dvar %type for_var block_var opt_block_var block_par %type brace_block cmd_brace_block do_block lhs none fitem @@ -2322,6 +2322,6 @@ open_args : call_args | tLPAREN_ARG {lex_state = EXPR_ENDARG;} rparen { + rb_warn0("don't put space before argument parentheses"); /*%%%*/ - rb_warn("don't put space before argument parentheses"); $$ = 0; /*% @@ -2331,6 +2331,6 @@ open_args : call_args | tLPAREN_ARG call_args2 {lex_state = EXPR_ENDARG;} rparen { + rb_warn0("don't put space before argument parentheses"); /*%%%*/ - rb_warn("don't put space before argument parentheses"); $$ = $2; /*% @@ -2439,9 +2439,8 @@ primary : literal | tLPAREN_ARG expr {lex_state = EXPR_ENDARG;} rparen { + rb_warning0("(...) interpreted as grouped expression"); /*%%%*/ - rb_warning("(...) interpreted as grouped expression"); $$ = $2; /*% - rb_warning0("(...) interpreted as grouped expression"); $$ = dispatch1(paren, $2); %*/ @@ -4067,8 +4066,4 @@ assoc_list : none %*/ } - | kwargs trailer - { - $$ = $1; - } ; @@ -4098,7 +4093,5 @@ assoc : arg_value tASSOC arg_value %*/ } - ; - -kwargs : tLABEL arg_value + | tLABEL arg_value { /*%%%*/ @@ -4108,13 +4101,4 @@ kwargs : tLABEL arg_value %*/ } - | kwargs ',' tLABEL arg_value - { - /*%%%*/ - $$ = list_append(NEW_LIST(NEW_LIT(ID2SYM($3))), $4); - $$ = list_concat($1, $$); - /*% - rb_ary_push($$, dispatch2(assoc_new, $3, $4)); - %*/ - } ; @@ -5236,5 +5220,5 @@ lvar_defined_gen(parser, id) #define IS_ARG() (lex_state == EXPR_ARG || lex_state == EXPR_CMDARG) -#define IS_BEG() (lex_state == EXPR_BEG || lex_state == EXPR_MID || lex_state == EXPR_TERNARY || lex_state == EXPR_CLASS) +#define IS_BEG() (lex_state == EXPR_BEG || lex_state == EXPR_MID || lex_state == EXPR_VALUE || lex_state == EXPR_CLASS) static int @@ -5320,5 +5304,5 @@ parser_yylex(parser) case EXPR_DOT: case EXPR_CLASS: - case EXPR_TERNARY: + case EXPR_VALUE: #ifdef RIPPER if (!fallthru) { @@ -5524,5 +5508,5 @@ parser_yylex(parser) case '?': if (lex_state == EXPR_END || lex_state == EXPR_ENDARG) { - lex_state = EXPR_TERNARY; + lex_state = EXPR_VALUE; return '?'; } @@ -5562,5 +5546,5 @@ parser_yylex(parser) ternary: pushback(c); - lex_state = EXPR_TERNARY; + lex_state = EXPR_VALUE; return '?'; } @@ -6399,5 +6383,5 @@ parser_yylex(parser) return kDO; } - if (state == EXPR_BEG || state == EXPR_TERNARY) + if (state == EXPR_BEG || state == EXPR_VALUE) return kw->id[0]; else { -- Nobu Nakada