ThirdParty/Pygments/pygments/lexers/ruby.py

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

eric ide

mercurial