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:
parent
9c86c513f0
commit
eb13bcec58
2 changed files with 35 additions and 71 deletions
90
parse.y
90
parse.y
|
@ -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':
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue