ruby-changes:48093
From: nobu <ko1@a...>
Date: Wed, 18 Oct 2017 22:08:59 +0900 (JST)
Subject: [ruby-changes:48093] nobu:r60207 (trunk): parse.y: serial comparisons
nobu 2017-10-18 22:08:53 +0900 (Wed, 18 Oct 2017) New Revision: 60207 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=60207 Log: parse.y: serial comparisons * parse.y (rel_expr): warn sequence of comparisons, which would be probably unintentional. [EXPERIMENTAL] Modified files: trunk/parse.y trunk/test/ruby/test_parse.rb Index: parse.y =================================================================== --- parse.y (revision 60206) +++ parse.y (revision 60207) @@ -773,6 +773,7 @@ static ID id_warn, id_warning, id_gets; https://github.com/ruby/ruby/blob/trunk/parse.y#L773 # define WARN_S_L(s,l) STR_NEW(s,l) # define WARN_S(s) STR_NEW2(s) # define WARN_I(i) INT2NUM(i) +# define WARN_ID(i) rb_id2str(i) # define PRIsWARN "s" # define WARN_ARGS(fmt,n) parser->value, id_warn, n, rb_usascii_str_new_lit(fmt) # define WARN_ARGS_L(l,fmt,n) WARN_ARGS(fmt,n) @@ -795,6 +796,7 @@ PRINTF_ARGS(static void ripper_compile_e https://github.com/ruby/ruby/blob/trunk/parse.y#L796 # define WARN_S_L(s,l) s # define WARN_S(s) s # define WARN_I(i) i +# define WARN_ID(i) rb_id2name(i) # define PRIsWARN PRIsVALUE # define WARN_ARGS(fmt,n) WARN_ARGS_L(ruby_sourceline,fmt,n) # define WARN_ARGS_L(l,fmt,n) ruby_sourcefile, (l), (fmt) @@ -896,7 +898,7 @@ static void token_info_pop_gen(struct pa https://github.com/ruby/ruby/blob/trunk/parse.y#L898 %type <node> literal numeric simple_numeric dsym cpath %type <node> top_compstmt top_stmts top_stmt %type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call -%type <node> expr_value arg_value primary_value fcall +%type <node> expr_value arg_value primary_value fcall rel_expr %type <node> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure %type <node> args call_args opt_call_args %type <node> paren_args opt_paren_args args_tail opt_args_tail block_args_tail opt_block_args_tail @@ -2093,10 +2095,7 @@ arg : lhs '=' arg_rhs https://github.com/ruby/ruby/blob/trunk/parse.y#L2095 { $$ = call_bin_op($1, idCmp, $3); } - | arg relop arg %prec '>' - { - $$ = call_bin_op($1, $2, $3); - } + | rel_expr %prec tCMP | arg tEQ arg { $$ = call_bin_op($1, idEq, $3); @@ -2172,6 +2171,17 @@ relop : '>' {$$ = '>';} https://github.com/ruby/ruby/blob/trunk/parse.y#L2171 | tLEQ {$$ = idLE;} ; +rel_expr : arg relop arg %prec '>' + { + $$ = call_bin_op($1, $2, $3); + } + | rel_expr relop arg %prec '>' + { + rb_warning1("comparison '%s' after comparison", WARN_ID($2)); + $$ = call_bin_op($1, $2, $3); + } + ; + arg_value : arg { /*%%%*/ Index: test/ruby/test_parse.rb =================================================================== --- test/ruby/test_parse.rb (revision 60206) +++ test/ruby/test_parse.rb (revision 60207) @@ -1069,6 +1069,14 @@ x = __ENCODING__ https://github.com/ruby/ruby/blob/trunk/test/ruby/test_parse.rb#L1069 assert_equal(1.3, o.x) end + def test_serial_comparison + assert_warning(/comparison '<' after/) do + $VERBOSE = true + x = 1 + eval("if false; 0 < x < 2; end") + end + end + =begin def test_past_scope_variable assert_warning(/past scope/) {catch {|tag| eval("BEGIN{throw tag}; tap {a = 1}; a")}} -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/