[ruby/yarp] Handle pound terminator in isolation

https://github.com/ruby/yarp/commit/1cfce46107
This commit is contained in:
Kevin Newton 2023-07-31 09:33:01 -04:00 committed by Takashi Kokubun
parent ede55edbd5
commit 86b32dac92
Notes: git 2023-08-17 00:48:16 +00:00

View File

@ -6645,10 +6645,13 @@ parser_lex(yp_parser_t *parser) {
LEX(YP_TOKEN_EOF); LEX(YP_TOKEN_EOF);
} }
// Get a reference to the current mode.
yp_lex_mode_t *mode = parser->lex_modes.current;
// These are the places where we need to split up the content of the // These are the places where we need to split up the content of the
// regular expression. We'll use strpbrk to find the first of these // regular expression. We'll use strpbrk to find the first of these
// characters. // characters.
const char *breakpoints = parser->lex_modes.current->as.regexp.breakpoints; const char *breakpoints = mode->as.regexp.breakpoints;
const char *breakpoint = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); const char *breakpoint = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end);
while (breakpoint != NULL) { while (breakpoint != NULL) {
@ -6673,14 +6676,15 @@ parser_lex(yp_parser_t *parser) {
break; break;
} }
case '#': { case '#': {
yp_token_type_t type = lex_interpolation(parser, breakpoint); // If the terminator is #, then we need to fall into the
if (type != YP_TOKEN_NOT_PROVIDED) { // default case. Otherwise we'll attempt to lex
LEX(type); // interpolation.
} if (mode->as.regexp.terminator != '#') {
yp_token_type_t type = lex_interpolation(parser, breakpoint);
if (type != YP_TOKEN_NOT_PROVIDED) {
LEX(type);
}
// We need to check if the terminator was # before skipping over
// to the next breakpoint
if (parser->lex_modes.current->as.regexp.terminator != '#') {
// If we haven't returned at this point then we had something // If we haven't returned at this point then we had something
// that looked like an interpolated class or instance variable // that looked like an interpolated class or instance variable
// like "#@" but wasn't actually. In this case we'll just skip // like "#@" but wasn't actually. In this case we'll just skip
@ -6691,11 +6695,11 @@ parser_lex(yp_parser_t *parser) {
} }
/* fallthrough */ /* fallthrough */
default: { default: {
if (*breakpoint == parser->lex_modes.current->as.regexp.incrementor) { if (*breakpoint == mode->as.regexp.incrementor) {
// If we've hit the incrementor, then we need to skip past it and // If we've hit the incrementor, then we need to skip past it and
// find the next breakpoint. // find the next breakpoint.
breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1));
parser->lex_modes.current->as.regexp.nesting++; mode->as.regexp.nesting++;
break; break;
} }
@ -6704,7 +6708,7 @@ parser_lex(yp_parser_t *parser) {
// that in the list of newlines. // that in the list of newlines.
yp_newline_list_append(&parser->newline_list, breakpoint); yp_newline_list_append(&parser->newline_list, breakpoint);
if (parser->lex_modes.current->as.regexp.terminator != '\n') { if (mode->as.regexp.terminator != '\n') {
// If the terminator is not a newline, then we // If the terminator is not a newline, then we
// can set the next breakpoint and continue. // can set the next breakpoint and continue.
breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1));
@ -6715,11 +6719,11 @@ parser_lex(yp_parser_t *parser) {
// terminator so we need to continue on. // terminator so we need to continue on.
} }
assert(*breakpoint == parser->lex_modes.current->as.regexp.terminator); assert(*breakpoint == mode->as.regexp.terminator);
if (parser->lex_modes.current->as.regexp.nesting > 0) { if (mode->as.regexp.nesting > 0) {
breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1));
parser->lex_modes.current->as.regexp.nesting--; mode->as.regexp.nesting--;
break; break;
} }