[ruby/yarp] Handle infinite opt terms after missing case predicate

https://github.com/ruby/yarp/commit/d931e258d1
This commit is contained in:
Kevin Newton 2023-09-15 11:13:11 -04:00 коммит произвёл git
Родитель bbf9f11ce6
Коммит ffe77c022c
3 изменённых файлов: 49 добавлений и 34 удалений

Просмотреть файл

@ -28,3 +28,5 @@ case type;
;when :b;
; else;
end
case ;;;;;;;; when 1; end

Просмотреть файл

@ -1,8 +1,8 @@
@ ProgramNode (location: (0...272))
@ ProgramNode (location: (0...299))
├── locals: []
└── statements:
@ StatementsNode (location: (0...272))
└── body: (length: 8)
@ StatementsNode (location: (0...299))
└── body: (length: 9)
├── @ CaseNode (location: (0...21))
│ ├── predicate:
│ │ @ SymbolNode (location: (5...8))
@ -222,32 +222,44 @@
│ │ └── end_keyword_loc: (227...230) = "end"
│ ├── case_keyword_loc: (200...204) = "case"
│ └── end_keyword_loc: (227...230) = "end"
└── @ CaseNode (location: (232...272))
├── predicate:
│ @ CallNode (location: (237...241))
│ ├── receiver: ∅
│ ├── call_operator_loc: ∅
│ ├── message_loc: (237...241) = "type"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── block: ∅
│ ├── flags: variable_call
│ └── name: "type"
├── @ CaseNode (location: (232...272))
│ ├── predicate:
│ │ @ CallNode (location: (237...241))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (237...241) = "type"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: "type"
│ ├── conditions: (length: 1)
│ │ └── @ WhenNode (location: (246...253))
│ │ ├── keyword_loc: (246...250) = "when"
│ │ ├── conditions: (length: 1)
│ │ │ └── @ SymbolNode (location: (251...253))
│ │ │ ├── opening_loc: (251...252) = ":"
│ │ │ ├── value_loc: (252...253) = "b"
│ │ │ ├── closing_loc: ∅
│ │ │ └── unescaped: "b"
│ │ └── statements: ∅
│ ├── consequent:
│ │ @ ElseNode (location: (260...272))
│ │ ├── else_keyword_loc: (260...264) = "else"
│ │ ├── statements: ∅
│ │ └── end_keyword_loc: (269...272) = "end"
│ ├── case_keyword_loc: (232...236) = "case"
│ └── end_keyword_loc: (269...272) = "end"
└── @ CaseNode (location: (274...299))
├── predicate: ∅
├── conditions: (length: 1)
│ └── @ WhenNode (location: (246...253))
│ ├── keyword_loc: (246...250) = "when"
│ └── @ WhenNode (location: (288...294))
│ ├── keyword_loc: (288...292) = "when"
│ ├── conditions: (length: 1)
│ │ └── @ SymbolNode (location: (251...253))
│ │ ├── opening_loc: (251...252) = ":"
│ │ ├── value_loc: (252...253) = "b"
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "b"
│ │ └── @ IntegerNode (location: (293...294))
│ │ └── flags: decimal
│ └── statements: ∅
├── consequent:
│ @ ElseNode (location: (260...272))
│ ├── else_keyword_loc: (260...264) = "else"
│ ├── statements: ∅
│ └── end_keyword_loc: (269...272) = "end"
├── case_keyword_loc: (232...236) = "case"
└── end_keyword_loc: (269...272) = "end"
├── consequent: ∅
├── case_keyword_loc: (274...278) = "case"
└── end_keyword_loc: (296...299) = "end"

Просмотреть файл

@ -11810,11 +11810,12 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
yp_token_t case_keyword = parser->previous;
yp_node_t *predicate = NULL;
if (
accept2(parser, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON) ||
match3(parser, YP_TOKEN_KEYWORD_WHEN, YP_TOKEN_KEYWORD_IN, YP_TOKEN_KEYWORD_END) ||
!token_begins_expression_p(parser->current.type)
) {
if (accept2(parser, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)) {
while (accept2(parser, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON));
predicate = NULL;
} else if (match3(parser, YP_TOKEN_KEYWORD_WHEN, YP_TOKEN_KEYWORD_IN, YP_TOKEN_KEYWORD_END)) {
predicate = NULL;
} else if (!token_begins_expression_p(parser->current.type)) {
predicate = NULL;
} else {
predicate = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_CASE_EXPRESSION_AFTER_CASE);