eric6/ThirdParty/Pygments/pygments/lexers/crystal.py

changeset 7983
54c5cfbb1e29
parent 7701
25f42e208e08
equal deleted inserted replaced
7982:48d210e41c65 7983:54c5cfbb1e29
3 pygments.lexers.crystal 3 pygments.lexers.crystal
4 ~~~~~~~~~~~~~~~~~~~~~~~ 4 ~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 Lexer for Crystal. 6 Lexer for Crystal.
7 7
8 :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS. 8 :copyright: Copyright 2006-2021 by the Pygments team, see AUTHORS.
9 :license: BSD, see LICENSE for details. 9 :license: BSD, see LICENSE for details.
10 """ 10 """
11 11
12 import re 12 import re
13 13
55 outermost = not bool(heredocstack) 55 outermost = not bool(heredocstack)
56 heredocstack.append((match.group(1) == '<<-', match.group(3))) 56 heredocstack.append((match.group(1) == '<<-', match.group(3)))
57 57
58 ctx.pos = match.start(5) 58 ctx.pos = match.start(5)
59 ctx.end = match.end(5) 59 ctx.end = match.end(5)
60 # this may find other heredocs 60 # this may find other heredocs, so limit the recursion depth
61 yield from self.get_tokens_unprocessed(context=ctx) 61 if len(heredocstack) < 100:
62 yield from self.get_tokens_unprocessed(context=ctx)
63 else:
64 yield ctx.pos, String.Heredoc, match.group(5)
62 ctx.pos = match.end() 65 ctx.pos = match.end()
63 66
64 if outermost: 67 if outermost:
65 # this is the outer heredoc again, now we can process them all 68 # this is the outer heredoc again, now we can process them all
66 for tolerant, hdname in heredocstack: 69 for tolerant, hdname in heredocstack:
84 yield amatch.start(), Error, amatch.group() 87 yield amatch.start(), Error, amatch.group()
85 ctx.end = len(ctx.text) 88 ctx.end = len(ctx.text)
86 del heredocstack[:] 89 del heredocstack[:]
87 90
88 def gen_crystalstrings_rules(): 91 def gen_crystalstrings_rules():
89 def intp_regex_callback(self, match, ctx):
90 yield match.start(1), String.Regex, match.group(1) # begin
91 nctx = LexerContext(match.group(3), 0, ['interpolated-regex'])
92 for i, t, v in self.get_tokens_unprocessed(context=nctx):
93 yield match.start(3)+i, t, v
94 yield match.start(4), String.Regex, match.group(4) # end[imsx]*
95 ctx.pos = match.end()
96
97 def intp_string_callback(self, match, ctx):
98 yield match.start(1), String.Other, match.group(1)
99 nctx = LexerContext(match.group(3), 0, ['interpolated-string'])
100 for i, t, v in self.get_tokens_unprocessed(context=nctx):
101 yield match.start(3)+i, t, v
102 yield match.start(4), String.Other, match.group(4) # end
103 ctx.pos = match.end()
104
105 states = {} 92 states = {}
106 states['strings'] = [ 93 states['strings'] = [
107 (r'\:@{0,2}[a-zA-Z_]\w*[!?]?', String.Symbol), 94 (r'\:\w+[!?]?', String.Symbol),
108 (words(CRYSTAL_OPERATORS, prefix=r'\:@{0,2}'), String.Symbol), 95 (words(CRYSTAL_OPERATORS, prefix=r'\:'), String.Symbol),
109 (r":'(\\\\|\\'|[^'])*'", String.Symbol), 96 (r":'(\\\\|\\[^\\]|[^'\\])*'", String.Symbol),
110 # This allows arbitrary text after '\ for simplicity 97 # This allows arbitrary text after '\ for simplicity
111 (r"'(\\\\|\\'|[^']|\\[^'\\]+)'", String.Char), 98 (r"'(\\\\|\\'|[^']|\\[^'\\]+)'", String.Char),
112 (r':"', String.Symbol, 'simple-sym'), 99 (r':"', String.Symbol, 'simple-sym'),
113 # Crystal doesn't have "symbol:"s but this simplifies function args 100 # Crystal doesn't have "symbol:"s but this simplifies function args
114 (r'([a-zA-Z_]\w*)(:)(?!:)', bygroups(String.Symbol, Punctuation)), 101 (r'([a-zA-Z_]\w*)(:)(?!:)', bygroups(String.Symbol, Punctuation)),
125 (r'[^\\%s#]+' % end, ttype), 112 (r'[^\\%s#]+' % end, ttype),
126 (r'[\\#]', ttype), 113 (r'[\\#]', ttype),
127 (end, ttype, '#pop'), 114 (end, ttype, '#pop'),
128 ] 115 ]
129 116
130 # braced quoted strings 117 # https://crystal-lang.org/docs/syntax_and_semantics/literals/string.html#percent-string-literals
131 for lbrace, rbrace, bracecc, name in \ 118 for lbrace, rbrace, bracecc, name in \
132 ('\\{', '\\}', '{}', 'cb'), \ 119 ('\\{', '\\}', '{}', 'cb'), \
133 ('\\[', '\\]', '\\[\\]', 'sb'), \ 120 ('\\[', '\\]', '\\[\\]', 'sb'), \
134 ('\\(', '\\)', '()', 'pa'), \ 121 ('\\(', '\\)', '()', 'pa'), \
135 ('<', '>', '<>', 'ab'): 122 ('<', '>', '<>', 'ab'), \
123 ('\\|', '\\|', '\\|', 'pi'):
136 states[name+'-intp-string'] = [ 124 states[name+'-intp-string'] = [
137 (r'\\' + lbrace, String.Other), 125 (r'\\' + lbrace, String.Other),
126 ] + (lbrace != rbrace) * [
138 (lbrace, String.Other, '#push'), 127 (lbrace, String.Other, '#push'),
128 ] + [
139 (rbrace, String.Other, '#pop'), 129 (rbrace, String.Other, '#pop'),
140 include('string-intp-escaped'), 130 include('string-intp-escaped'),
141 (r'[\\#' + bracecc + ']', String.Other), 131 (r'[\\#' + bracecc + ']', String.Other),
142 (r'[^\\#' + bracecc + ']+', String.Other), 132 (r'[^\\#' + bracecc + ']+', String.Other),
143 ] 133 ]
144 states['strings'].append((r'%' + lbrace, String.Other, 134 states['strings'].append((r'%Q?' + lbrace, String.Other,
145 name+'-intp-string')) 135 name+'-intp-string'))
146 states[name+'-string'] = [ 136 states[name+'-string'] = [
147 (r'\\[\\' + bracecc + ']', String.Other), 137 (r'\\[\\' + bracecc + ']', String.Other),
138 ] + (lbrace != rbrace) * [
148 (lbrace, String.Other, '#push'), 139 (lbrace, String.Other, '#push'),
140 ] + [
149 (rbrace, String.Other, '#pop'), 141 (rbrace, String.Other, '#pop'),
150 (r'[\\#' + bracecc + ']', String.Other), 142 (r'[\\#' + bracecc + ']', String.Other),
151 (r'[^\\#' + bracecc + ']+', String.Other), 143 (r'[^\\#' + bracecc + ']+', String.Other),
152 ] 144 ]
153 # http://crystal-lang.org/docs/syntax_and_semantics/literals/array.html 145 # https://crystal-lang.org/docs/syntax_and_semantics/literals/array.html#percent-array-literals
154 states['strings'].append((r'%[wi]' + lbrace, String.Other, 146 states['strings'].append((r'%[qwi]' + lbrace, String.Other,
155 name+'-string')) 147 name+'-string'))
156 states[name+'-regex'] = [ 148 states[name+'-regex'] = [
157 (r'\\[\\' + bracecc + ']', String.Regex), 149 (r'\\[\\' + bracecc + ']', String.Regex),
150 ] + (lbrace != rbrace) * [
158 (lbrace, String.Regex, '#push'), 151 (lbrace, String.Regex, '#push'),
152 ] + [
159 (rbrace + '[imsx]*', String.Regex, '#pop'), 153 (rbrace + '[imsx]*', String.Regex, '#pop'),
160 include('string-intp'), 154 include('string-intp'),
161 (r'[\\#' + bracecc + ']', String.Regex), 155 (r'[\\#' + bracecc + ']', String.Regex),
162 (r'[^\\#' + bracecc + ']+', String.Regex), 156 (r'[^\\#' + bracecc + ']+', String.Regex),
163 ] 157 ]
164 states['strings'].append((r'%r' + lbrace, String.Regex, 158 states['strings'].append((r'%r' + lbrace, String.Regex,
165 name+'-regex')) 159 name+'-regex'))
166 160
167 # these must come after %<brace>!
168 states['strings'] += [
169 # %r regex
170 (r'(%r([\W_]))((?:\\\2|(?!\2).)*)(\2[imsx]*)',
171 intp_regex_callback),
172 # regular fancy strings with qsw
173 (r'(%[wi]([\W_]))((?:\\\2|(?!\2).)*)(\2)',
174 intp_string_callback),
175 # special forms of fancy strings after operators or
176 # in method calls with braces
177 (r'(?<=[-+/*%=<>&!^|~,(])(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)',
178 bygroups(Text, String.Other, None)),
179 # and because of fixed width lookbehinds the whole thing a
180 # second time for line startings...
181 (r'^(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)',
182 bygroups(Text, String.Other, None)),
183 # all regular fancy strings without qsw
184 (r'(%([\[{(<]))((?:\\\2|(?!\2).)*)(\2)',
185 intp_string_callback),
186 ]
187
188 return states 161 return states
189 162
190 tokens = { 163 tokens = {
191 'root': [ 164 'root': [
192 (r'#.*?$', Comment.Single), 165 (r'#.*?$', Comment.Single),
193 # keywords 166 # keywords
194 (words(''' 167 (words('''
195 abstract asm as begin break case do else elsif end ensure extend ifdef if 168 abstract asm begin break case do else elsif end ensure extend if in
196 include instance_sizeof next of pointerof private protected rescue return 169 include next of private protected require rescue return select self super
197 require sizeof super then typeof unless until when while with yield 170 then unless until when while with yield
198 '''.split(), suffix=r'\b'), Keyword), 171 '''.split(), suffix=r'\b'), Keyword),
172 (words('''
173 previous_def forall out uninitialized __DIR__ __FILE__ __LINE__
174 __END_LINE__
175 '''.split(), prefix=r'(?<!\.)', suffix=r'\b'), Keyword.Pseudo),
176 # https://crystal-lang.org/docs/syntax_and_semantics/is_a.html
177 (r'\.(is_a\?|nil\?|responds_to\?|as\?|as\b)', Keyword.Pseudo),
199 (words(['true', 'false', 'nil'], suffix=r'\b'), Keyword.Constant), 178 (words(['true', 'false', 'nil'], suffix=r'\b'), Keyword.Constant),
200 # start of function, class and module names 179 # start of function, class and module names
201 (r'(module|lib)(\s+)([a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*)', 180 (r'(module|lib)(\s+)([a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*)',
202 bygroups(Keyword, Text, Name.Namespace)), 181 bygroups(Keyword, Text, Name.Namespace)),
203 (r'(def|fun|macro)(\s+)((?:[a-zA-Z_]\w*::)*)', 182 (r'(def|fun|macro)(\s+)((?:[a-zA-Z_]\w*::)*)',
204 bygroups(Keyword, Text, Name.Namespace), 'funcname'), 183 bygroups(Keyword, Text, Name.Namespace), 'funcname'),
205 (r'def(?=[*%&^`~+-/\[<>=])', Keyword, 'funcname'), 184 (r'def(?=[*%&^`~+-/\[<>=])', Keyword, 'funcname'),
206 (r'(class|struct|union|type|alias|enum)(\s+)((?:[a-zA-Z_]\w*::)*)', 185 (r'(annotation|class|struct|union|type|alias|enum)(\s+)((?:[a-zA-Z_]\w*::)*)',
207 bygroups(Keyword, Text, Name.Namespace), 'classname'), 186 bygroups(Keyword, Text, Name.Namespace), 'classname'),
208 (r'(self|out|uninitialized)\b|(is_a|responds_to)\?', Keyword.Pseudo), 187 # https://crystal-lang.org/api/toplevel.html
188 (words('''
189 instance_sizeof offsetof pointerof sizeof typeof
190 '''.split(), prefix=r'(?<!\.)', suffix=r'\b'), Keyword.Pseudo),
209 # macros 191 # macros
192 (r'(?<!\.)(debugger\b|p!|pp!|record\b|spawn\b)', Name.Builtin.Pseudo),
193 # builtins
210 (words(''' 194 (words('''
211 debugger record pp assert_responds_to spawn parallel 195 abort at_exit caller exit gets loop main p pp print printf puts
212 getter setter property delegate def_hash def_equals def_equals_and_hash 196 raise rand read_line sleep spawn sprintf system
213 forward_missing_to
214 '''.split(), suffix=r'\b'), Name.Builtin.Pseudo),
215 (r'getter[!?]|property[!?]|__(DIR|FILE|LINE)__\b', Name.Builtin.Pseudo),
216 # builtins
217 # http://crystal-lang.org/api/toplevel.html
218 (words('''
219 Object Value Struct Reference Proc Class Nil Symbol Enum Void
220 Bool Number Int Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64
221 Float Float32 Float64 Char String
222 Pointer Slice Range Exception Regex
223 Mutex StaticArray Array Hash Set Tuple Deque Box Process File
224 Dir Time Channel Concurrent Scheduler
225 abort at_exit caller delay exit fork future get_stack_top gets
226 lazy loop main p print printf puts
227 raise rand read_line sleep sprintf system with_color
228 '''.split(), prefix=r'(?<!\.)', suffix=r'\b'), Name.Builtin), 197 '''.split(), prefix=r'(?<!\.)', suffix=r'\b'), Name.Builtin),
198 # https://crystal-lang.org/api/Object.html#macro-summary
199 (r'(?<!\.)(((class_)?((getter|property)\b[!?]?|setter\b))|'
200 r'(def_(clone|equals|equals_and_hash|hash)|delegate|forward_missing_to)\b)',
201 Name.Builtin.Pseudo),
229 # normal heredocs 202 # normal heredocs
230 (r'(?<!\w)(<<-?)(["`\']?)([a-zA-Z_]\w*)(\2)(.*?\n)', 203 (r'(?<!\w)(<<-?)(["`\']?)([a-zA-Z_]\w*)(\2)(.*?\n)',
231 heredoc_callback), 204 heredoc_callback),
232 # empty string heredocs 205 # empty string heredocs
233 (r'(<<-?)("|\')()(\2)(.*?\n)', heredoc_callback), 206 (r'(<<-?)("|\')()(\2)(.*?\n)', heredoc_callback),
295 (r'\$\w+', Name.Variable.Global), 268 (r'\$\w+', Name.Variable.Global),
296 (r'\$[!@&`\'+~=/\\,;.<>_*$?:"^-]', Name.Variable.Global), 269 (r'\$[!@&`\'+~=/\\,;.<>_*$?:"^-]', Name.Variable.Global),
297 (r'\$-[0adFiIlpvw]', Name.Variable.Global), 270 (r'\$-[0adFiIlpvw]', Name.Variable.Global),
298 (r'::', Operator), 271 (r'::', Operator),
299 include('strings'), 272 include('strings'),
300 # chars 273 # https://crystal-lang.org/reference/syntax_and_semantics/literals/char.html
301 (r'\?(\\[MC]-)*' # modifiers 274 (r'\?(\\[MC]-)*' # modifiers
302 r'(\\([\\befnrtv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})|\S)' 275 r'(\\([\\abefnrtv#"\']|[0-7]{1,3}|x[a-fA-F0-9]{2}|u[a-fA-F0-9]{4}|u\{[a-fA-F0-9 ]+\})|\S)'
303 r'(?!\w)', 276 r'(?!\w)',
304 String.Char), 277 String.Char),
305 (r'[A-Z][A-Z_]+\b', Name.Constant), 278 (r'[A-Z][A-Z_]+\b(?!::|\.)', Name.Constant),
306 # macro expansion 279 # macro expansion
307 (r'\{%', String.Interpol, 'in-macro-control'), 280 (r'\{%', String.Interpol, 'in-macro-control'),
308 (r'\{\{', String.Interpol, 'in-macro-expr'), 281 (r'\{\{', String.Interpol, 'in-macro-expr'),
309 # attributes 282 # annotations
310 (r'(@\[)(\s*)([A-Z]\w*)', 283 (r'(@\[)(\s*)([A-Z]\w*(::[A-Z]\w*)*)',
311 bygroups(Operator, Text, Name.Decorator), 'in-attr'), 284 bygroups(Operator, Text, Name.Decorator), 'in-annot'),
312 # this is needed because Crystal attributes can look 285 # this is needed because Crystal attributes can look
313 # like keywords (class) or like this: ` ?!? 286 # like keywords (class) or like this: ` ?!?
314 (words(CRYSTAL_OPERATORS, prefix=r'(\.|::)'), 287 (words(CRYSTAL_OPERATORS, prefix=r'(\.|::)'),
315 bygroups(Operator, Name.Operator)), 288 bygroups(Operator, Name.Operator)),
316 (r'(\.|::)([a-zA-Z_]\w*[!?]?|[*%&^`~+\-/\[<>=])', 289 (r'(\.|::)([a-zA-Z_]\w*[!?]?|[*%&^`~+\-/\[<>=])',
343 ], 316 ],
344 'string-intp': [ 317 'string-intp': [
345 (r'#\{', String.Interpol, 'in-intp'), 318 (r'#\{', String.Interpol, 'in-intp'),
346 ], 319 ],
347 'string-escaped': [ 320 'string-escaped': [
348 (r'\\([\\befnstv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})', String.Escape) 321 # https://crystal-lang.org/reference/syntax_and_semantics/literals/string.html
322 (r'\\([\\abefnrtv#"\']|[0-7]{1,3}|x[a-fA-F0-9]{2}|u[a-fA-F0-9]{4}|u\{[a-fA-F0-9 ]+\})',
323 String.Escape)
349 ], 324 ],
350 'string-intp-escaped': [ 325 'string-intp-escaped': [
351 include('string-intp'), 326 include('string-intp'),
352 include('string-escaped'), 327 include('string-escaped'),
353 ], 328 ],
373 (r'.+', Comment.Preproc, '#pop') 348 (r'.+', Comment.Preproc, '#pop')
374 ], 349 ],
375 'in-macro-control': [ 350 'in-macro-control': [
376 (r'\{%', String.Interpol, '#push'), 351 (r'\{%', String.Interpol, '#push'),
377 (r'%\}', String.Interpol, '#pop'), 352 (r'%\}', String.Interpol, '#pop'),
378 (r'for\b|in\b', Keyword), 353 (r'(for|verbatim)\b', Keyword),
379 include('root'), 354 include('root'),
380 ], 355 ],
381 'in-macro-expr': [ 356 'in-macro-expr': [
382 (r'\{\{', String.Interpol, '#push'), 357 (r'\{\{', String.Interpol, '#push'),
383 (r'\}\}', String.Interpol, '#pop'), 358 (r'\}\}', String.Interpol, '#pop'),
384 include('root'), 359 include('root'),
385 ], 360 ],
386 'in-attr': [ 361 'in-annot': [
387 (r'\[', Operator, '#push'), 362 (r'\[', Operator, '#push'),
388 (r'\]', Operator, '#pop'), 363 (r'\]', Operator, '#pop'),
389 include('root'), 364 include('root'),
390 ], 365 ],
391 } 366 }

eric ide

mercurial