crystal.go

  1package c
  2
  3import (
  4	. "github.com/alecthomas/chroma" // nolint
  5	"github.com/alecthomas/chroma/lexers/internal"
  6)
  7
  8// Crystal lexer.
  9var Crystal = internal.Register(MustNewLexer(
 10	&Config{
 11		Name:      "Crystal",
 12		Aliases:   []string{"cr", "crystal"},
 13		Filenames: []string{"*.cr"},
 14		MimeTypes: []string{"text/x-crystal"},
 15		DotAll:    true,
 16	},
 17	Rules{
 18		"root": {
 19			{`#.*?$`, CommentSingle, nil},
 20			{Words(``, `\b`, `abstract`, `asm`, `as`, `begin`, `break`, `case`, `do`, `else`, `elsif`, `end`, `ensure`, `extend`, `ifdef`, `if`, `include`, `instance_sizeof`, `next`, `of`, `pointerof`, `private`, `protected`, `rescue`, `return`, `require`, `sizeof`, `super`, `then`, `typeof`, `unless`, `until`, `when`, `while`, `with`, `yield`), Keyword, nil},
 21			{Words(``, `\b`, `true`, `false`, `nil`), KeywordConstant, nil},
 22			{`(module|lib)(\s+)([a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*)`, ByGroups(Keyword, Text, NameNamespace), nil},
 23			{`(def|fun|macro)(\s+)((?:[a-zA-Z_]\w*::)*)`, ByGroups(Keyword, Text, NameNamespace), Push("funcname")},
 24			{"def(?=[*%&^`~+-/\\[<>=])", Keyword, Push("funcname")},
 25			{`(class|struct|union|type|alias|enum)(\s+)((?:[a-zA-Z_]\w*::)*)`, ByGroups(Keyword, Text, NameNamespace), Push("classname")},
 26			{`(self|out|uninitialized)\b|(is_a|responds_to)\?`, KeywordPseudo, nil},
 27			{Words(``, `\b`, `debugger`, `record`, `pp`, `assert_responds_to`, `spawn`, `parallel`, `getter`, `setter`, `property`, `delegate`, `def_hash`, `def_equals`, `def_equals_and_hash`, `forward_missing_to`), NameBuiltinPseudo, nil},
 28			{`getter[!?]|property[!?]|__(DIR|FILE|LINE)__\b`, NameBuiltinPseudo, nil},
 29			{Words(`(?<!\.)`, `\b`, `Object`, `Value`, `Struct`, `Reference`, `Proc`, `Class`, `Nil`, `Symbol`, `Enum`, `Void`, `Bool`, `Number`, `Int`, `Int8`, `Int16`, `Int32`, `Int64`, `UInt8`, `UInt16`, `UInt32`, `UInt64`, `Float`, `Float32`, `Float64`, `Char`, `String`, `Pointer`, `Slice`, `Range`, `Exception`, `Regex`, `Mutex`, `StaticArray`, `Array`, `Hash`, `Set`, `Tuple`, `Deque`, `Box`, `Process`, `File`, `Dir`, `Time`, `Channel`, `Concurrent`, `Scheduler`, `abort`, `at_exit`, `caller`, `delay`, `exit`, `fork`, `future`, `get_stack_top`, `gets`, `lazy`, `loop`, `main`, `p`, `print`, `printf`, `puts`, `raise`, `rand`, `read_line`, `sleep`, `sprintf`, `system`, `with_color`), NameBuiltin, nil},
 30			{"(?<!\\w)(<<-?)([\"`\\']?)([a-zA-Z_]\\w*)(\\2)(.*?\\n)", StringHeredoc, nil},
 31			{`(<<-?)("|\')()(\2)(.*?\n)`, StringHeredoc, nil},
 32			{`__END__`, CommentPreproc, Push("end-part")},
 33			{`(?:^|(?<=[=<>~!:])|(?<=(?:\s|;)when\s)|(?<=(?:\s|;)or\s)|(?<=(?:\s|;)and\s)|(?<=\.index\s)|(?<=\.scan\s)|(?<=\.sub\s)|(?<=\.sub!\s)|(?<=\.gsub\s)|(?<=\.gsub!\s)|(?<=\.match\s)|(?<=(?:\s|;)if\s)|(?<=(?:\s|;)elsif\s)|(?<=^when\s)|(?<=^index\s)|(?<=^scan\s)|(?<=^sub\s)|(?<=^gsub\s)|(?<=^sub!\s)|(?<=^gsub!\s)|(?<=^match\s)|(?<=^if\s)|(?<=^elsif\s))(\s*)(/)`, ByGroups(Text, LiteralStringRegex), Push("multiline-regex")},
 34			{`(?<=\(|,|\[)/`, LiteralStringRegex, Push("multiline-regex")},
 35			{`(\s+)(/)(?![\s=])`, ByGroups(Text, LiteralStringRegex), Push("multiline-regex")},
 36			{`(0o[0-7]+(?:_[0-7]+)*(?:_?[iu][0-9]+)?)\b(\s*)([/?])?`, ByGroups(LiteralNumberOct, Text, Operator), nil},
 37			{`(0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*(?:_?[iu][0-9]+)?)\b(\s*)([/?])?`, ByGroups(LiteralNumberHex, Text, Operator), nil},
 38			{`(0b[01]+(?:_[01]+)*(?:_?[iu][0-9]+)?)\b(\s*)([/?])?`, ByGroups(LiteralNumberBin, Text, Operator), nil},
 39			{`((?:0(?![0-9])|[1-9][\d_]*)(?:\.\d[\d_]*)(?:e[+-]?[0-9]+)?(?:_?f[0-9]+)?)(\s*)([/?])?`, ByGroups(LiteralNumberFloat, Text, Operator), nil},
 40			{`((?:0(?![0-9])|[1-9][\d_]*)(?:\.\d[\d_]*)?(?:e[+-]?[0-9]+)(?:_?f[0-9]+)?)(\s*)([/?])?`, ByGroups(LiteralNumberFloat, Text, Operator), nil},
 41			{`((?:0(?![0-9])|[1-9][\d_]*)(?:\.\d[\d_]*)?(?:e[+-]?[0-9]+)?(?:_?f[0-9]+))(\s*)([/?])?`, ByGroups(LiteralNumberFloat, Text, Operator), nil},
 42			{`(0\b|[1-9][\d]*(?:_\d+)*(?:_?[iu][0-9]+)?)\b(\s*)([/?])?`, ByGroups(LiteralNumberInteger, Text, Operator), nil},
 43			{`@@[a-zA-Z_]\w*`, NameVariableClass, nil},
 44			{`@[a-zA-Z_]\w*`, NameVariableInstance, nil},
 45			{`\$\w+`, NameVariableGlobal, nil},
 46			{"\\$[!@&`\\'+~=/\\\\,;.<>_*$?:\"^-]", NameVariableGlobal, nil},
 47			{`\$-[0adFiIlpvw]`, NameVariableGlobal, nil},
 48			{`::`, Operator, nil},
 49			Include("strings"),
 50			{`\?(\\[MC]-)*(\\([\\befnrtv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})|\S)(?!\w)`, LiteralStringChar, nil},
 51			{`[A-Z][A-Z_]+\b`, NameConstant, nil},
 52			{`\{%`, LiteralStringInterpol, Push("in-macro-control")},
 53			{`\{\{`, LiteralStringInterpol, Push("in-macro-expr")},
 54			{`(@\[)(\s*)([A-Z]\w*)`, ByGroups(Operator, Text, NameDecorator), Push("in-attr")},
 55			{Words(`(\.|::)`, ``, `!=`, `!~`, `!`, `%`, `&&`, `&`, `**`, `*`, `+`, `-`, `/`, `<=>`, `<<`, `<=`, `<`, `===`, `==`, `=~`, `=`, `>=`, `>>`, `>`, `[]=`, `[]?`, `[]`, `^`, `||`, `|`, `~`), ByGroups(Operator, NameOperator), nil},
 56			{"(\\.|::)([a-zA-Z_]\\w*[!?]?|[*%&^`~+\\-/\\[<>=])", ByGroups(Operator, Name), nil},
 57			{`[a-zA-Z_]\w*(?:[!?](?!=))?`, Name, nil},
 58			{`(\[|\]\??|\*\*|<=>?|>=|<<?|>>?|=~|===|!~|&&?|\|\||\.{1,3})`, Operator, nil},
 59			{`[-+/*%=<>&!^|~]=?`, Operator, nil},
 60			{`[(){};,/?:\\]`, Punctuation, nil},
 61			{`\s+`, Text, nil},
 62		},
 63		"funcname": {
 64			{"(?:([a-zA-Z_]\\w*)(\\.))?([a-zA-Z_]\\w*[!?]?|\\*\\*?|[-+]@?|[/%&|^`~]|\\[\\]=?|<<|>>|<=?>|>=?|===?)", ByGroups(NameClass, Operator, NameFunction), Pop(1)},
 65			Default(Pop(1)),
 66		},
 67		"classname": {
 68			{`[A-Z_]\w*`, NameClass, nil},
 69			{`(\()(\s*)([A-Z_]\w*)(\s*)(\))`, ByGroups(Punctuation, Text, NameClass, Text, Punctuation), nil},
 70			Default(Pop(1)),
 71		},
 72		"in-intp": {
 73			{`\{`, LiteralStringInterpol, Push()},
 74			{`\}`, LiteralStringInterpol, Pop(1)},
 75			Include("root"),
 76		},
 77		"string-intp": {
 78			{`#\{`, LiteralStringInterpol, Push("in-intp")},
 79		},
 80		"string-escaped": {
 81			{`\\([\\befnstv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})`, LiteralStringEscape, nil},
 82		},
 83		"string-intp-escaped": {
 84			Include("string-intp"),
 85			Include("string-escaped"),
 86		},
 87		"interpolated-regex": {
 88			Include("string-intp"),
 89			{`[\\#]`, LiteralStringRegex, nil},
 90			{`[^\\#]+`, LiteralStringRegex, nil},
 91		},
 92		"interpolated-string": {
 93			Include("string-intp"),
 94			{`[\\#]`, LiteralStringOther, nil},
 95			{`[^\\#]+`, LiteralStringOther, nil},
 96		},
 97		"multiline-regex": {
 98			Include("string-intp"),
 99			{`\\\\`, LiteralStringRegex, nil},
100			{`\\/`, LiteralStringRegex, nil},
101			{`[\\#]`, LiteralStringRegex, nil},
102			{`[^\\/#]+`, LiteralStringRegex, nil},
103			{`/[imsx]*`, LiteralStringRegex, Pop(1)},
104		},
105		"end-part": {
106			{`.+`, CommentPreproc, Pop(1)},
107		},
108		"in-macro-control": {
109			{`\{%`, LiteralStringInterpol, Push()},
110			{`%\}`, LiteralStringInterpol, Pop(1)},
111			{`for\b|in\b`, Keyword, nil},
112			Include("root"),
113		},
114		"in-macro-expr": {
115			{`\{\{`, LiteralStringInterpol, Push()},
116			{`\}\}`, LiteralStringInterpol, Pop(1)},
117			Include("root"),
118		},
119		"in-attr": {
120			{`\[`, Operator, Push()},
121			{`\]`, Operator, Pop(1)},
122			Include("root"),
123		},
124		"strings": {
125			{`\:@{0,2}[a-zA-Z_]\w*[!?]?`, LiteralStringSymbol, nil},
126			{Words(`\:@{0,2}`, ``, `!=`, `!~`, `!`, `%`, `&&`, `&`, `**`, `*`, `+`, `-`, `/`, `<=>`, `<<`, `<=`, `<`, `===`, `==`, `=~`, `=`, `>=`, `>>`, `>`, `[]=`, `[]?`, `[]`, `^`, `||`, `|`, `~`), LiteralStringSymbol, nil},
127			{`:'(\\\\|\\'|[^'])*'`, LiteralStringSymbol, nil},
128			{`'(\\\\|\\'|[^']|\\[^'\\]+)'`, LiteralStringChar, nil},
129			{`:"`, LiteralStringSymbol, Push("simple-sym")},
130			{`([a-zA-Z_]\w*)(:)(?!:)`, ByGroups(LiteralStringSymbol, Punctuation), nil},
131			{`"`, LiteralStringDouble, Push("simple-string")},
132			{"(?<!\\.)`", LiteralStringBacktick, Push("simple-backtick")},
133			{`%\{`, LiteralStringOther, Push("cb-intp-string")},
134			{`%[wi]\{`, LiteralStringOther, Push("cb-string")},
135			{`%r\{`, LiteralStringRegex, Push("cb-regex")},
136			{`%\[`, LiteralStringOther, Push("sb-intp-string")},
137			{`%[wi]\[`, LiteralStringOther, Push("sb-string")},
138			{`%r\[`, LiteralStringRegex, Push("sb-regex")},
139			{`%\(`, LiteralStringOther, Push("pa-intp-string")},
140			{`%[wi]\(`, LiteralStringOther, Push("pa-string")},
141			{`%r\(`, LiteralStringRegex, Push("pa-regex")},
142			{`%<`, LiteralStringOther, Push("ab-intp-string")},
143			{`%[wi]<`, LiteralStringOther, Push("ab-string")},
144			{`%r<`, LiteralStringRegex, Push("ab-regex")},
145			{`(%r([\W_]))((?:\\\2|(?!\2).)*)(\2[imsx]*)`, String, nil},
146			{`(%[wi]([\W_]))((?:\\\2|(?!\2).)*)(\2)`, String, nil},
147			{`(?<=[-+/*%=<>&!^|~,(])(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)`, ByGroups(Text, LiteralStringOther, None), nil},
148			{`^(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)`, ByGroups(Text, LiteralStringOther, None), nil},
149			{`(%([\[{(<]))((?:\\\2|(?!\2).)*)(\2)`, String, nil},
150		},
151		"simple-string": {
152			Include("string-intp-escaped"),
153			{`[^\\"#]+`, LiteralStringDouble, nil},
154			{`[\\#]`, LiteralStringDouble, nil},
155			{`"`, LiteralStringDouble, Pop(1)},
156		},
157		"simple-sym": {
158			Include("string-escaped"),
159			{`[^\\"#]+`, LiteralStringSymbol, nil},
160			{`[\\#]`, LiteralStringSymbol, nil},
161			{`"`, LiteralStringSymbol, Pop(1)},
162		},
163		"simple-backtick": {
164			Include("string-intp-escaped"),
165			{"[^\\\\`#]+", LiteralStringBacktick, nil},
166			{`[\\#]`, LiteralStringBacktick, nil},
167			{"`", LiteralStringBacktick, Pop(1)},
168		},
169		"cb-intp-string": {
170			{`\\[\{]`, LiteralStringOther, nil},
171			{`\{`, LiteralStringOther, Push()},
172			{`\}`, LiteralStringOther, Pop(1)},
173			Include("string-intp-escaped"),
174			{`[\\#{}]`, LiteralStringOther, nil},
175			{`[^\\#{}]+`, LiteralStringOther, nil},
176		},
177		"cb-string": {
178			{`\\[\\{}]`, LiteralStringOther, nil},
179			{`\{`, LiteralStringOther, Push()},
180			{`\}`, LiteralStringOther, Pop(1)},
181			{`[\\#{}]`, LiteralStringOther, nil},
182			{`[^\\#{}]+`, LiteralStringOther, nil},
183		},
184		"cb-regex": {
185			{`\\[\\{}]`, LiteralStringRegex, nil},
186			{`\{`, LiteralStringRegex, Push()},
187			{`\}[imsx]*`, LiteralStringRegex, Pop(1)},
188			Include("string-intp"),
189			{`[\\#{}]`, LiteralStringRegex, nil},
190			{`[^\\#{}]+`, LiteralStringRegex, nil},
191		},
192		"sb-intp-string": {
193			{`\\[\[]`, LiteralStringOther, nil},
194			{`\[`, LiteralStringOther, Push()},
195			{`\]`, LiteralStringOther, Pop(1)},
196			Include("string-intp-escaped"),
197			{`[\\#\[\]]`, LiteralStringOther, nil},
198			{`[^\\#\[\]]+`, LiteralStringOther, nil},
199		},
200		"sb-string": {
201			{`\\[\\\[\]]`, LiteralStringOther, nil},
202			{`\[`, LiteralStringOther, Push()},
203			{`\]`, LiteralStringOther, Pop(1)},
204			{`[\\#\[\]]`, LiteralStringOther, nil},
205			{`[^\\#\[\]]+`, LiteralStringOther, nil},
206		},
207		"sb-regex": {
208			{`\\[\\\[\]]`, LiteralStringRegex, nil},
209			{`\[`, LiteralStringRegex, Push()},
210			{`\][imsx]*`, LiteralStringRegex, Pop(1)},
211			Include("string-intp"),
212			{`[\\#\[\]]`, LiteralStringRegex, nil},
213			{`[^\\#\[\]]+`, LiteralStringRegex, nil},
214		},
215		"pa-intp-string": {
216			{`\\[\(]`, LiteralStringOther, nil},
217			{`\(`, LiteralStringOther, Push()},
218			{`\)`, LiteralStringOther, Pop(1)},
219			Include("string-intp-escaped"),
220			{`[\\#()]`, LiteralStringOther, nil},
221			{`[^\\#()]+`, LiteralStringOther, nil},
222		},
223		"pa-string": {
224			{`\\[\\()]`, LiteralStringOther, nil},
225			{`\(`, LiteralStringOther, Push()},
226			{`\)`, LiteralStringOther, Pop(1)},
227			{`[\\#()]`, LiteralStringOther, nil},
228			{`[^\\#()]+`, LiteralStringOther, nil},
229		},
230		"pa-regex": {
231			{`\\[\\()]`, LiteralStringRegex, nil},
232			{`\(`, LiteralStringRegex, Push()},
233			{`\)[imsx]*`, LiteralStringRegex, Pop(1)},
234			Include("string-intp"),
235			{`[\\#()]`, LiteralStringRegex, nil},
236			{`[^\\#()]+`, LiteralStringRegex, nil},
237		},
238		"ab-intp-string": {
239			{`\\[<]`, LiteralStringOther, nil},
240			{`<`, LiteralStringOther, Push()},
241			{`>`, LiteralStringOther, Pop(1)},
242			Include("string-intp-escaped"),
243			{`[\\#<>]`, LiteralStringOther, nil},
244			{`[^\\#<>]+`, LiteralStringOther, nil},
245		},
246		"ab-string": {
247			{`\\[\\<>]`, LiteralStringOther, nil},
248			{`<`, LiteralStringOther, Push()},
249			{`>`, LiteralStringOther, Pop(1)},
250			{`[\\#<>]`, LiteralStringOther, nil},
251			{`[^\\#<>]+`, LiteralStringOther, nil},
252		},
253		"ab-regex": {
254			{`\\[\\<>]`, LiteralStringRegex, nil},
255			{`<`, LiteralStringRegex, Push()},
256			{`>[imsx]*`, LiteralStringRegex, Pop(1)},
257			Include("string-intp"),
258			{`[\\#<>]`, LiteralStringRegex, nil},
259			{`[^\\#<>]+`, LiteralStringRegex, nil},
260		},
261	},
262))