@@ -6985,6 +6985,16 @@ is_identchar(struct parser_params *p, const char *ptr, const char *MAYBE_UNUSED(
69856985 return rb_enc_isalnum((unsigned char)*ptr, enc) || *ptr == '_' || !ISASCII(*ptr);
69866986}
69876987
6988+ static inline bool
6989+ peek_word_at(struct parser_params *p, const char *str, int at)
6990+ {
6991+ size_t len = strlen(str);
6992+ const char *ptr = p->lex.pcur + at;
6993+ if (lex_eol_ptr_n_p(p, ptr, len-1)) return false;
6994+ if (memcmp(ptr, str, len)) return false;
6995+ return !is_identchar(p, ptr, p->lex.pend, p->enc);
6996+ }
6997+
69886998static inline int
69896999parser_is_identchar(struct parser_params *p)
69907000{
@@ -10556,7 +10566,24 @@ parser_yylex(struct parser_params *p)
1055610566 token_flush(p);
1055710567 }
1055810568 goto retry;
10569+ case 'a':
10570+ if (peek_word_at(p, "nd", 0)) goto leading_logical;
10571+ goto bol;
10572+ case 'o':
10573+ if (peek_word_at(p, "r", 0)) goto leading_logical;
10574+ goto bol;
10575+ case '|':
10576+ if (peek(p, '|')) goto leading_logical;
10577+ goto bol;
1055910578 case '&':
10579+ if (peek(p, '&')) {
10580+ leading_logical:
10581+ pushback(p, c);
10582+ dispatch_delayed_token(p, tIGNORED_NL);
10583+ cmd_state = FALSE;
10584+ goto retry;
10585+ }
10586+ /* fall through */
1056010587 case '.': {
1056110588 dispatch_delayed_token(p, tIGNORED_NL);
1056210589 if (peek(p, '.') == (c == '&')) {
@@ -10565,6 +10592,7 @@ parser_yylex(struct parser_params *p)
1056510592 goto retry;
1056610593 }
1056710594 }
10595+ bol:
1056810596 default:
1056910597 p->ruby_sourceline--;
1057010598 p->lex.nextline = p->lex.lastline;
0 commit comments