Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/pygments/lexers/ruby.py : 43%

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