Skip to content

Commit 27c71a2

Browse files
Fix lexing MacroVar syntax in literal
1 parent 004e037 commit 27c71a2

File tree

2 files changed

+15
-15
lines changed

2 files changed

+15
-15
lines changed

spec/compiler/parser/parser_spec.cr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,9 @@ module Crystal
146146
it_parses %(macro foo\n%q(%t{)\nend), Macro.new("foo", body: Expressions.from(["%q(%t".macro_literal, "{)\n".macro_literal] of ASTNode))
147147
it_parses %(macro foo\n%(%t{)\nend), Macro.new("foo", body: Expressions.from(["%(%t".macro_literal, "{)\n".macro_literal] of ASTNode))
148148

149-
assert_syntax_error %({% begin %}\n%q(%t{})\n{% end %}), %(unexpected token: "}") # #16772
149+
it_parses %({% begin %}\n%q(%t{})\n{% end %}), MacroIf.new(true.bool, Expressions.from(["\n".macro_literal, "%q(%t".macro_literal, "{})\n".macro_literal] of ASTNode))
150150
it_parses %({% begin %}\n%(%t{})\n{% end %}), MacroIf.new(true.bool, Expressions.from(["\n%(%t".macro_literal, "{})\n".macro_literal] of ASTNode))
151-
assert_syntax_error %({% begin %}\n%q(%t{)\n{% end %}), %{unexpected token: ")"}
151+
it_parses %({% begin %}\n%q(%t{)\n{% end %}), MacroIf.new(true.bool, Expressions.from(["\n".macro_literal, "%q(%t".macro_literal, "{)\n".macro_literal] of ASTNode))
152152
it_parses %({% begin %}\n%(%t{)\n{% end %}), MacroIf.new(true.bool, Expressions.from(["\n%(%t".macro_literal, "{)\n".macro_literal] of ASTNode))
153153

154154
it_parses ":foo", "foo".symbol

src/compiler/crystal/syntax/lexer.cr

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1898,19 +1898,19 @@ module Crystal
18981898
end
18991899
whitespace = false
19001900
when '%'
1901-
case char = peek_next_char
1902-
when '(', '[', '<', '{', '|'
1903-
next_char
1904-
delimiter_state = Token::DelimiterState.new(:string, char, closing_char)
1905-
else
1906-
whitespace = false
1907-
# Don't break if this looks like a prefixed percent literal that will
1908-
# be handled before the main loop (e.g., %Q|...|, %w|...|, etc.)
1909-
if !delimiter_state && ident_start?(char)
1910-
is_percent_literal =
1911-
char.in?('q', 'Q', 'w', 'i', 'r', 'x') &&
1912-
lookahead { next_char; peek_next_char.in?('(', '<', '[', '{', '|') }
1913-
break unless is_percent_literal
1901+
if !delimiter_state
1902+
case char = peek_next_char
1903+
when '(', '[', '<', '{', '|'
1904+
next_char
1905+
delimiter_state = Token::DelimiterState.new(:string, char, closing_char)
1906+
else
1907+
whitespace = false
1908+
# Don't break if this looks like a prefixed percent literal that will
1909+
# be handled before the main loop (e.g., %Q|...|, %w|...|, etc.)
1910+
if !delimiter_state && ident_start?(char)
1911+
# This looks like a macro var or a percent literal. Both are handled further above.
1912+
break
1913+
end
19141914
end
19151915
end
19161916
when '#'

0 commit comments

Comments
 (0)