ruby-changes:48776
From: nobu <ko1@a...>
Date: Fri, 24 Nov 2017 13:26:39 +0900 (JST)
Subject: [ruby-changes:48776] nobu:r60892 (trunk): parse.y: refactor list literals
nobu 2017-11-24 13:26:27 +0900 (Fri, 24 Nov 2017) New Revision: 60892 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=60892 Log: parse.y: refactor list literals * parse.y (words, symbols, qwords, qsymbols): unify empty list and non-empty list. * parse.y (parser_parse_string): always dispatch a word separator at the beginning of list literals. [ruby-core:83871] [Bug #14126] Modified files: trunk/parse.y trunk/test/ripper/test_parser_events.rb Index: test/ripper/test_parser_events.rb =================================================================== --- test/ripper/test_parser_events.rb (revision 60891) +++ test/ripper/test_parser_events.rb (revision 60892) @@ -1017,6 +1017,10 @@ class TestRipper::ParserEvents < Test::U https://github.com/ruby/ruby/blob/trunk/test/ripper/test_parser_events.rb#L1017 tree = parse('%w[a]', :on_qwords_add) {thru_qwords_add = true} assert_equal true, thru_qwords_add assert_equal '[array([a])]', tree + thru_qwords_add = false + tree = parse('%w[ a ]', :on_qwords_add) {thru_qwords_add = true} + assert_equal true, thru_qwords_add + assert_equal '[array([a])]', tree end def test_qsymbols_add @@ -1024,6 +1028,10 @@ class TestRipper::ParserEvents < Test::U https://github.com/ruby/ruby/blob/trunk/test/ripper/test_parser_events.rb#L1028 tree = parse('%i[a]', :on_qsymbols_add) {thru_qsymbols_add = true} assert_equal true, thru_qsymbols_add assert_equal '[array([:a])]', tree + thru_qsymbols_add = false + tree = parse('%i[ a ]', :on_qsymbols_add) {thru_qsymbols_add = true} + assert_equal true, thru_qsymbols_add + assert_equal '[array([:a])]', tree end def test_symbols_add @@ -1031,6 +1039,10 @@ class TestRipper::ParserEvents < Test::U https://github.com/ruby/ruby/blob/trunk/test/ripper/test_parser_events.rb#L1039 tree = parse('%I[a]', :on_symbols_add) {thru_symbols_add = true} assert_equal true, thru_symbols_add assert_equal '[array([:a])]', tree + thru_symbols_add = false + tree = parse('%I[ a ]', :on_symbols_add) {thru_symbols_add = true} + assert_equal true, thru_symbols_add + assert_equal '[array([:a])]', tree end def test_qwords_new @@ -1383,6 +1395,10 @@ class TestRipper::ParserEvents < Test::U https://github.com/ruby/ruby/blob/trunk/test/ripper/test_parser_events.rb#L1395 tree = parse('%W[a]', :on_words_add) {thru_words_add = true} assert_equal true, thru_words_add assert_equal '[array([a])]', tree + thru_words_add = false + tree = parse('%W[ a ]', :on_words_add) {thru_words_add = true} + assert_equal true, thru_words_add + assert_equal '[array([a])]', tree end def test_words_new Index: parse.y =================================================================== --- parse.y (revision 60891) +++ parse.y (revision 60892) @@ -3952,21 +3952,12 @@ regexp : tREGEXP_BEG regexp_contents tR https://github.com/ruby/ruby/blob/trunk/parse.y#L3952 } ; -words : tWORDS_BEG ' ' tSTRING_END +words : tWORDS_BEG ' ' word_list tSTRING_END { /*%%%*/ - $$ = new_zarray(&@$); + $$ = $3 ? $3 : new_zarray(&@$); /*% - $$ = dispatch0(words_new); - $$ = dispatch1(array, $$); - %*/ - } - | tWORDS_BEG word_list tSTRING_END - { - /*%%%*/ - $$ = $2; - /*% - $$ = dispatch1(array, $2); + $$ = dispatch1(array, $3); %*/ } ; @@ -4007,21 +3998,12 @@ word : string_content https://github.com/ruby/ruby/blob/trunk/parse.y#L3998 } ; -symbols : tSYMBOLS_BEG ' ' tSTRING_END - { - /*%%%*/ - $$ = new_zarray(&@$); - /*% - $$ = dispatch0(symbols_new); - $$ = dispatch1(array, $$); - %*/ - } - | tSYMBOLS_BEG symbol_list tSTRING_END +symbols : tSYMBOLS_BEG ' ' symbol_list tSTRING_END { /*%%%*/ - $$ = $2; + $$ = $3 ? $3 : new_zarray(&@$); /*% - $$ = dispatch1(array, $2); + $$ = dispatch1(array, $3); %*/ } ; @@ -4052,40 +4034,22 @@ symbol_list : /* none */ https://github.com/ruby/ruby/blob/trunk/parse.y#L4034 } ; -qwords : tQWORDS_BEG ' ' tSTRING_END +qwords : tQWORDS_BEG ' ' qword_list tSTRING_END { /*%%%*/ - $$ = new_zarray(&@$); + $$ = $3 ? $3 : new_zarray(&@$); /*% - $$ = dispatch0(qwords_new); - $$ = dispatch1(array, $$); - %*/ - } - | tQWORDS_BEG qword_list tSTRING_END - { - /*%%%*/ - $$ = $2; - /*% - $$ = dispatch1(array, $2); + $$ = dispatch1(array, $3); %*/ } ; -qsymbols : tQSYMBOLS_BEG ' ' tSTRING_END +qsymbols : tQSYMBOLS_BEG ' ' qsym_list tSTRING_END { /*%%%*/ - $$ = new_zarray(&@$); + $$ = $3 ? $3 : new_zarray(&@$); /*% - $$ = dispatch0(qsymbols_new); - $$ = dispatch1(array, $$); - %*/ - } - | tQSYMBOLS_BEG qsym_list tSTRING_END - { - /*%%%*/ - $$ = $2; - /*% - $$ = dispatch1(array, $2); + $$ = dispatch1(array, $3); %*/ } ; @@ -5781,6 +5745,7 @@ rb_parser_compile_file_path(VALUE vparse https://github.com/ruby/ruby/blob/trunk/parse.y#L5745 #define STR_FUNC_SYMBOL 0x10 #define STR_FUNC_INDENT 0x20 #define STR_FUNC_LABEL 0x40 +#define STR_FUNC_LIST 0x4000 #define STR_FUNC_TERM 0x8000 enum string_type { @@ -5789,8 +5754,8 @@ enum string_type { https://github.com/ruby/ruby/blob/trunk/parse.y#L5754 str_dquote = (STR_FUNC_EXPAND), str_xquote = (STR_FUNC_EXPAND), str_regexp = (STR_FUNC_REGEXP|STR_FUNC_ESCAPE|STR_FUNC_EXPAND), - str_sword = (STR_FUNC_QWORDS), - str_dword = (STR_FUNC_QWORDS|STR_FUNC_EXPAND), + str_sword = (STR_FUNC_QWORDS|STR_FUNC_LIST), + str_dword = (STR_FUNC_QWORDS|STR_FUNC_EXPAND|STR_FUNC_LIST), str_ssym = (STR_FUNC_SYMBOL), str_dsym = (STR_FUNC_SYMBOL|STR_FUNC_EXPAND) }; @@ -6602,9 +6567,7 @@ parser_parse_string(struct parser_params https://github.com/ruby/ruby/blob/trunk/parse.y#L6567 VALUE lit; if (func & STR_FUNC_TERM) { -#ifdef RIPPER if (func & STR_FUNC_QWORDS) nextc(); /* delayed term */ -#endif SET_LEX_STATE(EXPR_END|EXPR_ENDARG); lex_strterm = 0; return func & STR_FUNC_REGEXP ? tREGEXP_END : tSTRING_END; @@ -6614,12 +6577,14 @@ parser_parse_string(struct parser_params https://github.com/ruby/ruby/blob/trunk/parse.y#L6577 do {c = nextc();} while (ISSPACE(c)); space = 1; } + if (func & STR_FUNC_LIST) { + quote->u1.func &= ~STR_FUNC_LIST; + space = 1; + } if (c == term && !quote->u0.nest) { if (func & STR_FUNC_QWORDS) { quote->u1.func |= STR_FUNC_TERM; -#ifdef RIPPER pushback(c); /* dispatch the term at tSTRING_END */ -#endif add_delayed_token(parser->tokp, lex_p); return ' '; } @@ -7866,19 +7831,6 @@ parse_qmark(struct parser_params *parser https://github.com/ruby/ruby/blob/trunk/parse.y#L7831 return tCHAR; } -#ifndef RIPPER -static void -parser_skip_words_sep(struct parser_params *parser) -{ - int c; - do {c = nextc();} while (ISSPACE(c)); - pushback(c); -} -#define skip_words_sep() parser_skip_words_sep(parser) -#else -#define skip_words_sep() ((void)0) -#endif - static enum yytokentype parse_percent(struct parser_params *parser, const int space_seen, const enum lex_state_e last_state) { @@ -7923,22 +7875,18 @@ parse_percent(struct parser_params *pars https://github.com/ruby/ruby/blob/trunk/parse.y#L7875 case 'W': lex_strterm = NEW_STRTERM(str_dword, term, paren); - skip_words_sep(); return tWORDS_BEG; case 'w': lex_strterm = NEW_STRTERM(str_sword, term, paren); - skip_words_sep(); return tQWORDS_BEG; case 'I': lex_strterm = NEW_STRTERM(str_dword, term, paren); - skip_words_sep(); return tSYMBOLS_BEG; case 'i': lex_strterm = NEW_STRTERM(str_sword, term, paren); - skip_words_sep(); return tQSYMBOLS_BEG; case 'x': -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/