Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pygments/lexers/ruby.py: 45%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2 pygments.lexers.ruby
3 ~~~~~~~~~~~~~~~~~~~~
5 Lexers for Ruby and related languages.
7 :copyright: Copyright 2006-present by the Pygments team, see AUTHORS.
8 :license: BSD, see LICENSE for details.
9"""
11import re
13from pygments.lexer import Lexer, RegexLexer, ExtendedRegexLexer, include, \
14 bygroups, default, LexerContext, do_insertions, words, line_re
15from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
16 Number, Punctuation, Error, Generic, Whitespace
17from pygments.util import shebang_matches
19__all__ = ['RubyLexer', 'RubyConsoleLexer', 'FancyLexer']
22RUBY_OPERATORS = (
23 '*', '**', '-', '+', '-@', '+@', '/', '%', '&', '|', '^', '`', '~',
24 '[]', '[]=', '<<', '>>', '<', '<>', '<=>', '>', '>=', '==', '==='
25)
28class RubyLexer(ExtendedRegexLexer):
29 """
30 For Ruby source code.
31 """
33 name = 'Ruby'
34 url = 'http://www.ruby-lang.org'
35 aliases = ['ruby', 'rb', 'duby']
36 filenames = ['*.rb', '*.rbw', 'Rakefile', '*.rake', '*.gemspec',
37 '*.rbx', '*.duby', 'Gemfile', 'Vagrantfile']
38 mimetypes = ['text/x-ruby', 'application/x-ruby']
39 version_added = ''
41 flags = re.DOTALL | re.MULTILINE
43 def heredoc_callback(self, match, ctx):
44 # okay, this is the hardest part of parsing Ruby...
45 # match: 1 = <<[-~]?, 2 = quote? 3 = name 4 = quote? 5 = rest of line
47 start = match.start(1)
48 yield start, Operator, match.group(1) # <<[-~]?
49 yield match.start(2), String.Heredoc, match.group(2) # quote ", ', `
50 yield match.start(3), String.Delimiter, match.group(3) # heredoc name
51 yield match.start(4), String.Heredoc, match.group(4) # quote again
53 heredocstack = ctx.__dict__.setdefault('heredocstack', [])
54 outermost = not bool(heredocstack)
55 heredocstack.append((match.group(1) in ('<<-', '<<~'), match.group(3)))
57 ctx.pos = match.start(5)
58 ctx.end = match.end(5)
59 # this may find other heredocs, so limit the recursion depth
60 if len(heredocstack) < 100:
61 yield from self.get_tokens_unprocessed(context=ctx)
62 else:
63 yield ctx.pos, String.Heredoc, match.group(5)
64 ctx.pos = match.end()
66 if outermost:
67 # this is the outer heredoc again, now we can process them all
68 for tolerant, hdname in heredocstack:
69 lines = []
70 for match in line_re.finditer(ctx.text, ctx.pos):
71 if tolerant:
72 check = match.group().strip()
73 else:
74 check = match.group().rstrip()
75 if check == hdname:
76 for amatch in lines:
77 yield amatch.start(), String.Heredoc, amatch.group()
78 yield match.start(), String.Delimiter, match.group()
79 ctx.pos = match.end()
80 break
81 else:
82 lines.append(match)
83 else:
84 # end of heredoc not found -- error!
85 for amatch in lines:
86 yield amatch.start(), Error, amatch.group()
87 # advance past the consumed lines so they are not
88 # re-lexed (and thus duplicated) once ctx.end is reset
89 if lines:
90 ctx.pos = lines[-1].end()
91 ctx.end = len(ctx.text)
92 del heredocstack[:]
94 def gen_rubystrings_rules():
95 def intp_regex_callback(self, match, ctx):
96 yield match.start(1), String.Regex, match.group(1) # begin
97 nctx = LexerContext(match.group(3), 0, ['interpolated-regex'])
98 for i, t, v in self.get_tokens_unprocessed(context=nctx):
99 yield match.start(3)+i, t, v
100 yield match.start(4), String.Regex, match.group(4) # end[mixounse]*
101 ctx.pos = match.end()
103 def intp_string_callback(self, match, ctx):
104 yield match.start(1), String.Other, match.group(1)
105 nctx = LexerContext(match.group(3), 0, ['interpolated-string'])
106 for i, t, v in self.get_tokens_unprocessed(context=nctx):
107 yield match.start(3)+i, t, v
108 yield match.start(4), String.Other, match.group(4) # end
109 ctx.pos = match.end()
111 states = {}
112 states['strings'] = [
113 # easy ones
114 (r'\:@{0,2}[a-zA-Z_]\w*[!?]?', String.Symbol),
115 (words(RUBY_OPERATORS, prefix=r'\:@{0,2}'), String.Symbol),
116 (r":'(\\\\|\\[^\\]|[^'\\])*'", String.Symbol),
117 (r':"', String.Symbol, 'simple-sym'),
118 (r'([a-zA-Z_]\w*)(:)(?!:)',
119 bygroups(String.Symbol, Punctuation)), # Since Ruby 1.9
120 (r'"', String.Double, 'simple-string-double'),
121 (r"'", String.Single, 'simple-string-single'),
122 (r'(?<!\.)`', String.Backtick, 'simple-backtick'),
123 ]
125 # quoted string and symbol
126 for name, ttype, end in ('string-double', String.Double, '"'), \
127 ('string-single', String.Single, "'"),\
128 ('sym', String.Symbol, '"'), \
129 ('backtick', String.Backtick, '`'):
130 states['simple-'+name] = [
131 include('string-intp-escaped'),
132 (rf'[^\\{end}#]+', ttype),
133 (r'[\\#]', ttype),
134 (end, ttype, '#pop'),
135 ]
137 # braced quoted strings
138 for lbrace, rbrace, bracecc, name in \
139 ('\\{', '\\}', '{}', 'cb'), \
140 ('\\[', '\\]', '\\[\\]', 'sb'), \
141 ('\\(', '\\)', '()', 'pa'), \
142 ('<', '>', '<>', 'ab'):
143 states[name+'-intp-string'] = [
144 (r'\\[\\' + bracecc + ']', String.Other),
145 (lbrace, String.Other, '#push'),
146 (rbrace, String.Other, '#pop'),
147 include('string-intp-escaped'),
148 (r'[\\#' + bracecc + ']', String.Other),
149 (r'[^\\#' + bracecc + ']+', String.Other),
150 ]
151 states['strings'].append((r'%[QWx]?' + lbrace, String.Other,
152 name+'-intp-string'))
153 states[name+'-string'] = [
154 (r'\\[\\' + bracecc + ']', String.Other),
155 (lbrace, String.Other, '#push'),
156 (rbrace, String.Other, '#pop'),
157 (r'[\\#' + bracecc + ']', String.Other),
158 (r'[^\\#' + bracecc + ']+', String.Other),
159 ]
160 states['strings'].append((r'%[qsw]' + lbrace, String.Other,
161 name+'-string'))
162 states[name+'-regex'] = [
163 (r'\\[\\' + bracecc + ']', String.Regex),
164 (lbrace, String.Regex, '#push'),
165 (rbrace + '[mixounse]*', String.Regex, '#pop'),
166 include('string-intp'),
167 (r'[\\#' + bracecc + ']', String.Regex),
168 (r'[^\\#' + bracecc + ']+', String.Regex),
169 ]
170 states['strings'].append((r'%r' + lbrace, String.Regex,
171 name+'-regex'))
173 # these must come after %<brace>!
174 states['strings'] += [
175 # %r regex
176 (r'(%r([\W_]))((?:\\\2|(?!\2).)*)(\2[mixounse]*)',
177 intp_regex_callback),
178 # regular fancy strings with qsw
179 (r'%[qsw]([\W_])((?:\\\1|(?!\1).)*)\1', String.Other),
180 (r'(%[QWx]([\W_]))((?:\\\2|(?!\2).)*)(\2)',
181 intp_string_callback),
182 # special forms of fancy strings after operators or
183 # in method calls with braces
184 (r'(?<=[-+/*%=<>&!^|~,(])(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)',
185 bygroups(Whitespace, String.Other, None)),
186 # and because of fixed width lookbehinds the whole thing a
187 # second time for line startings...
188 (r'^(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)',
189 bygroups(Whitespace, String.Other, None)),
190 # all regular fancy strings without qsw
191 (r'(%([^a-zA-Z0-9\s]))((?:\\\2|(?!\2).)*)(\2)',
192 intp_string_callback),
193 ]
195 return states
197 tokens = {
198 'root': [
199 (r'\A#!.+?$', Comment.Hashbang),
200 (r'#.*?$', Comment.Single),
201 (r'=begin\s.*?\n=end.*?$', Comment.Multiline),
202 # keywords
203 (words((
204 'BEGIN', 'END', 'alias', 'begin', 'break', 'case', 'defined?',
205 'do', 'else', 'elsif', 'end', 'ensure', 'for', 'if', 'in', 'next', 'redo',
206 'rescue', 'raise', 'retry', 'return', 'super', 'then', 'undef',
207 'unless', 'until', 'when', 'while', 'yield'), suffix=r'\b'),
208 Keyword),
209 # start of function, class and module names
210 (r'(module)(\s+)([a-zA-Z_]\w*'
211 r'(?:::[a-zA-Z_]\w*)*)',
212 bygroups(Keyword, Whitespace, Name.Namespace)),
213 (r'(def)(\s+)', bygroups(Keyword, Whitespace), 'funcname'),
214 (r'def(?=[*%&^`~+-/\[<>=])', Keyword, 'funcname'),
215 (r'(class)(\s+)', bygroups(Keyword, Whitespace), 'classname'),
216 # special methods
217 (words((
218 'initialize', 'new', 'loop', 'include', 'extend', 'raise', 'attr_reader',
219 'attr_writer', 'attr_accessor', 'attr', 'catch', 'throw', 'private',
220 'module_function', 'public', 'protected', 'true', 'false', 'nil'),
221 suffix=r'\b'),
222 Keyword.Pseudo),
223 (r'(not|and|or)\b', Operator.Word),
224 (words((
225 'autoload', 'block_given', 'const_defined', 'eql', 'equal', 'frozen', 'include',
226 'instance_of', 'is_a', 'iterator', 'kind_of', 'method_defined', 'nil',
227 'private_method_defined', 'protected_method_defined',
228 'public_method_defined', 'respond_to', 'tainted'), suffix=r'\?'),
229 Name.Builtin),
230 (r'(chomp|chop|exit|gsub|sub)!', Name.Builtin),
231 (words((
232 'Array', 'Float', 'Integer', 'String', '__id__', '__send__', 'abort',
233 'ancestors', 'at_exit', 'autoload', 'binding', 'callcc', 'caller',
234 'catch', 'chomp', 'chop', 'class_eval', 'class_variables',
235 'clone', 'const_defined?', 'const_get', 'const_missing', 'const_set',
236 'constants', 'display', 'dup', 'eval', 'exec', 'exit', 'extend', 'fail', 'fork',
237 'format', 'freeze', 'getc', 'gets', 'global_variables', 'gsub',
238 'hash', 'id', 'included_modules', 'inspect', 'instance_eval',
239 'instance_method', 'instance_methods',
240 'instance_variable_get', 'instance_variable_set', 'instance_variables',
241 'lambda', 'load', 'local_variables', 'loop',
242 'method', 'method_missing', 'methods', 'module_eval', 'name',
243 'object_id', 'open', 'p', 'print', 'printf', 'private_class_method',
244 'private_instance_methods',
245 'private_methods', 'proc', 'protected_instance_methods',
246 'protected_methods', 'public_class_method',
247 'public_instance_methods', 'public_methods',
248 'putc', 'puts', 'raise', 'rand', 'readline', 'readlines', 'require',
249 'scan', 'select', 'self', 'send', 'set_trace_func', 'singleton_methods', 'sleep',
250 'split', 'sprintf', 'srand', 'sub', 'syscall', 'system', 'taint',
251 'test', 'throw', 'to_a', 'to_s', 'trace_var', 'trap', 'untaint',
252 'untrace_var', 'warn'), prefix=r'(?<!\.)', suffix=r'\b'),
253 Name.Builtin),
254 (r'__(FILE|LINE)__\b', Name.Builtin.Pseudo),
255 # normal heredocs
256 (r'(?<![\w)\]}])(<<[-~]?)(["`\']?)([a-zA-Z_]\w*)(\2)(.*?\n)',
257 heredoc_callback),
258 # empty string heredocs
259 (r'(<<[-~]?)("|\')()(\2)(.*?\n)', heredoc_callback),
260 (r'__END__', Comment.Preproc, 'end-part'),
261 # multiline regex (after keywords or assignments)
262 (r'(?:^|(?<=[=<>~!:])|'
263 r'(?<=(?:\s|;)when\s)|'
264 r'(?<=(?:\s|;)or\s)|'
265 r'(?<=(?:\s|;)and\s)|'
266 r'(?<=\.index\s)|'
267 r'(?<=\.scan\s)|'
268 r'(?<=\.sub\s)|'
269 r'(?<=\.sub!\s)|'
270 r'(?<=\.gsub\s)|'
271 r'(?<=\.gsub!\s)|'
272 r'(?<=\.match\s)|'
273 r'(?<=(?:\s|;)if\s)|'
274 r'(?<=(?:\s|;)elsif\s)|'
275 r'(?<=^when\s)|'
276 r'(?<=^index\s)|'
277 r'(?<=^scan\s)|'
278 r'(?<=^sub\s)|'
279 r'(?<=^gsub\s)|'
280 r'(?<=^sub!\s)|'
281 r'(?<=^gsub!\s)|'
282 r'(?<=^match\s)|'
283 r'(?<=^if\s)|'
284 r'(?<=^elsif\s)'
285 r')(\s*)(/)', bygroups(Text, String.Regex), 'multiline-regex'),
286 # multiline regex (in method calls or subscripts)
287 (r'(?<=\(|,|\[)/', String.Regex, 'multiline-regex'),
288 # multiline regex (this time the funny no whitespace rule)
289 (r'(\s+)(/)(?![\s=])', bygroups(Whitespace, String.Regex),
290 'multiline-regex'),
291 # lex numbers and ignore following regular expressions which
292 # are division operators in fact (grrrr. i hate that. any
293 # better ideas?)
294 # since pygments 0.7 we also eat a "?" operator after numbers
295 # so that the char operator does not work. Chars are not allowed
296 # there so that you can use the ternary operator.
297 # stupid example:
298 # x>=0?n[x]:""
299 (r'(0_?[0-7]+(?:_[0-7]+)*)(\s*)([/?])?',
300 bygroups(Number.Oct, Whitespace, Operator)),
301 (r'(0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*)(\s*)([/?])?',
302 bygroups(Number.Hex, Whitespace, Operator)),
303 (r'(0b[01]+(?:_[01]+)*)(\s*)([/?])?',
304 bygroups(Number.Bin, Whitespace, Operator)),
305 (r'([\d]+(?:_\d+)*)(\s*)([/?])?',
306 bygroups(Number.Integer, Whitespace, Operator)),
307 # Names
308 (r'@@[a-zA-Z_]\w*', Name.Variable.Class),
309 (r'@[a-zA-Z_]\w*', Name.Variable.Instance),
310 (r'\$\w+', Name.Variable.Global),
311 (r'\$[!@&`\'+~=/\\,;.<>_*$?:"^-]', Name.Variable.Global),
312 (r'\$-[0adFiIlpvw]', Name.Variable.Global),
313 (r'::', Operator),
314 include('strings'),
315 # chars
316 (r'\?(\\[MC]-)*' # modifiers
317 r'(\\([\\abefnrstv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})|\S)'
318 r'(?!\w)',
319 String.Char),
320 (r'[A-Z]\w+', Name.Constant),
321 # this is needed because ruby attributes can look
322 # like keywords (class) or like this: ` ?!?
323 (words(RUBY_OPERATORS, prefix=r'(\.|::)'),
324 bygroups(Operator, Name.Operator)),
325 (r'(\.|::)([a-zA-Z_]\w*[!?]?|[*%&^`~+\-/\[<>=])',
326 bygroups(Operator, Name)),
327 (r'[a-zA-Z_]\w*[!?]?', Name),
328 (r'(\[|\]|\*\*|<<?|>>?|>=|<=|<=>|=~|={3}|'
329 r'!~|&&?|\|\||\.{1,3})', Operator),
330 (r'[-+/*%=<>&!^|~]=?', Operator),
331 (r'[(){};,/?:\\]', Punctuation),
332 (r'\s+', Whitespace)
333 ],
334 'funcname': [
335 (r'\(', Punctuation, 'defexpr'),
336 (r'(?:([a-zA-Z_]\w*)(\.))?' # optional scope name, like "self."
337 r'('
338 r'[a-zA-Z\u0080-\uffff][a-zA-Z0-9_\u0080-\uffff]*[!?=]?' # method name
339 r'|!=|!~|=~|\*\*?|[-+!~]@?|[/%&|^]|<=>|<[<=]?|>[>=]?|===?' # or operator override
340 r'|\[\]=?' # or element reference/assignment override
341 r'|`' # or the undocumented backtick override
342 r')',
343 bygroups(Name.Class, Operator, Name.Function), '#pop'),
344 default('#pop')
345 ],
346 'classname': [
347 (r'\(', Punctuation, 'defexpr'),
348 (r'<<', Operator, '#pop'),
349 (r'[A-Z_]\w*', Name.Class, '#pop'),
350 default('#pop')
351 ],
352 'defexpr': [
353 (r'(\))(\.|::)?', bygroups(Punctuation, Operator), '#pop'),
354 (r'\(', Operator, '#push'),
355 include('root')
356 ],
357 'in-intp': [
358 (r'\{', String.Interpol, '#push'),
359 (r'\}', String.Interpol, '#pop'),
360 include('root'),
361 ],
362 'string-intp': [
363 (r'#\{', String.Interpol, 'in-intp'),
364 (r'#@@?[a-zA-Z_]\w*', String.Interpol),
365 (r'#\$[a-zA-Z_]\w*', String.Interpol)
366 ],
367 'string-intp-escaped': [
368 include('string-intp'),
369 (r'\\([\\abefnrstv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})',
370 String.Escape)
371 ],
372 'interpolated-regex': [
373 include('string-intp'),
374 (r'[\\#]', String.Regex),
375 (r'[^\\#]+', String.Regex),
376 ],
377 'interpolated-string': [
378 include('string-intp'),
379 (r'[\\#]', String.Other),
380 (r'[^\\#]+', String.Other),
381 ],
382 'multiline-regex': [
383 include('string-intp'),
384 (r'\\\\', String.Regex),
385 (r'\\/', String.Regex),
386 (r'[\\#]', String.Regex),
387 (r'[^\\/#]+', String.Regex),
388 (r'/[mixounse]*', String.Regex, '#pop'),
389 ],
390 'end-part': [
391 (r'.+', Comment.Preproc, '#pop')
392 ]
393 }
394 tokens.update(gen_rubystrings_rules())
396 def analyse_text(text):
397 return shebang_matches(text, r'ruby(1\.\d)?')
400class RubyConsoleLexer(Lexer):
401 """
402 For Ruby interactive console (**irb**) output.
403 """
404 name = 'Ruby irb session'
405 aliases = ['rbcon', 'irb']
406 mimetypes = ['text/x-ruby-shellsession']
407 url = 'https://www.ruby-lang.org'
408 version_added = ''
409 _example = 'rbcon/console'
411 _prompt_re = re.compile(r'irb\([a-zA-Z_]\w*\):\d{3}:\d+[>*"\'] '
412 r'|>> |\?> ')
414 def get_tokens_unprocessed(self, text):
415 rblexer = RubyLexer(**self.options)
417 curcode = ''
418 insertions = []
419 for match in line_re.finditer(text):
420 line = match.group()
421 m = self._prompt_re.match(line)
422 if m is not None:
423 end = m.end()
424 insertions.append((len(curcode),
425 [(0, Generic.Prompt, line[:end])]))
426 curcode += line[end:]
427 else:
428 if curcode:
429 yield from do_insertions(
430 insertions, rblexer.get_tokens_unprocessed(curcode))
431 curcode = ''
432 insertions = []
433 yield match.start(), Generic.Output, line
434 if curcode:
435 yield from do_insertions(
436 insertions, rblexer.get_tokens_unprocessed(curcode))
439class FancyLexer(RegexLexer):
440 """
441 Pygments Lexer For Fancy.
443 Fancy is a self-hosted, pure object-oriented, dynamic,
444 class-based, concurrent general-purpose programming language
445 running on Rubinius, the Ruby VM.
446 """
447 name = 'Fancy'
448 url = 'https://github.com/bakkdoor/fancy'
449 filenames = ['*.fy', '*.fancypack']
450 aliases = ['fancy', 'fy']
451 mimetypes = ['text/x-fancysrc']
452 version_added = '1.5'
454 tokens = {
455 # copied from PerlLexer:
456 'balanced-regex': [
457 (r'/(\\\\|\\[^\\]|[^/\\])*/[egimosx]*', String.Regex, '#pop'),
458 (r'!(\\\\|\\[^\\]|[^!\\])*![egimosx]*', String.Regex, '#pop'),
459 (r'\\(\\\\|[^\\])*\\[egimosx]*', String.Regex, '#pop'),
460 (r'\{(\\\\|\\[^\\]|[^}\\])*\}[egimosx]*', String.Regex, '#pop'),
461 (r'<(\\\\|\\[^\\]|[^>\\])*>[egimosx]*', String.Regex, '#pop'),
462 (r'\[(\\\\|\\[^\\]|[^\]\\])*\][egimosx]*', String.Regex, '#pop'),
463 (r'\((\\\\|\\[^\\]|[^)\\])*\)[egimosx]*', String.Regex, '#pop'),
464 (r'@(\\\\|\\[^\\]|[^@\\])*@[egimosx]*', String.Regex, '#pop'),
465 (r'%(\\\\|\\[^\\]|[^%\\])*%[egimosx]*', String.Regex, '#pop'),
466 (r'\$(\\\\|\\[^\\]|[^$\\])*\$[egimosx]*', String.Regex, '#pop'),
467 ],
468 'root': [
469 (r'\s+', Whitespace),
471 # balanced delimiters (copied from PerlLexer):
472 (r's\{(\\\\|\\[^\\]|[^}\\])*\}\s*', String.Regex, 'balanced-regex'),
473 (r's<(\\\\|\\[^\\]|[^>\\])*>\s*', String.Regex, 'balanced-regex'),
474 (r's\[(\\\\|\\[^\\]|[^\]\\])*\]\s*', String.Regex, 'balanced-regex'),
475 (r's\((\\\\|\\[^\\]|[^)\\])*\)\s*', String.Regex, 'balanced-regex'),
476 (r'm?/(\\\\|\\[^\\]|[^///\n])*/[gcimosx]*', String.Regex),
477 (r'm(?=[/!\\{<\[(@%$])', String.Regex, 'balanced-regex'),
479 # Comments
480 (r'#(.*?)\n', Comment.Single),
481 # Symbols
482 (r'\'([^\'\s\[\](){}]+|\[\])', String.Symbol),
483 # Multi-line DoubleQuotedString
484 (r'"""(\\\\|\\[^\\]|[^\\])*?"""', String),
485 # DoubleQuotedString
486 (r'"(\\\\|\\[^\\]|[^"\\])*"', String),
487 # keywords
488 (r'(def|class|try|catch|finally|retry|return|return_local|match|'
489 r'case|->|=>)\b', Keyword),
490 # constants
491 (r'(self|super|nil|false|true)\b', Name.Constant),
492 (r'[(){};,/?|:\\]', Punctuation),
493 # names
494 (words((
495 'Object', 'Array', 'Hash', 'Directory', 'File', 'Class', 'String',
496 'Number', 'Enumerable', 'FancyEnumerable', 'Block', 'TrueClass',
497 'NilClass', 'FalseClass', 'Tuple', 'Symbol', 'Stack', 'Set',
498 'FancySpec', 'Method', 'Package', 'Range'), suffix=r'\b'),
499 Name.Builtin),
500 # functions
501 (r'[a-zA-Z](\w|[-+?!=*/^><%])*:', Name.Function),
502 # operators, must be below functions
503 (r'[-+*/~,<>=&!?%^\[\].$]+', Operator),
504 (r'[A-Z]\w*', Name.Constant),
505 (r'@[a-zA-Z_]\w*', Name.Variable.Instance),
506 (r'@@[a-zA-Z_]\w*', Name.Variable.Class),
507 ('@@?', Operator),
508 (r'[a-zA-Z_]\w*', Name),
509 # numbers - / checks are necessary to avoid mismarking regexes,
510 # see comment in RubyLexer
511 (r'(0[oO]?[0-7]+(?:_[0-7]+)*)(\s*)([/?])?',
512 bygroups(Number.Oct, Whitespace, Operator)),
513 (r'(0[xX][0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*)(\s*)([/?])?',
514 bygroups(Number.Hex, Whitespace, Operator)),
515 (r'(0[bB][01]+(?:_[01]+)*)(\s*)([/?])?',
516 bygroups(Number.Bin, Whitespace, Operator)),
517 (r'([\d]+(?:_\d+)*)(\s*)([/?])?',
518 bygroups(Number.Integer, Whitespace, Operator)),
519 (r'\d+([eE][+-]?[0-9]+)|\d+\.\d+([eE][+-]?[0-9]+)?', Number.Float),
520 (r'\d+', Number.Integer)
521 ]
522 }