зеркало из https://github.com/github/ruby.git
parse.y: quoted ID key
* parse.y (assoc): allow quoted ID as a key of a hash literal. [ruby-core:34453] [Feature #4276] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47649 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
7190c04417
Коммит
b0c03f63e5
|
@ -1,3 +1,8 @@
|
||||||
|
Sat Sep 20 10:48:41 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* parse.y (assoc): allow quoted ID as a key of a hash literal.
|
||||||
|
[ruby-core:34453] [Feature #4276]
|
||||||
|
|
||||||
Sat Sep 20 10:23:00 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Sat Sep 20 10:23:00 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* compile.c (iseq_set_arguments): store local variable IDs in
|
* compile.c (iseq_set_arguments): store local variable IDs in
|
||||||
|
|
|
@ -46,6 +46,7 @@ static ID ripper_id_rational;
|
||||||
static ID ripper_id_regexp_beg;
|
static ID ripper_id_regexp_beg;
|
||||||
static ID ripper_id_regexp_end;
|
static ID ripper_id_regexp_end;
|
||||||
static ID ripper_id_label;
|
static ID ripper_id_label;
|
||||||
|
static ID ripper_id_label_end;
|
||||||
static ID ripper_id_tlambda;
|
static ID ripper_id_tlambda;
|
||||||
static ID ripper_id_tlambeg;
|
static ID ripper_id_tlambeg;
|
||||||
|
|
||||||
|
@ -103,6 +104,7 @@ ripper_init_eventids2(void)
|
||||||
ripper_id_regexp_beg = rb_intern_const("on_regexp_beg");
|
ripper_id_regexp_beg = rb_intern_const("on_regexp_beg");
|
||||||
ripper_id_regexp_end = rb_intern_const("on_regexp_end");
|
ripper_id_regexp_end = rb_intern_const("on_regexp_end");
|
||||||
ripper_id_label = rb_intern_const("on_label");
|
ripper_id_label = rb_intern_const("on_label");
|
||||||
|
ripper_id_label_end = rb_intern_const("on_label_end");
|
||||||
ripper_id_tlambda = rb_intern_const("on_tlambda");
|
ripper_id_tlambda = rb_intern_const("on_tlambda");
|
||||||
ripper_id_tlambeg = rb_intern_const("on_tlambeg");
|
ripper_id_tlambeg = rb_intern_const("on_tlambeg");
|
||||||
|
|
||||||
|
@ -259,6 +261,7 @@ static const struct token_assoc {
|
||||||
{tWORDS_BEG, &ripper_id_words_beg},
|
{tWORDS_BEG, &ripper_id_words_beg},
|
||||||
{tXSTRING_BEG, &ripper_id_backtick},
|
{tXSTRING_BEG, &ripper_id_backtick},
|
||||||
{tLABEL, &ripper_id_label},
|
{tLABEL, &ripper_id_label},
|
||||||
|
{tLABEL_END, &ripper_id_label_end},
|
||||||
{tLAMBDA, &ripper_id_tlambda},
|
{tLAMBDA, &ripper_id_tlambda},
|
||||||
{tLAMBEG, &ripper_id_tlambeg},
|
{tLAMBEG, &ripper_id_tlambeg},
|
||||||
|
|
||||||
|
|
47
parse.y
47
parse.y
|
@ -823,7 +823,7 @@ static void token_info_pop(struct parser_params*, const char *token);
|
||||||
%token tAMPER "&"
|
%token tAMPER "&"
|
||||||
%token tLAMBDA "->"
|
%token tLAMBDA "->"
|
||||||
%token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG
|
%token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG
|
||||||
%token tSTRING_DBEG tSTRING_DEND tSTRING_DVAR tSTRING_END tLAMBEG
|
%token tSTRING_DBEG tSTRING_DEND tSTRING_DVAR tSTRING_END tLAMBEG tLABEL_END
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* precedence table
|
* precedence table
|
||||||
|
@ -2305,14 +2305,24 @@ arg : lhs '=' arg
|
||||||
$$ = dispatch1(defined, $4);
|
$$ = dispatch1(defined, $4);
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
| arg '?' arg opt_nl ':' arg
|
| arg '?'
|
||||||
|
{
|
||||||
|
$<val>$ = cond_stack;
|
||||||
|
cond_stack = 0;
|
||||||
|
COND_PUSH(1);
|
||||||
|
}
|
||||||
|
arg opt_nl ':'
|
||||||
|
{
|
||||||
|
cond_stack = $<val>3;
|
||||||
|
}
|
||||||
|
arg
|
||||||
{
|
{
|
||||||
/*%%%*/
|
/*%%%*/
|
||||||
value_expr($1);
|
value_expr($1);
|
||||||
$$ = NEW_IF(cond($1), $3, $6);
|
$$ = NEW_IF(cond($1), $4, $8);
|
||||||
fixpos($$, $1);
|
fixpos($$, $1);
|
||||||
/*%
|
/*%
|
||||||
$$ = dispatch3(ifop, $1, $3, $6);
|
$$ = dispatch3(ifop, $1, $4, $8);
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
| primary
|
| primary
|
||||||
|
@ -4217,6 +4227,9 @@ string_content : tSTRING_CONTENT
|
||||||
{
|
{
|
||||||
$<node>$ = lex_strterm;
|
$<node>$ = lex_strterm;
|
||||||
lex_strterm = 0;
|
lex_strterm = 0;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
$<num>$ = lex_state;
|
||||||
lex_state = EXPR_BEG;
|
lex_state = EXPR_BEG;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -4228,12 +4241,13 @@ string_content : tSTRING_CONTENT
|
||||||
cond_stack = $<val>1;
|
cond_stack = $<val>1;
|
||||||
cmdarg_stack = $<val>2;
|
cmdarg_stack = $<val>2;
|
||||||
lex_strterm = $<node>3;
|
lex_strterm = $<node>3;
|
||||||
brace_nest = $<num>4;
|
lex_state = $<num>4;
|
||||||
|
brace_nest = $<num>5;
|
||||||
/*%%%*/
|
/*%%%*/
|
||||||
if ($5) $5->flags &= ~NODE_FL_NEWLINE;
|
if ($6) $6->flags &= ~NODE_FL_NEWLINE;
|
||||||
$$ = new_evstr($5);
|
$$ = new_evstr($6);
|
||||||
/*%
|
/*%
|
||||||
$$ = dispatch1(string_embexpr, $5);
|
$$ = dispatch1(string_embexpr, $6);
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -4947,6 +4961,14 @@ assoc : arg_value tASSOC arg_value
|
||||||
$$ = dispatch2(assoc_new, $1, $2);
|
$$ = dispatch2(assoc_new, $1, $2);
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
|
| tSTRING_BEG string_contents tLABEL_END arg_value
|
||||||
|
{
|
||||||
|
/*%%%*/
|
||||||
|
$$ = list_append(NEW_LIST(dsym_node($2)), $4);
|
||||||
|
/*%
|
||||||
|
$$ = dispatch2(assoc_new, dispatch1(dyna_symbol, $2), $4);
|
||||||
|
%*/
|
||||||
|
}
|
||||||
| tDSTAR arg_value
|
| tDSTAR arg_value
|
||||||
{
|
{
|
||||||
/*%%%*/
|
/*%%%*/
|
||||||
|
@ -7653,7 +7675,14 @@ parser_yylex(struct parser_params *parser)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
token = parse_string(lex_strterm);
|
token = parse_string(lex_strterm);
|
||||||
if (token == tSTRING_END || token == tREGEXP_END) {
|
if (token == tSTRING_END && (peek_n('\'', -1) || peek_n('"', -1))) {
|
||||||
|
if (((IS_lex_state(EXPR_BEG | EXPR_ENDFN) && !COND_P()) || IS_ARG()) &&
|
||||||
|
IS_LABEL_SUFFIX(0)) {
|
||||||
|
nextc();
|
||||||
|
token = tLABEL_END;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (token == tSTRING_END || token == tREGEXP_END || token == tLABEL_END) {
|
||||||
rb_gc_force_recycle((VALUE)lex_strterm);
|
rb_gc_force_recycle((VALUE)lex_strterm);
|
||||||
lex_strterm = 0;
|
lex_strterm = 0;
|
||||||
lex_state = EXPR_END;
|
lex_state = EXPR_END;
|
||||||
|
|
|
@ -548,6 +548,10 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
|
||||||
thru_dyna_symbol = false
|
thru_dyna_symbol = false
|
||||||
parse(':"#{foo}"', :on_dyna_symbol) {thru_dyna_symbol = true}
|
parse(':"#{foo}"', :on_dyna_symbol) {thru_dyna_symbol = true}
|
||||||
assert_equal true, thru_dyna_symbol
|
assert_equal true, thru_dyna_symbol
|
||||||
|
|
||||||
|
thru_dyna_symbol = false
|
||||||
|
parse('{"#{foo}": 1}', :on_dyna_symbol) {thru_dyna_symbol = true}
|
||||||
|
assert_equal true, thru_dyna_symbol
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_else
|
def test_else
|
||||||
|
|
|
@ -878,6 +878,11 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase
|
||||||
scan('label', '{foo: 1}')
|
scan('label', '{foo: 1}')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_label_end
|
||||||
|
assert_equal %w(":),
|
||||||
|
scan('label_end', '{"foo-bar": 1}')
|
||||||
|
end
|
||||||
|
|
||||||
def test_tlambda
|
def test_tlambda
|
||||||
assert_equal %w(->),
|
assert_equal %w(->),
|
||||||
scan('tlambda', '->{}')
|
scan('tlambda', '->{}')
|
||||||
|
|
|
@ -1269,6 +1269,17 @@ class TestHash < Test::Unit::TestCase
|
||||||
assert_equal(bug9381, hash[wrapper.new(5)])
|
assert_equal(bug9381, hash[wrapper.new(5)])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_label_syntax
|
||||||
|
return unless @cls == Hash
|
||||||
|
|
||||||
|
feature4935 = '[ruby-core:37553] [Feature #4935]'
|
||||||
|
x = 'world'
|
||||||
|
hash = assert_nothing_raised(SyntaxError) do
|
||||||
|
break eval(%q({foo: 1, "foo-bar": 2, "hello-#{x}": 3, 'hello-#{x}': 4}))
|
||||||
|
end
|
||||||
|
assert_equal({:foo => 1, :'foo-bar' => 2, :'hello-world' => 3, :'hello-#{x}' => 4}, hash)
|
||||||
|
end
|
||||||
|
|
||||||
class TestSubHash < TestHash
|
class TestSubHash < TestHash
|
||||||
class SubHash < Hash
|
class SubHash < Hash
|
||||||
def reject(*)
|
def reject(*)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче