1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60892 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2017-11-24 04:26:27 +00:00
parent 9c86c513f0
commit eb13bcec58
2 changed files with 35 additions and 71 deletions

90
parse.y
View file

@ -3952,21 +3952,12 @@ regexp : tREGEXP_BEG regexp_contents tREGEXP_END
} }
; ;
words : tWORDS_BEG ' ' tSTRING_END words : tWORDS_BEG ' ' word_list tSTRING_END
{ {
/*%%%*/ /*%%%*/
$$ = new_zarray(&@$); $$ = $3 ? $3 : new_zarray(&@$);
/*% /*%
$$ = dispatch0(words_new); $$ = dispatch1(array, $3);
$$ = dispatch1(array, $$);
%*/
}
| tWORDS_BEG word_list tSTRING_END
{
/*%%%*/
$$ = $2;
/*%
$$ = dispatch1(array, $2);
%*/ %*/
} }
; ;
@ -4007,21 +3998,12 @@ word : string_content
} }
; ;
symbols : tSYMBOLS_BEG ' ' tSTRING_END symbols : tSYMBOLS_BEG ' ' symbol_list tSTRING_END
{ {
/*%%%*/ /*%%%*/
$$ = new_zarray(&@$); $$ = $3 ? $3 : new_zarray(&@$);
/*% /*%
$$ = dispatch0(symbols_new); $$ = dispatch1(array, $3);
$$ = dispatch1(array, $$);
%*/
}
| tSYMBOLS_BEG symbol_list tSTRING_END
{
/*%%%*/
$$ = $2;
/*%
$$ = dispatch1(array, $2);
%*/ %*/
} }
; ;
@ -4052,40 +4034,22 @@ symbol_list : /* none */
} }
; ;
qwords : tQWORDS_BEG ' ' tSTRING_END qwords : tQWORDS_BEG ' ' qword_list tSTRING_END
{ {
/*%%%*/ /*%%%*/
$$ = new_zarray(&@$); $$ = $3 ? $3 : new_zarray(&@$);
/*% /*%
$$ = dispatch0(qwords_new); $$ = dispatch1(array, $3);
$$ = dispatch1(array, $$);
%*/
}
| tQWORDS_BEG qword_list tSTRING_END
{
/*%%%*/
$$ = $2;
/*%
$$ = dispatch1(array, $2);
%*/ %*/
} }
; ;
qsymbols : tQSYMBOLS_BEG ' ' tSTRING_END qsymbols : tQSYMBOLS_BEG ' ' qsym_list tSTRING_END
{ {
/*%%%*/ /*%%%*/
$$ = new_zarray(&@$); $$ = $3 ? $3 : new_zarray(&@$);
/*% /*%
$$ = dispatch0(qsymbols_new); $$ = dispatch1(array, $3);
$$ = dispatch1(array, $$);
%*/
}
| tQSYMBOLS_BEG qsym_list tSTRING_END
{
/*%%%*/
$$ = $2;
/*%
$$ = dispatch1(array, $2);
%*/ %*/
} }
; ;
@ -5781,6 +5745,7 @@ rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE file, int start)
#define STR_FUNC_SYMBOL 0x10 #define STR_FUNC_SYMBOL 0x10
#define STR_FUNC_INDENT 0x20 #define STR_FUNC_INDENT 0x20
#define STR_FUNC_LABEL 0x40 #define STR_FUNC_LABEL 0x40
#define STR_FUNC_LIST 0x4000
#define STR_FUNC_TERM 0x8000 #define STR_FUNC_TERM 0x8000
enum string_type { enum string_type {
@ -5789,8 +5754,8 @@ enum string_type {
str_dquote = (STR_FUNC_EXPAND), str_dquote = (STR_FUNC_EXPAND),
str_xquote = (STR_FUNC_EXPAND), str_xquote = (STR_FUNC_EXPAND),
str_regexp = (STR_FUNC_REGEXP|STR_FUNC_ESCAPE|STR_FUNC_EXPAND), str_regexp = (STR_FUNC_REGEXP|STR_FUNC_ESCAPE|STR_FUNC_EXPAND),
str_sword = (STR_FUNC_QWORDS), str_sword = (STR_FUNC_QWORDS|STR_FUNC_LIST),
str_dword = (STR_FUNC_QWORDS|STR_FUNC_EXPAND), str_dword = (STR_FUNC_QWORDS|STR_FUNC_EXPAND|STR_FUNC_LIST),
str_ssym = (STR_FUNC_SYMBOL), str_ssym = (STR_FUNC_SYMBOL),
str_dsym = (STR_FUNC_SYMBOL|STR_FUNC_EXPAND) str_dsym = (STR_FUNC_SYMBOL|STR_FUNC_EXPAND)
}; };
@ -6602,9 +6567,7 @@ parser_parse_string(struct parser_params *parser, rb_strterm_literal_t *quote)
VALUE lit; VALUE lit;
if (func & STR_FUNC_TERM) { if (func & STR_FUNC_TERM) {
#ifdef RIPPER
if (func & STR_FUNC_QWORDS) nextc(); /* delayed term */ if (func & STR_FUNC_QWORDS) nextc(); /* delayed term */
#endif
SET_LEX_STATE(EXPR_END|EXPR_ENDARG); SET_LEX_STATE(EXPR_END|EXPR_ENDARG);
lex_strterm = 0; lex_strterm = 0;
return func & STR_FUNC_REGEXP ? tREGEXP_END : tSTRING_END; return func & STR_FUNC_REGEXP ? tREGEXP_END : tSTRING_END;
@ -6614,12 +6577,14 @@ parser_parse_string(struct parser_params *parser, rb_strterm_literal_t *quote)
do {c = nextc();} while (ISSPACE(c)); do {c = nextc();} while (ISSPACE(c));
space = 1; space = 1;
} }
if (func & STR_FUNC_LIST) {
quote->u1.func &= ~STR_FUNC_LIST;
space = 1;
}
if (c == term && !quote->u0.nest) { if (c == term && !quote->u0.nest) {
if (func & STR_FUNC_QWORDS) { if (func & STR_FUNC_QWORDS) {
quote->u1.func |= STR_FUNC_TERM; quote->u1.func |= STR_FUNC_TERM;
#ifdef RIPPER
pushback(c); /* dispatch the term at tSTRING_END */ pushback(c); /* dispatch the term at tSTRING_END */
#endif
add_delayed_token(parser->tokp, lex_p); add_delayed_token(parser->tokp, lex_p);
return ' '; return ' ';
} }
@ -7866,19 +7831,6 @@ parse_qmark(struct parser_params *parser, int space_seen)
return tCHAR; 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 static enum yytokentype
parse_percent(struct parser_params *parser, const int space_seen, const enum lex_state_e last_state) 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 *parser, const int space_seen, const enum lex
case 'W': case 'W':
lex_strterm = NEW_STRTERM(str_dword, term, paren); lex_strterm = NEW_STRTERM(str_dword, term, paren);
skip_words_sep();
return tWORDS_BEG; return tWORDS_BEG;
case 'w': case 'w':
lex_strterm = NEW_STRTERM(str_sword, term, paren); lex_strterm = NEW_STRTERM(str_sword, term, paren);
skip_words_sep();
return tQWORDS_BEG; return tQWORDS_BEG;
case 'I': case 'I':
lex_strterm = NEW_STRTERM(str_dword, term, paren); lex_strterm = NEW_STRTERM(str_dword, term, paren);
skip_words_sep();
return tSYMBOLS_BEG; return tSYMBOLS_BEG;
case 'i': case 'i':
lex_strterm = NEW_STRTERM(str_sword, term, paren); lex_strterm = NEW_STRTERM(str_sword, term, paren);
skip_words_sep();
return tQSYMBOLS_BEG; return tQSYMBOLS_BEG;
case 'x': case 'x':

View file

@ -1017,6 +1017,10 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
tree = parse('%w[a]', :on_qwords_add) {thru_qwords_add = true} tree = parse('%w[a]', :on_qwords_add) {thru_qwords_add = true}
assert_equal true, thru_qwords_add assert_equal true, thru_qwords_add
assert_equal '[array([a])]', tree 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 end
def test_qsymbols_add def test_qsymbols_add
@ -1024,6 +1028,10 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
tree = parse('%i[a]', :on_qsymbols_add) {thru_qsymbols_add = true} tree = parse('%i[a]', :on_qsymbols_add) {thru_qsymbols_add = true}
assert_equal true, thru_qsymbols_add assert_equal true, thru_qsymbols_add
assert_equal '[array([:a])]', tree 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 end
def test_symbols_add def test_symbols_add
@ -1031,6 +1039,10 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
tree = parse('%I[a]', :on_symbols_add) {thru_symbols_add = true} tree = parse('%I[a]', :on_symbols_add) {thru_symbols_add = true}
assert_equal true, thru_symbols_add assert_equal true, thru_symbols_add
assert_equal '[array([:a])]', tree 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 end
def test_qwords_new def test_qwords_new
@ -1383,6 +1395,10 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
tree = parse('%W[a]', :on_words_add) {thru_words_add = true} tree = parse('%W[a]', :on_words_add) {thru_words_add = true}
assert_equal true, thru_words_add assert_equal true, thru_words_add
assert_equal '[array([a])]', tree 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 end
def test_words_new def test_words_new