зеркало из https://github.com/github/ruby.git
[ruby/prism] Fix up find and array patterns with multiple rests
https://github.com/ruby/prism/commit/035890a839
This commit is contained in:
Родитель
8fb2227205
Коммит
0ac9c6dc10
|
@ -208,6 +208,7 @@ errors:
|
||||||
- PARAMETER_UNEXPECTED_FWD
|
- PARAMETER_UNEXPECTED_FWD
|
||||||
- PARAMETER_UNEXPECTED_NO_KW
|
- PARAMETER_UNEXPECTED_NO_KW
|
||||||
- PARAMETER_WILD_LOOSE_COMMA
|
- PARAMETER_WILD_LOOSE_COMMA
|
||||||
|
- PATTERN_ARRAY_MULTIPLE_RESTS
|
||||||
- PATTERN_CAPTURE_DUPLICATE
|
- PATTERN_CAPTURE_DUPLICATE
|
||||||
- PATTERN_EXPRESSION_AFTER_BRACKET
|
- PATTERN_EXPRESSION_AFTER_BRACKET
|
||||||
- PATTERN_EXPRESSION_AFTER_COMMA
|
- PATTERN_EXPRESSION_AFTER_COMMA
|
||||||
|
@ -219,6 +220,7 @@ errors:
|
||||||
- PATTERN_EXPRESSION_AFTER_PIPE
|
- PATTERN_EXPRESSION_AFTER_PIPE
|
||||||
- PATTERN_EXPRESSION_AFTER_RANGE
|
- PATTERN_EXPRESSION_AFTER_RANGE
|
||||||
- PATTERN_EXPRESSION_AFTER_REST
|
- PATTERN_EXPRESSION_AFTER_REST
|
||||||
|
- PATTERN_FIND_MISSING_INNER
|
||||||
- PATTERN_HASH_IMPLICIT
|
- PATTERN_HASH_IMPLICIT
|
||||||
- PATTERN_HASH_KEY
|
- PATTERN_HASH_KEY
|
||||||
- PATTERN_HASH_KEY_DUPLICATE
|
- PATTERN_HASH_KEY_DUPLICATE
|
||||||
|
|
|
@ -17049,9 +17049,9 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flag
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & PM_PARSE_PATTERN_MULTI) && match1(parser, PM_TOKEN_COMMA)) {
|
if ((flags & PM_PARSE_PATTERN_MULTI) && match1(parser, PM_TOKEN_COMMA)) {
|
||||||
// If we have a comma, then we are now parsing either an array pattern or a
|
// If we have a comma, then we are now parsing either an array pattern
|
||||||
// find pattern. We need to parse all of the patterns, put them into a big
|
// or a find pattern. We need to parse all of the patterns, put them
|
||||||
// list, and then determine which type of node we have.
|
// into a big list, and then determine which type of node we have.
|
||||||
pm_node_list_t nodes = { 0 };
|
pm_node_list_t nodes = { 0 };
|
||||||
pm_node_list_append(&nodes, node);
|
pm_node_list_append(&nodes, node);
|
||||||
|
|
||||||
|
@ -17067,9 +17067,9 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flag
|
||||||
if (accept1(parser, PM_TOKEN_USTAR)) {
|
if (accept1(parser, PM_TOKEN_USTAR)) {
|
||||||
node = (pm_node_t *) parse_pattern_rest(parser, captures);
|
node = (pm_node_t *) parse_pattern_rest(parser, captures);
|
||||||
|
|
||||||
// If we have already parsed a splat pattern, then this is an error. We
|
// If we have already parsed a splat pattern, then this is an
|
||||||
// will continue to parse the rest of the patterns, but we will indicate
|
// error. We will continue to parse the rest of the patterns,
|
||||||
// it as an error.
|
// but we will indicate it as an error.
|
||||||
if (trailing_rest) {
|
if (trailing_rest) {
|
||||||
pm_parser_err_previous(parser, PM_ERR_PATTERN_REST);
|
pm_parser_err_previous(parser, PM_ERR_PATTERN_REST);
|
||||||
}
|
}
|
||||||
|
@ -17082,20 +17082,28 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flag
|
||||||
pm_node_list_append(&nodes, node);
|
pm_node_list_append(&nodes, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the first pattern and the last pattern are rest patterns, then we will
|
// If the first pattern and the last pattern are rest patterns, then we
|
||||||
// call this a find pattern, regardless of how many rest patterns are in
|
// will call this a find pattern, regardless of how many rest patterns
|
||||||
// between because we know we already added the appropriate errors.
|
// are in between because we know we already added the appropriate
|
||||||
// Otherwise we will create an array pattern.
|
// errors. Otherwise we will create an array pattern.
|
||||||
if (PM_NODE_TYPE_P(nodes.nodes[0], PM_SPLAT_NODE) && PM_NODE_TYPE_P(nodes.nodes[nodes.size - 1], PM_SPLAT_NODE)) {
|
if (leading_rest && PM_NODE_TYPE_P(nodes.nodes[nodes.size - 1], PM_SPLAT_NODE)) {
|
||||||
node = (pm_node_t *) pm_find_pattern_node_create(parser, &nodes);
|
node = (pm_node_t *) pm_find_pattern_node_create(parser, &nodes);
|
||||||
|
|
||||||
|
if (nodes.size == 2) {
|
||||||
|
pm_parser_err_node(parser, node, PM_ERR_PATTERN_FIND_MISSING_INNER);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
node = (pm_node_t *) pm_array_pattern_node_node_list_create(parser, &nodes);
|
node = (pm_node_t *) pm_array_pattern_node_node_list_create(parser, &nodes);
|
||||||
|
|
||||||
|
if (leading_rest && trailing_rest) {
|
||||||
|
pm_parser_err_node(parser, node, PM_ERR_PATTERN_ARRAY_MULTIPLE_RESTS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xfree(nodes.nodes);
|
xfree(nodes.nodes);
|
||||||
} else if (leading_rest) {
|
} else if (leading_rest) {
|
||||||
// Otherwise, if we parsed a single splat pattern, then we know we have an
|
// Otherwise, if we parsed a single splat pattern, then we know we have
|
||||||
// array pattern, so we can go ahead and create that node.
|
// an array pattern, so we can go ahead and create that node.
|
||||||
node = (pm_node_t *) pm_array_pattern_node_rest_create(parser, node);
|
node = (pm_node_t *) pm_array_pattern_node_rest_create(parser, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -290,6 +290,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
|
||||||
[PM_ERR_PARAMETER_UNEXPECTED_FWD] = { "unexpected `...` in parameters", PM_ERROR_LEVEL_SYNTAX },
|
[PM_ERR_PARAMETER_UNEXPECTED_FWD] = { "unexpected `...` in parameters", PM_ERROR_LEVEL_SYNTAX },
|
||||||
[PM_ERR_PARAMETER_WILD_LOOSE_COMMA] = { "unexpected `,` in parameters", PM_ERROR_LEVEL_SYNTAX },
|
[PM_ERR_PARAMETER_WILD_LOOSE_COMMA] = { "unexpected `,` in parameters", PM_ERROR_LEVEL_SYNTAX },
|
||||||
[PM_ERR_PARAMETER_UNEXPECTED_NO_KW] = { "unexpected **nil; no keywords marker disallowed after keywords", PM_ERROR_LEVEL_SYNTAX },
|
[PM_ERR_PARAMETER_UNEXPECTED_NO_KW] = { "unexpected **nil; no keywords marker disallowed after keywords", PM_ERROR_LEVEL_SYNTAX },
|
||||||
|
[PM_ERR_PATTERN_ARRAY_MULTIPLE_RESTS] = { "unexpected multiple '*' rest patterns in an array pattern", PM_ERROR_LEVEL_SYNTAX },
|
||||||
[PM_ERR_PATTERN_CAPTURE_DUPLICATE] = { "duplicated variable name", PM_ERROR_LEVEL_SYNTAX },
|
[PM_ERR_PATTERN_CAPTURE_DUPLICATE] = { "duplicated variable name", PM_ERROR_LEVEL_SYNTAX },
|
||||||
[PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET] = { "expected a pattern expression after the `[` operator", PM_ERROR_LEVEL_SYNTAX },
|
[PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET] = { "expected a pattern expression after the `[` operator", PM_ERROR_LEVEL_SYNTAX },
|
||||||
[PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA] = { "expected a pattern expression after `,`", PM_ERROR_LEVEL_SYNTAX },
|
[PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA] = { "expected a pattern expression after `,`", PM_ERROR_LEVEL_SYNTAX },
|
||||||
|
@ -301,6 +302,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
|
||||||
[PM_ERR_PATTERN_EXPRESSION_AFTER_PIPE] = { "expected a pattern expression after the `|` operator", PM_ERROR_LEVEL_SYNTAX },
|
[PM_ERR_PATTERN_EXPRESSION_AFTER_PIPE] = { "expected a pattern expression after the `|` operator", PM_ERROR_LEVEL_SYNTAX },
|
||||||
[PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE] = { "expected a pattern expression after the range operator", PM_ERROR_LEVEL_SYNTAX },
|
[PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE] = { "expected a pattern expression after the range operator", PM_ERROR_LEVEL_SYNTAX },
|
||||||
[PM_ERR_PATTERN_EXPRESSION_AFTER_REST] = { "unexpected pattern expression after the `**` expression", PM_ERROR_LEVEL_SYNTAX },
|
[PM_ERR_PATTERN_EXPRESSION_AFTER_REST] = { "unexpected pattern expression after the `**` expression", PM_ERROR_LEVEL_SYNTAX },
|
||||||
|
[PM_ERR_PATTERN_FIND_MISSING_INNER] = { "find patterns need at least one required inner pattern", PM_ERROR_LEVEL_SYNTAX },
|
||||||
[PM_ERR_PATTERN_HASH_IMPLICIT] = { "unexpected implicit hash in pattern; use '{' to delineate", PM_ERROR_LEVEL_SYNTAX },
|
[PM_ERR_PATTERN_HASH_IMPLICIT] = { "unexpected implicit hash in pattern; use '{' to delineate", PM_ERROR_LEVEL_SYNTAX },
|
||||||
[PM_ERR_PATTERN_HASH_KEY] = { "unexpected %s; expected a key in the hash pattern", PM_ERROR_LEVEL_SYNTAX },
|
[PM_ERR_PATTERN_HASH_KEY] = { "unexpected %s; expected a key in the hash pattern", PM_ERROR_LEVEL_SYNTAX },
|
||||||
[PM_ERR_PATTERN_HASH_KEY_DUPLICATE] = { "duplicated key name", PM_ERROR_LEVEL_SYNTAX },
|
[PM_ERR_PATTERN_HASH_KEY_DUPLICATE] = { "duplicated key name", PM_ERROR_LEVEL_SYNTAX },
|
||||||
|
|
Загрузка…
Ссылка в новой задаче