aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-11-24 04:26:27 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-11-24 04:26:27 +0000
commiteb13bcec58cfd2a65b0d6996af65865f357699ad (patch)
tree8c2d40ac47f3357db59466ae254fd8ca6c387d8c
parent9c86c513f0912af07c9addb57026bab385abea35 (diff)
downloadruby-eb13bcec58cfd2a65b0d6996af65865f357699ad.tar.gz
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
-rw-r--r--parse.y90
-rw-r--r--test/ripper/test_parser_events.rb16
2 files changed, 35 insertions, 71 deletions
diff --git a/parse.y b/parse.y
index 1ef3a10cfa..84498a0ce0 100644
--- a/parse.y
+++ b/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, $$);
- %*/
- }
- | tWORDS_BEG word_list tSTRING_END
- {
- /*%%%*/
- $$ = $2;
- /*%
- $$ = dispatch1(array, $2);
+ $$ = dispatch1(array, $3);
%*/
}
;
@@ -4007,21 +3998,12 @@ word : string_content
}
;
-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 */
}
;
-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 vparser, VALUE fname, VALUE file, int start)
#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 {
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 *parser, rb_strterm_literal_t *quote)
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 *parser, rb_strterm_literal_t *quote)
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, int space_seen)
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 *parser, const int space_seen, const enum lex
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':
diff --git a/test/ripper/test_parser_events.rb b/test/ripper/test_parser_events.rb
index 86720b1446..2fca61e1d1 100644
--- a/test/ripper/test_parser_events.rb
+++ b/test/ripper/test_parser_events.rb
@@ -1017,6 +1017,10 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
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::Unit::TestCase
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::Unit::TestCase
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::Unit::TestCase
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