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

changeset 8258
82b608e352ec
parent 8257
28146736bbfc
child 8259
2bbec88047dd
equal deleted inserted replaced
8257:28146736bbfc 8258:82b608e352ec
1 # -*- coding: utf-8 -*-
2 """
3 pygments.lexers.ruby
4 ~~~~~~~~~~~~~~~~~~~~
5
6 Lexers for Ruby and related languages.
7
8 :copyright: Copyright 2006-2021 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', 'Gemfile']
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), String.Delimiter, 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) in ('<<-', '<<~'), match.group(3)))
57
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()
66
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[:]
90
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()
99
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()
107
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 ]
121
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 ]
133
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'))
169
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 ]
191
192 return states
193
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())
388
389 def analyse_text(text):
390 return shebang_matches(text, r'ruby(1\.\d)?')
391
392
393 class RubyConsoleLexer(Lexer):
394 """
395 For Ruby interactive console (**irb**) output like:
396
397 .. sourcecode:: rbcon
398
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']
408
409 _prompt_re = re.compile(r'irb\([a-zA-Z_]\w*\):\d{3}:\d+[>*"\'] '
410 r'|>> |\?> ')
411
412 def get_tokens_unprocessed(self, text):
413 rblexer = RubyLexer(**self.options)
414
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))
435
436
437 class FancyLexer(RegexLexer):
438 """
439 Pygments Lexer For `Fancy <http://www.fancy-lang.org/>`_.
440
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.
444
445 .. versionadded:: 1.5
446 """
447 name = 'Fancy'
448 filenames = ['*.fy', '*.fancypack']
449 aliases = ['fancy', 'fy']
450 mimetypes = ['text/x-fancysrc']
451
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),
468
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'),
476
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 }

eric ide

mercurial