From 3d7ee499a3499eac0e868efaf529f18ee67a2c76 Mon Sep 17 00:00:00 2001 From: Michael Camilleri Date: Tue, 18 Feb 2020 14:44:49 +0900 Subject: [PATCH] Improve regex and string lexing in CoffeeScript lexer (#1441) This commit improves the way that the CoffeeScript lexer lexes regular expressions and strings (in particular the way that escaping is handled). --- lib/rouge/lexers/coffeescript.rb | 62 ++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/lib/rouge/lexers/coffeescript.rb b/lib/rouge/lexers/coffeescript.rb index af5ee8cf7a..032943b931 100644 --- a/lib/rouge/lexers/coffeescript.rb +++ b/lib/rouge/lexers/coffeescript.rb @@ -49,33 +49,54 @@ def self.builtins id = /[$a-zA-Z_][a-zA-Z0-9_]*/ - state :comments_and_whitespace do - rule %r/\s+/m, Text + state :comments do rule %r/###[^#].*?###/m, Comment::Multiline rule %r/#.*$/, Comment::Single end - state :multiline_regex do - # this order is important, so that #{ isn't interpreted - # as a comment - mixin :has_interpolation - mixin :comments_and_whitespace + state :whitespace do + rule %r/\s+/m, Text + end - rule %r(///([gim]+\b|\B)), Str::Regex, :pop! - rule %r(/), Str::Regex - rule %r([^/#]+), Str::Regex + state :regex_comment do + rule %r/^#(?!\{).*$/, Comment::Single + rule %r/(\s+)(#(?!\{).*)$/ do + groups Text, Comment::Single + end end - state :slash_starts_regex do - mixin :comments_and_whitespace + state :multiline_regex_begin do rule %r(///) do token Str::Regex goto :multiline_regex end + end + + state :multiline_regex_end do + rule %r(///([gimy]+\b|\B)), Str::Regex, :pop! + end + + state :multiline_regex do + mixin :multiline_regex_end + mixin :regex_comment + mixin :has_interpolation + mixin :comments + mixin :whitespace + mixin :code_escape + + rule %r/\\\D/, Str::Escape + rule %r/\\\d+/, Name::Variable + rule %r/./m, Str::Regex + end + + state :slash_starts_regex do + mixin :comments + mixin :whitespace + mixin :multiline_regex_begin rule %r( /(\\.|[^\[/\\\n]|\[(\\.|[^\]\\\n])*\])+/ # a regex - ([gim]+\b|\B) + ([gimy]+\b|\B) )x, Str::Regex, :pop! rule(//) { pop! } @@ -83,7 +104,9 @@ def self.builtins state :root do rule(%r(^(?=\s|/|