# -*- coding: utf-8 -*- """ pygments.lexers.agile ~~~~~~~~~~~~~~~~~~~~~ Lexers for agile languages. :copyright: Copyright 2006-2013 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. """ import re from pygments.lexer import Lexer, RegexLexer, ExtendedRegexLexer, \ LexerContext, include, combined, do_insertions, bygroups, using, this from pygments.token import Error, Text, Other, \ Comment, Operator, Keyword, Name, String, Number, Generic, Punctuation from pygments.util import get_bool_opt, get_list_opt, shebang_matches from pygments import unistring as uni __all__ = ['PythonLexer', 'PythonConsoleLexer', 'PythonTracebackLexer', 'Python3Lexer', 'Python3TracebackLexer', 'RubyLexer', 'RubyConsoleLexer', 'PerlLexer', 'LuaLexer', 'MoonScriptLexer', 'CrocLexer', 'MiniDLexer', 'IoLexer', 'TclLexer', 'FactorLexer', 'FancyLexer', 'DgLexer', 'Perl6Lexer'] # b/w compatibility from pygments.lexers.functional import SchemeLexer from pygments.lexers.jvm import IokeLexer, ClojureLexer line_re = re.compile('.*?\n') class PythonLexer(RegexLexer): """ For `Python `_ source code. """ name = 'Python' aliases = ['python', 'py', 'sage'] filenames = ['*.py', '*.pyw', '*.sc', 'SConstruct', 'SConscript', '*.tac', '*.sage'] mimetypes = ['text/x-python', 'application/x-python'] tokens = { 'root': [ (r'\n', Text), (r'^(\s*)([rRuU]{,2}"""(?:.|\n)*?""")', bygroups(Text, String.Doc)), (r"^(\s*)([rRuU]{,2}'''(?:.|\n)*?''')", bygroups(Text, String.Doc)), (r'[^\S\n]+', Text), (r'#.*$', Comment), (r'[]{}:(),;[]', Punctuation), (r'\\\n', Text), (r'\\', Text), (r'(in|is|and|or|not)\b', Operator.Word), (r'!=|==|<<|>>|[-~+/*%=<>&^|.]', Operator), include('keywords'), (r'(def)((?:\s|\\\s)+)', bygroups(Keyword, Text), 'funcname'), (r'(class)((?:\s|\\\s)+)', bygroups(Keyword, Text), 'classname'), (r'(from)((?:\s|\\\s)+)', bygroups(Keyword.Namespace, Text), 'fromimport'), (r'(import)((?:\s|\\\s)+)', bygroups(Keyword.Namespace, Text), 'import'), include('builtins'), include('backtick'), ('(?:[rR]|[uU][rR]|[rR][uU])"""', String, 'tdqs'), ("(?:[rR]|[uU][rR]|[rR][uU])'''", String, 'tsqs'), ('(?:[rR]|[uU][rR]|[rR][uU])"', String, 'dqs'), ("(?:[rR]|[uU][rR]|[rR][uU])'", String, 'sqs'), ('[uU]?"""', String, combined('stringescape', 'tdqs')), ("[uU]?'''", String, combined('stringescape', 'tsqs')), ('[uU]?"', String, combined('stringescape', 'dqs')), ("[uU]?'", String, combined('stringescape', 'sqs')), include('name'), include('numbers'), ], 'keywords': [ (r'(assert|break|continue|del|elif|else|except|exec|' r'finally|for|global|if|lambda|pass|print|raise|' r'return|try|while|yield(\s+from)?|as|with)\b', Keyword), ], 'builtins': [ (r'(?`_ source code (version 3.0). *New in Pygments 0.10.* """ name = 'Python 3' aliases = ['python3', 'py3'] filenames = [] # Nothing until Python 3 gets widespread mimetypes = ['text/x-python3', 'application/x-python3'] flags = re.MULTILINE | re.UNICODE uni_name = "[%s][%s]*" % (uni.xid_start, uni.xid_continue) tokens = PythonLexer.tokens.copy() tokens['keywords'] = [ (r'(assert|break|continue|del|elif|else|except|' r'finally|for|global|if|lambda|pass|raise|nonlocal|' r'return|try|while|yield(\s+from)?|as|with|True|False|None)\b', Keyword), ] tokens['builtins'] = [ (r'(?>> a = 'foo' >>> print a foo >>> 1 / 0 Traceback (most recent call last): File "", line 1, in ZeroDivisionError: integer division or modulo by zero Additional options: `python3` Use Python 3 lexer for code. Default is ``False``. *New in Pygments 1.0.* """ name = 'Python console session' aliases = ['pycon'] mimetypes = ['text/x-python-doctest'] def __init__(self, **options): self.python3 = get_bool_opt(options, 'python3', False) Lexer.__init__(self, **options) def get_tokens_unprocessed(self, text): if self.python3: pylexer = Python3Lexer(**self.options) tblexer = Python3TracebackLexer(**self.options) else: pylexer = PythonLexer(**self.options) tblexer = PythonTracebackLexer(**self.options) curcode = '' insertions = [] curtb = '' tbindex = 0 tb = 0 for match in line_re.finditer(text): line = match.group() if line.startswith(u'>>> ') or line.startswith(u'... '): tb = 0 insertions.append((len(curcode), [(0, Generic.Prompt, line[:4])])) curcode += line[4:] elif line.rstrip() == u'...' and not tb: # only a new >>> prompt can end an exception block # otherwise an ellipsis in place of the traceback frames # will be mishandled insertions.append((len(curcode), [(0, Generic.Prompt, u'...')])) curcode += line[3:] else: if curcode: for item in do_insertions(insertions, pylexer.get_tokens_unprocessed(curcode)): yield item curcode = '' insertions = [] if (line.startswith(u'Traceback (most recent call last):') or re.match(ur' File "[^"]+", line \d+\n$', line)): tb = 1 curtb = line tbindex = match.start() elif line == 'KeyboardInterrupt\n': yield match.start(), Name.Class, line elif tb: curtb += line if not (line.startswith(' ') or line.strip() == u'...'): tb = 0 for i, t, v in tblexer.get_tokens_unprocessed(curtb): yield tbindex+i, t, v else: yield match.start(), Generic.Output, line if curcode: for item in do_insertions(insertions, pylexer.get_tokens_unprocessed(curcode)): yield item class PythonTracebackLexer(RegexLexer): """ For Python tracebacks. *New in Pygments 0.7.* """ name = 'Python Traceback' aliases = ['pytb'] filenames = ['*.pytb'] mimetypes = ['text/x-python-traceback'] tokens = { 'root': [ (r'^Traceback \(most recent call last\):\n', Generic.Traceback, 'intb'), # SyntaxError starts with this. (r'^(?= File "[^"]+", line \d+)', Generic.Traceback, 'intb'), (r'^.*\n', Other), ], 'intb': [ (r'^( File )("[^"]+")(, line )(\d+)(, in )(.+)(\n)', bygroups(Text, Name.Builtin, Text, Number, Text, Name, Text)), (r'^( File )("[^"]+")(, line )(\d+)(\n)', bygroups(Text, Name.Builtin, Text, Number, Text)), (r'^( )(.+)(\n)', bygroups(Text, using(PythonLexer), Text)), (r'^([ \t]*)(\.\.\.)(\n)', bygroups(Text, Comment, Text)), # for doctests... (r'^([^:]+)(: )(.+)(\n)', bygroups(Generic.Error, Text, Name, Text), '#pop'), (r'^([a-zA-Z_][a-zA-Z0-9_]*)(:?\n)', bygroups(Generic.Error, Text), '#pop') ], } class Python3TracebackLexer(RegexLexer): """ For Python 3.0 tracebacks, with support for chained exceptions. *New in Pygments 1.0.* """ name = 'Python 3.0 Traceback' aliases = ['py3tb'] filenames = ['*.py3tb'] mimetypes = ['text/x-python3-traceback'] tokens = { 'root': [ (r'\n', Text), (r'^Traceback \(most recent call last\):\n', Generic.Traceback, 'intb'), (r'^During handling of the above exception, another ' r'exception occurred:\n\n', Generic.Traceback), (r'^The above exception was the direct cause of the ' r'following exception:\n\n', Generic.Traceback), (r'^(?= File "[^"]+", line \d+)', Generic.Traceback, 'intb'), ], 'intb': [ (r'^( File )("[^"]+")(, line )(\d+)(, in )(.+)(\n)', bygroups(Text, Name.Builtin, Text, Number, Text, Name, Text)), (r'^( File )("[^"]+")(, line )(\d+)(\n)', bygroups(Text, Name.Builtin, Text, Number, Text)), (r'^( )(.+)(\n)', bygroups(Text, using(Python3Lexer), Text)), (r'^([ \t]*)(\.\.\.)(\n)', bygroups(Text, Comment, Text)), # for doctests... (r'^([^:]+)(: )(.+)(\n)', bygroups(Generic.Error, Text, Name, Text), '#pop'), (r'^([a-zA-Z_][a-zA-Z0-9_]*)(:?\n)', bygroups(Generic.Error, Text), '#pop') ], } class RubyLexer(ExtendedRegexLexer): """ For `Ruby `_ source code. """ name = 'Ruby' aliases = ['rb', 'ruby', 'duby'] filenames = ['*.rb', '*.rbw', 'Rakefile', '*.rake', '*.gemspec', '*.rbx', '*.duby'] mimetypes = ['text/x-ruby', 'application/x-ruby'] flags = re.DOTALL | re.MULTILINE def heredoc_callback(self, match, ctx): # okay, this is the hardest part of parsing Ruby... # match: 1 = <<-?, 2 = quote? 3 = name 4 = quote? 5 = rest of line start = match.start(1) yield start, Operator, match.group(1) # <<-? yield match.start(2), String.Heredoc, match.group(2) # quote ", ', ` yield match.start(3), Name.Constant, match.group(3) # heredoc name yield match.start(4), String.Heredoc, match.group(4) # quote again heredocstack = ctx.__dict__.setdefault('heredocstack', []) outermost = not bool(heredocstack) heredocstack.append((match.group(1) == '<<-', match.group(3))) ctx.pos = match.start(5) ctx.end = match.end(5) # this may find other heredocs for i, t, v in self.get_tokens_unprocessed(context=ctx): yield i, t, v ctx.pos = match.end() if outermost: # this is the outer heredoc again, now we can process them all for tolerant, hdname in heredocstack: lines = [] for match in line_re.finditer(ctx.text, ctx.pos): if tolerant: check = match.group().strip() else: check = match.group().rstrip() if check == hdname: for amatch in lines: yield amatch.start(), String.Heredoc, amatch.group() yield match.start(), Name.Constant, match.group() ctx.pos = match.end() break else: lines.append(match) else: # end of heredoc not found -- error! for amatch in lines: yield amatch.start(), Error, amatch.group() ctx.end = len(ctx.text) del heredocstack[:] def gen_rubystrings_rules(): def intp_regex_callback(self, match, ctx): yield match.start(1), String.Regex, match.group(1) # begin nctx = LexerContext(match.group(3), 0, ['interpolated-regex']) for i, t, v in self.get_tokens_unprocessed(context=nctx): yield match.start(3)+i, t, v yield match.start(4), String.Regex, match.group(4) # end[mixounse]* ctx.pos = match.end() def intp_string_callback(self, match, ctx): yield match.start(1), String.Other, match.group(1) nctx = LexerContext(match.group(3), 0, ['interpolated-string']) for i, t, v in self.get_tokens_unprocessed(context=nctx): yield match.start(3)+i, t, v yield match.start(4), String.Other, match.group(4) # end ctx.pos = match.end() states = {} states['strings'] = [ # easy ones (r'\:@{0,2}([a-zA-Z_]\w*[\!\?]?|\*\*?|[-+]@?|' r'[/%&|^`~]|\[\]=?|<<|>>|<=?>|>=?|===?)', String.Symbol), (r":'(\\\\|\\'|[^'])*'", String.Symbol), (r"'(\\\\|\\'|[^'])*'", String.Single), (r':"', String.Symbol, 'simple-sym'), (r'([a-zA-Z_][a-zA-Z0-9]*)(:)(?!:)', bygroups(String.Symbol, Punctuation)), # Since Ruby 1.9 (r'"', String.Double, 'simple-string'), (r'(?', 'ab'): states[name+'-intp-string'] = [ (r'\\[\\' + lbrace + rbrace + ']', String.Other), (r'(?! states['strings'] += [ # %r regex (r'(%r([^a-zA-Z0-9]))((?:\\\2|(?!\2).)*)(\2[mixounse]*)', intp_regex_callback), # regular fancy strings with qsw (r'%[qsw]([^a-zA-Z0-9])((?:\\\1|(?!\1).)*)\1', String.Other), (r'(%[QWx]([^a-zA-Z0-9]))((?:\\\2|(?!\2).)*)(\2)', intp_string_callback), # special forms of fancy strings after operators or # in method calls with braces (r'(?<=[-+/*%=<>&!^|~,(])(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)', bygroups(Text, String.Other, None)), # and because of fixed width lookbehinds the whole thing a # second time for line startings... (r'^(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)', bygroups(Text, String.Other, None)), # all regular fancy strings without qsw (r'(%([^a-zA-Z0-9\s]))((?:\\\2|(?!\2).)*)(\2)', intp_string_callback), ] return states tokens = { 'root': [ (r'#.*?$', Comment.Single), (r'=begin\s.*?\n=end.*?$', Comment.Multiline), # keywords (r'(BEGIN|END|alias|begin|break|case|defined\?|' r'do|else|elsif|end|ensure|for|if|in|next|redo|' r'rescue|raise|retry|return|super|then|undef|unless|until|when|' r'while|yield)\b', Keyword), # start of function, class and module names (r'(module)(\s+)([a-zA-Z_][a-zA-Z0-9_]*' r'(?:::[a-zA-Z_][a-zA-Z0-9_]*)*)', bygroups(Keyword, Text, Name.Namespace)), (r'(def)(\s+)', bygroups(Keyword, Text), 'funcname'), (r'def(?=[*%&^`~+-/\[<>=])', Keyword, 'funcname'), (r'(class)(\s+)', bygroups(Keyword, Text), 'classname'), # special methods (r'(initialize|new|loop|include|extend|raise|attr_reader|' r'attr_writer|attr_accessor|attr|catch|throw|private|' r'module_function|public|protected|true|false|nil)\b', Keyword.Pseudo), (r'(not|and|or)\b', Operator.Word), (r'(autoload|block_given|const_defined|eql|equal|frozen|include|' r'instance_of|is_a|iterator|kind_of|method_defined|nil|' r'private_method_defined|protected_method_defined|' r'public_method_defined|respond_to|tainted)\?', Name.Builtin), (r'(chomp|chop|exit|gsub|sub)!', Name.Builtin), (r'(?~!:])|' r'(?<=(?:\s|;)when\s)|' r'(?<=(?:\s|;)or\s)|' r'(?<=(?:\s|;)and\s)|' r'(?<=(?:\s|;|\.)index\s)|' r'(?<=(?:\s|;|\.)scan\s)|' r'(?<=(?:\s|;|\.)sub\s)|' r'(?<=(?:\s|;|\.)sub!\s)|' r'(?<=(?:\s|;|\.)gsub\s)|' r'(?<=(?:\s|;|\.)gsub!\s)|' r'(?<=(?:\s|;|\.)match\s)|' r'(?<=(?:\s|;)if\s)|' r'(?<=(?:\s|;)elsif\s)|' r'(?<=^when\s)|' r'(?<=^index\s)|' r'(?<=^scan\s)|' r'(?<=^sub\s)|' r'(?<=^gsub\s)|' r'(?<=^sub!\s)|' r'(?<=^gsub!\s)|' r'(?<=^match\s)|' r'(?<=^if\s)|' r'(?<=^elsif\s)' r')(\s*)(/)', bygroups(Text, String.Regex), 'multiline-regex'), # multiline regex (in method calls or subscripts) (r'(?<=\(|,|\[)/', String.Regex, 'multiline-regex'), # multiline regex (this time the funny no whitespace rule) (r'(\s+)(/)(?![\s=])', bygroups(Text, String.Regex), 'multiline-regex'), # lex numbers and ignore following regular expressions which # are division operators in fact (grrrr. i hate that. any # better ideas?) # since pygments 0.7 we also eat a "?" operator after numbers # so that the char operator does not work. Chars are not allowed # there so that you can use the ternary operator. # stupid example: # x>=0?n[x]:"" (r'(0_?[0-7]+(?:_[0-7]+)*)(\s*)([/?])?', bygroups(Number.Oct, Text, Operator)), (r'(0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*)(\s*)([/?])?', bygroups(Number.Hex, Text, Operator)), (r'(0b[01]+(?:_[01]+)*)(\s*)([/?])?', bygroups(Number.Bin, Text, Operator)), (r'([\d]+(?:_\d+)*)(\s*)([/?])?', bygroups(Number.Integer, Text, Operator)), # Names (r'@@[a-zA-Z_][a-zA-Z0-9_]*', Name.Variable.Class), (r'@[a-zA-Z_][a-zA-Z0-9_]*', Name.Variable.Instance), (r'\$[a-zA-Z0-9_]+', Name.Variable.Global), (r'\$[!@&`\'+~=/\\,;.<>_*$?:"]', Name.Variable.Global), (r'\$-[0adFiIlpvw]', Name.Variable.Global), (r'::', Operator), include('strings'), # chars (r'\?(\\[MC]-)*' # modifiers r'(\\([\\abefnrstv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})|\S)' r'(?!\w)', String.Char), (r'[A-Z][a-zA-Z0-9_]+', Name.Constant), # this is needed because ruby attributes can look # like keywords (class) or like this: ` ?!? (r'(\.|::)([a-zA-Z_]\w*[\!\?]?|[*%&^`~+-/\[<>=])', bygroups(Operator, Name)), (r'[a-zA-Z_]\w*[\!\?]?', Name), (r'(\[|\]|\*\*|<>?|>=|<=|<=>|=~|={3}|' r'!~|&&?|\|\||\.{1,3})', Operator), (r'[-+/*%=<>&!^|~]=?', Operator), (r'[(){};,/?:\\]', Punctuation), (r'\s+', Text) ], 'funcname': [ (r'\(', Punctuation, 'defexpr'), (r'(?:([a-zA-Z_][a-zA-Z0-9_]*)(\.))?' r'([a-zA-Z_]\w*[\!\?]?|\*\*?|[-+]@?|' r'[/%&|^`~]|\[\]=?|<<|>>|<=?>|>=?|===?)', bygroups(Name.Class, Operator, Name.Function), '#pop'), (r'', Text, '#pop') ], 'classname': [ (r'\(', Punctuation, 'defexpr'), (r'<<', Operator, '#pop'), (r'[A-Z_]\w*', Name.Class, '#pop'), (r'', Text, '#pop') ], 'defexpr': [ (r'(\))(\.|::)?', bygroups(Punctuation, Operator), '#pop'), (r'\(', Operator, '#push'), include('root') ], 'in-intp': [ ('}', String.Interpol, '#pop'), include('root'), ], 'string-intp': [ (r'#{', String.Interpol, 'in-intp'), (r'#@@?[a-zA-Z_][a-zA-Z0-9_]*', String.Interpol), (r'#\$[a-zA-Z_][a-zA-Z0-9_]*', String.Interpol) ], 'string-intp-escaped': [ include('string-intp'), (r'\\([\\abefnrstv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})', String.Escape) ], 'interpolated-regex': [ include('string-intp'), (r'[\\#]', String.Regex), (r'[^\\#]+', String.Regex), ], 'interpolated-string': [ include('string-intp'), (r'[\\#]', String.Other), (r'[^\\#]+', String.Other), ], 'multiline-regex': [ include('string-intp'), (r'\\\\', String.Regex), (r'\\/', String.Regex), (r'[\\#]', String.Regex), (r'[^\\/#]+', String.Regex), (r'/[mixounse]*', String.Regex, '#pop'), ], 'end-part': [ (r'.+', Comment.Preproc, '#pop') ] } tokens.update(gen_rubystrings_rules()) def analyse_text(text): return shebang_matches(text, r'ruby(1\.\d)?') class RubyConsoleLexer(Lexer): """ For Ruby interactive console (**irb**) output like: .. sourcecode:: rbcon irb(main):001:0> a = 1 => 1 irb(main):002:0> puts a 1 => nil """ name = 'Ruby irb session' aliases = ['rbcon', 'irb'] mimetypes = ['text/x-ruby-shellsession'] _prompt_re = re.compile('irb\([a-zA-Z_][a-zA-Z0-9_]*\):\d{3}:\d+[>*"\'] ' '|>> |\?> ') def get_tokens_unprocessed(self, text): rblexer = RubyLexer(**self.options) curcode = '' insertions = [] for match in line_re.finditer(text): line = match.group() m = self._prompt_re.match(line) if m is not None: end = m.end() insertions.append((len(curcode), [(0, Generic.Prompt, line[:end])])) curcode += line[end:] else: if curcode: for item in do_insertions(insertions, rblexer.get_tokens_unprocessed(curcode)): yield item curcode = '' insertions = [] yield match.start(), Generic.Output, line if curcode: for item in do_insertions(insertions, rblexer.get_tokens_unprocessed(curcode)): yield item class PerlLexer(RegexLexer): """ For `Perl `_ source code. """ name = 'Perl' aliases = ['perl', 'pl'] filenames = ['*.pl', '*.pm'] mimetypes = ['text/x-perl', 'application/x-perl'] flags = re.DOTALL | re.MULTILINE # TODO: give this to a perl guy who knows how to parse perl... tokens = { 'balanced-regex': [ (r'/(\\\\|\\[^\\]|[^\\/])*/[egimosx]*', String.Regex, '#pop'), (r'!(\\\\|\\[^\\]|[^\\!])*![egimosx]*', String.Regex, '#pop'), (r'\\(\\\\|[^\\])*\\[egimosx]*', String.Regex, '#pop'), (r'{(\\\\|\\[^\\]|[^\\}])*}[egimosx]*', String.Regex, '#pop'), (r'<(\\\\|\\[^\\]|[^\\>])*>[egimosx]*', String.Regex, '#pop'), (r'\[(\\\\|\\[^\\]|[^\\\]])*\][egimosx]*', String.Regex, '#pop'), (r'\((\\\\|\\[^\\]|[^\\\)])*\)[egimosx]*', String.Regex, '#pop'), (r'@(\\\\|\\[^\\]|[^\\\@])*@[egimosx]*', String.Regex, '#pop'), (r'%(\\\\|\\[^\\]|[^\\\%])*%[egimosx]*', String.Regex, '#pop'), (r'\$(\\\\|\\[^\\]|[^\\\$])*\$[egimosx]*', String.Regex, '#pop'), ], 'root': [ (r'\#.*?$', Comment.Single), (r'^=[a-zA-Z0-9]+\s+.*?\n=cut', Comment.Multiline), (r'(case|continue|do|else|elsif|for|foreach|if|last|my|' r'next|our|redo|reset|then|unless|until|while|use|' r'print|new|BEGIN|CHECK|INIT|END|return)\b', Keyword), (r'(format)(\s+)([a-zA-Z0-9_]+)(\s*)(=)(\s*\n)', bygroups(Keyword, Text, Name, Text, Punctuation, Text), 'format'), (r'(eq|lt|gt|le|ge|ne|not|and|or|cmp)\b', Operator.Word), # common delimiters (r's/(\\\\|\\[^\\]|[^\\/])*/(\\\\|\\[^\\]|[^\\/])*/[egimosx]*', String.Regex), (r's!(\\\\|\\!|[^!])*!(\\\\|\\!|[^!])*![egimosx]*', String.Regex), (r's\\(\\\\|[^\\])*\\(\\\\|[^\\])*\\[egimosx]*', String.Regex), (r's@(\\\\|\\[^\\]|[^\\@])*@(\\\\|\\[^\\]|[^\\@])*@[egimosx]*', String.Regex), (r's%(\\\\|\\[^\\]|[^\\%])*%(\\\\|\\[^\\]|[^\\%])*%[egimosx]*', String.Regex), # balanced delimiters (r's{(\\\\|\\[^\\]|[^\\}])*}\s*', String.Regex, 'balanced-regex'), (r's<(\\\\|\\[^\\]|[^\\>])*>\s*', String.Regex, 'balanced-regex'), (r's\[(\\\\|\\[^\\]|[^\\\]])*\]\s*', String.Regex, 'balanced-regex'), (r's\((\\\\|\\[^\\]|[^\\\)])*\)\s*', String.Regex, 'balanced-regex'), (r'm?/(\\\\|\\[^\\]|[^\\/\n])*/[gcimosx]*', String.Regex), (r'm(?=[/!\\{<\[\(@%\$])', String.Regex, 'balanced-regex'), (r'((?<==~)|(?<=\())\s*/(\\\\|\\[^\\]|[^\\/])*/[gcimosx]*', String.Regex), (r'\s+', Text), (r'(abs|accept|alarm|atan2|bind|binmode|bless|caller|chdir|' r'chmod|chomp|chop|chown|chr|chroot|close|closedir|connect|' r'continue|cos|crypt|dbmclose|dbmopen|defined|delete|die|' r'dump|each|endgrent|endhostent|endnetent|endprotoent|' r'endpwent|endservent|eof|eval|exec|exists|exit|exp|fcntl|' r'fileno|flock|fork|format|formline|getc|getgrent|getgrgid|' r'getgrnam|gethostbyaddr|gethostbyname|gethostent|getlogin|' r'getnetbyaddr|getnetbyname|getnetent|getpeername|getpgrp|' r'getppid|getpriority|getprotobyname|getprotobynumber|' r'getprotoent|getpwent|getpwnam|getpwuid|getservbyname|' r'getservbyport|getservent|getsockname|getsockopt|glob|gmtime|' r'goto|grep|hex|import|index|int|ioctl|join|keys|kill|last|' r'lc|lcfirst|length|link|listen|local|localtime|log|lstat|' r'map|mkdir|msgctl|msgget|msgrcv|msgsnd|my|next|no|oct|open|' r'opendir|ord|our|pack|package|pipe|pop|pos|printf|' r'prototype|push|quotemeta|rand|read|readdir|' r'readline|readlink|readpipe|recv|redo|ref|rename|require|' r'reverse|rewinddir|rindex|rmdir|scalar|seek|seekdir|' r'select|semctl|semget|semop|send|setgrent|sethostent|setnetent|' r'setpgrp|setpriority|setprotoent|setpwent|setservent|' r'setsockopt|shift|shmctl|shmget|shmread|shmwrite|shutdown|' r'sin|sleep|socket|socketpair|sort|splice|split|sprintf|sqrt|' r'srand|stat|study|substr|symlink|syscall|sysopen|sysread|' r'sysseek|system|syswrite|tell|telldir|tie|tied|time|times|tr|' r'truncate|uc|ucfirst|umask|undef|unlink|unpack|unshift|untie|' r'utime|values|vec|wait|waitpid|wantarray|warn|write' r')\b', Name.Builtin), (r'((__(DATA|DIE|WARN)__)|(STD(IN|OUT|ERR)))\b', Name.Builtin.Pseudo), (r'<<([\'"]?)([a-zA-Z_][a-zA-Z0-9_]*)\1;?\n.*?\n\2\n', String), (r'__END__', Comment.Preproc, 'end-part'), (r'\$\^[ADEFHILMOPSTWX]', Name.Variable.Global), (r"\$[\\\"\[\]'&`+*.,;=%~?@$!<>(^|/-](?!\w)", Name.Variable.Global), (r'[$@%#]+', Name.Variable, 'varname'), (r'0_?[0-7]+(_[0-7]+)*', Number.Oct), (r'0x[0-9A-Fa-f]+(_[0-9A-Fa-f]+)*', Number.Hex), (r'0b[01]+(_[01]+)*', Number.Bin), (r'(?i)(\d*(_\d*)*\.\d+(_\d*)*|\d+(_\d*)*\.\d+(_\d*)*)(e[+-]?\d+)?', Number.Float), (r'(?i)\d+(_\d*)*e[+-]?\d+(_\d*)*', Number.Float), (r'\d+(_\d+)*', Number.Integer), (r"'(\\\\|\\[^\\]|[^'\\])*'", String), (r'"(\\\\|\\[^\\]|[^"\\])*"', String), (r'`(\\\\|\\[^\\]|[^`\\])*`', String.Backtick), (r'<([^\s>]+)>', String.Regex), (r'(q|qq|qw|qr|qx)\{', String.Other, 'cb-string'), (r'(q|qq|qw|qr|qx)\(', String.Other, 'rb-string'), (r'(q|qq|qw|qr|qx)\[', String.Other, 'sb-string'), (r'(q|qq|qw|qr|qx)\<', String.Other, 'lt-string'), (r'(q|qq|qw|qr|qx)([^a-zA-Z0-9])(.|\n)*?\2', String.Other), (r'package\s+', Keyword, 'modulename'), (r'sub\s+', Keyword, 'funcname'), (r'(\[\]|\*\*|::|<<|>>|>=|<=>|<=|={3}|!=|=~|' r'!~|&&?|\|\||\.{1,3})', Operator), (r'[-+/*%=<>&^|!\\~]=?', Operator), (r'[\(\)\[\]:;,<>/\?\{\}]', Punctuation), # yes, there's no shortage # of punctuation in Perl! (r'(?=\w)', Name, 'name'), ], 'format': [ (r'\.\n', String.Interpol, '#pop'), (r'[^\n]*\n', String.Interpol), ], 'varname': [ (r'\s+', Text), (r'\{', Punctuation, '#pop'), # hash syntax? (r'\)|,', Punctuation, '#pop'), # argument specifier (r'[a-zA-Z0-9_]+::', Name.Namespace), (r'[a-zA-Z0-9_:]+', Name.Variable, '#pop'), ], 'name': [ (r'[a-zA-Z0-9_]+::', Name.Namespace), (r'[a-zA-Z0-9_:]+', Name, '#pop'), (r'[A-Z_]+(?=[^a-zA-Z0-9_])', Name.Constant, '#pop'), (r'(?=[^a-zA-Z0-9_])', Text, '#pop'), ], 'modulename': [ (r'[a-zA-Z_]\w*', Name.Namespace, '#pop') ], 'funcname': [ (r'[a-zA-Z_]\w*[\!\?]?', Name.Function), (r'\s+', Text), # argument declaration (r'(\([$@%]*\))(\s*)', bygroups(Punctuation, Text)), (r'.*?{', Punctuation, '#pop'), (r';', Punctuation, '#pop'), ], 'cb-string': [ (r'\\[\{\}\\]', String.Other), (r'\\', String.Other), (r'\{', String.Other, 'cb-string'), (r'\}', String.Other, '#pop'), (r'[^\{\}\\]+', String.Other) ], 'rb-string': [ (r'\\[\(\)\\]', String.Other), (r'\\', String.Other), (r'\(', String.Other, 'rb-string'), (r'\)', String.Other, '#pop'), (r'[^\(\)]+', String.Other) ], 'sb-string': [ (r'\\[\[\]\\]', String.Other), (r'\\', String.Other), (r'\[', String.Other, 'sb-string'), (r'\]', String.Other, '#pop'), (r'[^\[\]]+', String.Other) ], 'lt-string': [ (r'\\[\<\>\\]', String.Other), (r'\\', String.Other), (r'\<', String.Other, 'lt-string'), (r'\>', String.Other, '#pop'), (r'[^\<\>]+', String.Other) ], 'end-part': [ (r'.+', Comment.Preproc, '#pop') ] } def analyse_text(text): if shebang_matches(text, r'perl'): return True if 'my $' in text: return 0.9 return 0.1 # who knows, might still be perl! class LuaLexer(RegexLexer): """ For `Lua `_ source code. Additional options accepted: `func_name_highlighting` If given and ``True``, highlight builtin function names (default: ``True``). `disabled_modules` If given, must be a list of module names whose function names should not be highlighted. By default all modules are highlighted. To get a list of allowed modules have a look into the `_luabuiltins` module: .. sourcecode:: pycon >>> from pygments.lexers._luabuiltins import MODULES >>> MODULES.keys() ['string', 'coroutine', 'modules', 'io', 'basic', ...] """ name = 'Lua' aliases = ['lua'] filenames = ['*.lua', '*.wlua'] mimetypes = ['text/x-lua', 'application/x-lua'] tokens = { 'root': [ # lua allows a file to start with a shebang (r'#!(.*?)$', Comment.Preproc), (r'', Text, 'base'), ], 'base': [ (r'(?s)--\[(=*)\[.*?\]\1\]', Comment.Multiline), ('--.*$', Comment.Single), (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number.Float), (r'(?i)\d+e[+-]?\d+', Number.Float), ('(?i)0x[0-9a-f]*', Number.Hex), (r'\d+', Number.Integer), (r'\n', Text), (r'[^\S\n]', Text), # multiline strings (r'(?s)\[(=*)\[.*?\]\1\]', String), (r'(==|~=|<=|>=|\.\.\.|\.\.|[=+\-*/%^<>#])', Operator), (r'[\[\]\{\}\(\)\.,:;]', Punctuation), (r'(and|or|not)\b', Operator.Word), ('(break|do|else|elseif|end|for|if|in|repeat|return|then|until|' r'while)\b', Keyword), (r'(local)\b', Keyword.Declaration), (r'(true|false|nil)\b', Keyword.Constant), (r'(function)\b', Keyword, 'funcname'), (r'[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?', Name), ("'", String.Single, combined('stringescape', 'sqs')), ('"', String.Double, combined('stringescape', 'dqs')) ], 'funcname': [ (r'\s+', Text), ('(?:([A-Za-z_][A-Za-z0-9_]*)(\.))?([A-Za-z_][A-Za-z0-9_]*)', bygroups(Name.Class, Punctuation, Name.Function), '#pop'), # inline function ('\(', Punctuation, '#pop'), ], # if I understand correctly, every character is valid in a lua string, # so this state is only for later corrections 'string': [ ('.', String) ], 'stringescape': [ (r'''\\([abfnrtv\\"']|\d{1,3})''', String.Escape) ], 'sqs': [ ("'", String, '#pop'), include('string') ], 'dqs': [ ('"', String, '#pop'), include('string') ] } def __init__(self, **options): self.func_name_highlighting = get_bool_opt( options, 'func_name_highlighting', True) self.disabled_modules = get_list_opt(options, 'disabled_modules', []) self._functions = set() if self.func_name_highlighting: from pygments.lexers._luabuiltins import MODULES for mod, func in MODULES.iteritems(): if mod not in self.disabled_modules: self._functions.update(func) RegexLexer.__init__(self, **options) def get_tokens_unprocessed(self, text): for index, token, value in \ RegexLexer.get_tokens_unprocessed(self, text): if token is Name: if value in self._functions: yield index, Name.Builtin, value continue elif '.' in value: a, b = value.split('.') yield index, Name, a yield index + len(a), Punctuation, u'.' yield index + len(a) + 1, Name, b continue yield index, token, value class MoonScriptLexer(LuaLexer): """ For `MoonScript `_ source code. *New in Pygments 1.5.* """ name = "MoonScript" aliases = ["moon", "moonscript"] filenames = ["*.moon"] mimetypes = ['text/x-moonscript', 'application/x-moonscript'] tokens = { 'root': [ (r'#!(.*?)$', Comment.Preproc), (r'', Text, 'base'), ], 'base': [ ('--.*$', Comment.Single), (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number.Float), (r'(?i)\d+e[+-]?\d+', Number.Float), (r'(?i)0x[0-9a-f]*', Number.Hex), (r'\d+', Number.Integer), (r'\n', Text), (r'[^\S\n]+', Text), (r'(?s)\[(=*)\[.*?\]\1\]', String), (r'(->|=>)', Name.Function), (r':[a-zA-Z_][a-zA-Z0-9_]*', Name.Variable), (r'(==|!=|~=|<=|>=|\.\.\.|\.\.|[=+\-*/%^<>#!.\\:])', Operator), (r'[;,]', Punctuation), (r'[\[\]\{\}\(\)]', Keyword.Type), (r'[a-zA-Z_][a-zA-Z0-9_]*:', Name.Variable), (r"(class|extends|if|then|super|do|with|import|export|" r"while|elseif|return|for|in|from|when|using|else|" r"and|or|not|switch|break)\b", Keyword), (r'(true|false|nil)\b', Keyword.Constant), (r'(and|or|not)\b', Operator.Word), (r'(self)\b', Name.Builtin.Pseudo), (r'@@?([a-zA-Z_][a-zA-Z0-9_]*)?', Name.Variable.Class), (r'[A-Z]\w*', Name.Class), # proper name (r'[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?', Name), ("'", String.Single, combined('stringescape', 'sqs')), ('"', String.Double, combined('stringescape', 'dqs')) ], 'stringescape': [ (r'''\\([abfnrtv\\"']|\d{1,3})''', String.Escape) ], 'sqs': [ ("'", String.Single, '#pop'), (".", String) ], 'dqs': [ ('"', String.Double, '#pop'), (".", String) ] } def get_tokens_unprocessed(self, text): # set . as Operator instead of Punctuation for index, token, value in \ LuaLexer.get_tokens_unprocessed(self, text): if token == Punctuation and value == ".": token = Operator yield index, token, value class CrocLexer(RegexLexer): """ For `Croc `_ source. """ name = 'Croc' filenames = ['*.croc'] aliases = ['croc'] mimetypes = ['text/x-crocsrc'] tokens = { 'root': [ (r'\n', Text), (r'\s+', Text), # Comments (r'//(.*?)\n', Comment.Single), (r'/\*', Comment.Multiline, 'nestedcomment'), # Keywords (r'(as|assert|break|case|catch|class|continue|default' r'|do|else|finally|for|foreach|function|global|namespace' r'|if|import|in|is|local|module|return|scope|super|switch' r'|this|throw|try|vararg|while|with|yield)\b', Keyword), (r'(false|true|null)\b', Keyword.Constant), # FloatLiteral (r'([0-9][0-9_]*)(?=[.eE])(\.[0-9][0-9_]*)?([eE][+\-]?[0-9_]+)?', Number.Float), # IntegerLiteral # -- Binary (r'0[bB][01][01_]*', Number), # -- Hexadecimal (r'0[xX][0-9a-fA-F][0-9a-fA-F_]*', Number.Hex), # -- Decimal (r'([0-9][0-9_]*)(?![.eE])', Number.Integer), # CharacterLiteral (r"""'(\\['"\\nrt]|\\x[0-9a-fA-F]{2}|\\[0-9]{1,3}""" r"""|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|.)'""", String.Char ), # StringLiteral # -- WysiwygString (r'@"(""|[^"])*"', String), (r'@`(``|[^`])*`', String), (r"@'(''|[^'])*'", String), # -- DoubleQuotedString (r'"(\\\\|\\"|[^"])*"', String), # Tokens ( r'(~=|\^=|%=|\*=|==|!=|>>>=|>>>|>>=|>>|>=|<=>|\?=|-\>' r'|<<=|<<|<=|\+\+|\+=|--|-=|\|\||\|=|&&|&=|\.\.|/=)' r'|[-/.&$@|\+<>!()\[\]{}?,;:=*%^~#\\]', Punctuation ), # Identifier (r'[a-zA-Z_]\w*', Name), ], 'nestedcomment': [ (r'[^*/]+', Comment.Multiline), (r'/\*', Comment.Multiline, '#push'), (r'\*/', Comment.Multiline, '#pop'), (r'[*/]', Comment.Multiline), ], } class MiniDLexer(CrocLexer): """ For MiniD source. MiniD is now known as Croc. """ name = 'MiniD' filenames = ['*.md'] aliases = ['minid'] mimetypes = ['text/x-minidsrc'] class IoLexer(RegexLexer): """ For `Io `_ (a small, prototype-based programming language) source. *New in Pygments 0.10.* """ name = 'Io' filenames = ['*.io'] aliases = ['io'] mimetypes = ['text/x-iosrc'] tokens = { 'root': [ (r'\n', Text), (r'\s+', Text), # Comments (r'//(.*?)\n', Comment.Single), (r'#(.*?)\n', Comment.Single), (r'/(\\\n)?[*](.|\n)*?[*](\\\n)?/', Comment.Multiline), (r'/\+', Comment.Multiline, 'nestedcomment'), # DoubleQuotedString (r'"(\\\\|\\"|[^"])*"', String), # Operators (r'::=|:=|=|\(|\)|;|,|\*|-|\+|>|<|@|!|/|\||\^|\.|%|&|\[|\]|\{|\}', Operator), # keywords (r'(clone|do|doFile|doString|method|for|if|else|elseif|then)\b', Keyword), # constants (r'(nil|false|true)\b', Name.Constant), # names (r'(Object|list|List|Map|args|Sequence|Coroutine|File)\b', Name.Builtin), ('[a-zA-Z_][a-zA-Z0-9_]*', Name), # numbers (r'(\d+\.?\d*|\d*\.\d+)([eE][+-]?[0-9]+)?', Number.Float), (r'\d+', Number.Integer) ], 'nestedcomment': [ (r'[^+/]+', Comment.Multiline), (r'/\+', Comment.Multiline, '#push'), (r'\+/', Comment.Multiline, '#pop'), (r'[+/]', Comment.Multiline), ] } class TclLexer(RegexLexer): """ For Tcl source code. *New in Pygments 0.10.* """ keyword_cmds_re = ( r'\b(after|apply|array|break|catch|continue|elseif|else|error|' r'eval|expr|for|foreach|global|if|namespace|proc|rename|return|' r'set|switch|then|trace|unset|update|uplevel|upvar|variable|' r'vwait|while)\b' ) builtin_cmds_re = ( r'\b(append|bgerror|binary|cd|chan|clock|close|concat|dde|dict|' r'encoding|eof|exec|exit|fblocked|fconfigure|fcopy|file|' r'fileevent|flush|format|gets|glob|history|http|incr|info|interp|' r'join|lappend|lassign|lindex|linsert|list|llength|load|loadTk|' r'lrange|lrepeat|lreplace|lreverse|lsearch|lset|lsort|mathfunc|' r'mathop|memory|msgcat|open|package|pid|pkg::create|pkg_mkIndex|' r'platform|platform::shell|puts|pwd|re_syntax|read|refchan|' r'regexp|registry|regsub|scan|seek|socket|source|split|string|' r'subst|tell|time|tm|unknown|unload)\b' ) name = 'Tcl' aliases = ['tcl'] filenames = ['*.tcl'] mimetypes = ['text/x-tcl', 'text/x-script.tcl', 'application/x-tcl'] def _gen_command_rules(keyword_cmds_re, builtin_cmds_re, context=""): return [ (keyword_cmds_re, Keyword, 'params' + context), (builtin_cmds_re, Name.Builtin, 'params' + context), (r'([\w\.\-]+)', Name.Variable, 'params' + context), (r'#', Comment, 'comment'), ] tokens = { 'root': [ include('command'), include('basic'), include('data'), (r'}', Keyword), # HACK: somehow we miscounted our braces ], 'command': _gen_command_rules(keyword_cmds_re, builtin_cmds_re), 'command-in-brace': _gen_command_rules(keyword_cmds_re, builtin_cmds_re, "-in-brace"), 'command-in-bracket': _gen_command_rules(keyword_cmds_re, builtin_cmds_re, "-in-bracket"), 'command-in-paren': _gen_command_rules(keyword_cmds_re, builtin_cmds_re, "-in-paren"), 'basic': [ (r'\(', Keyword, 'paren'), (r'\[', Keyword, 'bracket'), (r'\{', Keyword, 'brace'), (r'"', String.Double, 'string'), (r'(eq|ne|in|ni)\b', Operator.Word), (r'!=|==|<<|>>|<=|>=|&&|\|\||\*\*|[-+~!*/%<>&^|?:]', Operator), ], 'data': [ (r'\s+', Text), (r'0x[a-fA-F0-9]+', Number.Hex), (r'0[0-7]+', Number.Oct), (r'\d+\.\d+', Number.Float), (r'\d+', Number.Integer), (r'\$([\w\.\-\:]+)', Name.Variable), (r'([\w\.\-\:]+)', Text), ], 'params': [ (r';', Keyword, '#pop'), (r'\n', Text, '#pop'), (r'(else|elseif|then)\b', Keyword), include('basic'), include('data'), ], 'params-in-brace': [ (r'}', Keyword, ('#pop', '#pop')), include('params') ], 'params-in-paren': [ (r'\)', Keyword, ('#pop', '#pop')), include('params') ], 'params-in-bracket': [ (r'\]', Keyword, ('#pop', '#pop')), include('params') ], 'string': [ (r'\[', String.Double, 'string-square'), (r'(?s)(\\\\|\\[0-7]+|\\.|[^"\\])', String.Double), (r'"', String.Double, '#pop') ], 'string-square': [ (r'\[', String.Double, 'string-square'), (r'(?s)(\\\\|\\[0-7]+|\\.|\\\n|[^\]\\])', String.Double), (r'\]', String.Double, '#pop') ], 'brace': [ (r'}', Keyword, '#pop'), include('command-in-brace'), include('basic'), include('data'), ], 'paren': [ (r'\)', Keyword, '#pop'), include('command-in-paren'), include('basic'), include('data'), ], 'bracket': [ (r'\]', Keyword, '#pop'), include('command-in-bracket'), include('basic'), include('data'), ], 'comment': [ (r'.*[^\\]\n', Comment, '#pop'), (r'.*\\\n', Comment), ], } def analyse_text(text): return shebang_matches(text, r'(tcl)') class FactorLexer(RegexLexer): """ Lexer for the `Factor `_ language. *New in Pygments 1.4.* """ name = 'Factor' aliases = ['factor'] filenames = ['*.factor'] mimetypes = ['text/x-factor'] flags = re.MULTILINE | re.UNICODE builtin_kernel = ( r'(?:or|2bi|2tri|while|wrapper|nip|4dip|wrapper\\?|bi\\*|' r'callstack>array|both\\?|hashcode|die|dupd|callstack|' r'callstack\\?|3dup|tri@|pick|curry|build|\\?execute|3bi|' r'prepose|>boolean|\\?if|clone|eq\\?|tri\\*|\\?|=|swapd|' r'2over|2keep|3keep|clear|2dup|when|not|tuple\\?|dup|2bi\\*|' r'2tri\\*|call|tri-curry|object|bi@|do|unless\\*|if\\*|loop|' r'bi-curry\\*|drop|when\\*|assert=|retainstack|assert\\?|-rot|' r'execute|2bi@|2tri@|boa|with|either\\?|3drop|bi|curry\\?|' r'datastack|until|3dip|over|3curry|tri-curry\\*|tri-curry@|swap|' r'and|2nip|throw|bi-curry|\\(clone\\)|hashcode\\*|compose|2dip|if|3tri|' r'unless|compose\\?|tuple|keep|2curry|equal\\?|assert|tri|2drop|' r'most||boolean\\?|identity-hashcode|identity-tuple\\?|' r'null|new|dip|bi-curry@|rot|xor|identity-tuple|boolean)\s' ) builtin_assocs = ( r'(?:\\?at|assoc\\?|assoc-clone-like|assoc=|delete-at\\*|' r'assoc-partition|extract-keys|new-assoc|value\\?|assoc-size|' r'map>assoc|push-at|assoc-like|key\\?|assoc-intersect|' r'assoc-refine|update|assoc-union|assoc-combine|at\\*|' r'assoc-empty\\?|at\\+|set-at|assoc-all\\?|assoc-subset\\?|' r'assoc-hashcode|change-at|assoc-each|assoc-diff|zip|values|' r'value-at|rename-at|inc-at|enum\\?|at|cache|assoc>map||' r'assoc|assoc-map|enum|value-at\\*|assoc-map-as|>alist|' r'assoc-filter-as|clear-assoc|assoc-stack|maybe-set-at|' r'substitute|assoc-filter|2cache|delete-at|assoc-find|keys|' r'assoc-any\\?|unzip)\s' ) builtin_combinators = ( r'(?:case|execute-effect|no-cond|no-case\\?|3cleave>quot|2cleave|' r'cond>quot|wrong-values\\?|no-cond\\?|cleave>quot|no-case|' r'case>quot|3cleave|wrong-values|to-fixed-point|alist>quot|' r'case-find|cond|cleave|call-effect|2cleave>quot|recursive-hashcode|' r'linear-case-quot|spread|spread>quot)\s' ) builtin_math = ( r'(?:number=|if-zero|next-power-of-2|each-integer|\\?1\\+|' r'fp-special\\?|imaginary-part|unless-zero|float>bits|number\\?|' r'fp-infinity\\?|bignum\\?|fp-snan\\?|denominator|fp-bitwise=|\\*|' r'\\+|power-of-2\\?|-|u>=|/|>=|bitand|log2-expects-positive|<|' r'log2|>|integer\\?|number|bits>double|2/|zero\\?|(find-integer)|' r'bits>float|float\\?|shift|ratio\\?|even\\?|ratio|fp-sign|bitnot|' r'>fixnum|complex\\?|/i|/f|byte-array>bignum|when-zero|sgn|>bignum|' r'next-float|u<|u>|mod|recip|rational|find-last-integer|>float|' r'(all-integers\\?)|2^|times|integer|fixnum\\?|neg|fixnum|sq|' r'bignum|(each-integer)|bit\\?|fp-qnan\\?|find-integer|complex|' r'|real|double>bits|bitor|rem|fp-nan-payload|all-integers\\?|' r'real-part|log2-expects-positive\\?|prev-float|align|unordered\\?|' r'float|fp-nan\\?|abs|bitxor|u<=|odd\\?|<=|/mod|rational\\?|>integer|' r'real\\?|numerator)\s' ) builtin_sequences = ( r'(?:member-eq\\?|append|assert-sequence=|find-last-from|trim-head-slice|' r'clone-like|3sequence|assert-sequence\\?|map-as|last-index-from|' r'reversed|index-from|cut\\*|pad-tail|remove-eq!|concat-as|' r'but-last|snip|trim-tail|nths|nth|2selector|sequence|slice\\?|' r'|partition|remove-nth|tail-slice|empty\\?|tail\\*|' r'if-empty|find-from|virtual-sequence\\?|member\\?|set-length|' r'drop-prefix|unclip|unclip-last-slice|iota|map-sum|' r'bounds-error\\?|sequence-hashcode-step|selector-for|' r'accumulate-as|map|start|midpoint@|\\(accumulate\\)|rest-slice|' r'prepend|fourth|sift|accumulate!|new-sequence|follow|map!|' r'like|first4|1sequence|reverse|slice|unless-empty|padding|' r'virtual@|repetition\\?|set-last|index|4sequence|max-length|' r'set-second|immutable-sequence|first2|first3|replicate-as|' r'reduce-index|unclip-slice|supremum|suffix!|insert-nth|' r'trim-tail-slice|tail|3append|short|count|suffix|concat|' r'flip|filter|sum|immutable\\?|reverse!|2sequence|map-integers|' r'delete-all|start\\*|indices|snip-slice|check-slice|sequence\\?|' r'head|map-find|filter!|append-as|reduce|sequence=|halves|' r'collapse-slice|interleave|2map|filter-as|binary-reduce|' r'slice-error\\?|product|bounds-check\\?|bounds-check|harvest|' r'immutable|virtual-exemplar|find|produce|remove|pad-head|last|' r'replicate|set-fourth|remove-eq|shorten|reversed\\?|' r'map-find-last|3map-as|2unclip-slice|shorter\\?|3map|find-last|' r'head-slice|pop\\*|2map-as|tail-slice\\*|but-last-slice|' r'2map-reduce|iota\\?|collector-for|accumulate|each|selector|' r'append!|new-resizable|cut-slice|each-index|head-slice\\*|' r'2reverse-each|sequence-hashcode|pop|set-nth|\\?nth|' r'|second|join|when-empty|collector|' r'immutable-sequence\\?||all\\?|3append-as|' r'virtual-sequence|subseq\\?|remove-nth!|push-either|new-like|' r'length|last-index|push-if|2all\\?|lengthen|assert-sequence|' r'copy|map-reduce|move|third|first|3each|tail\\?|set-first|' r'prefix|bounds-error|any\\?||trim-slice|exchange|' r'surround|2reduce|cut|change-nth|min-length|set-third|produce-as|' r'push-all|head\\?|delete-slice|rest|sum-lengths|2each|head\\*|' r'infimum|remove!|glue|slice-error|subseq|trim|replace-slice|' r'push|repetition|map-index|trim-head|unclip-last|mismatch)\s' ) builtin_namespaces = ( r'(?:global|\\+@|change|set-namestack|change-global|init-namespaces|' r'on|off|set-global|namespace|set|with-scope|bind|with-variable|' r'inc|dec|counter|initialize|namestack|get|get-global|make-assoc)\s' ) builtin_arrays = ( r'(?:|2array|3array|pair|>array|1array|4array|pair\\?|' r'array|resize-array|array\\?)\s' ) builtin_io = ( r'(?:\\+character\\+|bad-seek-type\\?|readln|each-morsel|stream-seek|' r'read|print|with-output-stream|contents|write1|stream-write1|' r'stream-copy|stream-element-type|with-input-stream|' r'stream-print|stream-read|stream-contents|stream-tell|' r'tell-output|bl|seek-output|bad-seek-type|nl|stream-nl|write|' r'flush|stream-lines|\\+byte\\+|stream-flush|read1|' r'seek-absolute\\?|stream-read1|lines|stream-readln|' r'stream-read-until|each-line|seek-end|with-output-stream\\*|' r'seek-absolute|with-streams|seek-input|seek-relative\\?|' r'input-stream|stream-write|read-partial|seek-end\\?|' r'seek-relative|error-stream|read-until|with-input-stream\\*|' r'with-streams\\*|tell-input|each-block|output-stream|' r'stream-read-partial|each-stream-block|each-stream-line)\s' ) builtin_strings = ( r'(?:resize-string|>string||1string|string|string\\?)\s' ) builtin_vectors = ( r'(?:vector\\?||\\?push|vector|>vector|1vector)\s' ) builtin_continuations = ( r'(?:with-return|restarts|return-continuation|with-datastack|' r'recover|rethrow-restarts||ifcc|set-catchstack|' r'>continuation<|cleanup|ignore-errors|restart\\?|' r'compute-restarts|attempt-all-error|error-thread|continue|' r'|attempt-all-error\\?|condition\\?|' r'|throw-restarts|error|catchstack|continue-with|' r'thread-error-hook|continuation|rethrow|callcc1|' r'error-continuation|callcc0|attempt-all|condition|' r'continuation\\?|restart|return)\s' ) tokens = { 'root': [ # TODO: (( inputs -- outputs )) # TODO: << ... >> # defining words (r'(\s*)(:|::|MACRO:|MEMO:)(\s+)(\S+)', bygroups(Text, Keyword, Text, Name.Function)), (r'(\s*)(M:)(\s+)(\S+)(\s+)(\S+)', bygroups(Text, Keyword, Text, Name.Class, Text, Name.Function)), (r'(\s*)(GENERIC:)(\s+)(\S+)', bygroups(Text, Keyword, Text, Name.Function)), (r'(\s*)(HOOK:|GENERIC#)(\s+)(\S+)(\s+)(\S+)', bygroups(Text, Keyword, Text, Name.Function, Text, Name.Function)), (r'(\()(\s+)', bygroups(Name.Function, Text), 'stackeffect'), (r'\;\s', Keyword), # imports and namespaces (r'(USING:)((?:\s|\\\s)+)', bygroups(Keyword.Namespace, Text), 'import'), (r'(USE:)(\s+)(\S+)', bygroups(Keyword.Namespace, Text, Name.Namespace)), (r'(UNUSE:)(\s+)(\S+)', bygroups(Keyword.Namespace, Text, Name.Namespace)), (r'(QUALIFIED:)(\s+)(\S+)', bygroups(Keyword.Namespace, Text, Name.Namespace)), (r'(QUALIFIED-WITH:)(\s+)(\S+)', bygroups(Keyword.Namespace, Text, Name.Namespace)), (r'(FROM:|EXCLUDE:)(\s+)(\S+)(\s+)(=>)', bygroups(Keyword.Namespace, Text, Name.Namespace, Text, Text)), (r'(IN:)(\s+)(\S+)', bygroups(Keyword.Namespace, Text, Name.Namespace)), (r'(?:ALIAS|DEFER|FORGET|POSTPONE):', Keyword.Namespace), # tuples and classes (r'(TUPLE:)(\s+)(\S+)(\s+<\s+)(\S+)', bygroups(Keyword, Text, Name.Class, Text, Name.Class), 'slots'), (r'(TUPLE:)(\s+)(\S+)', bygroups(Keyword, Text, Name.Class), 'slots'), (r'(UNION:)(\s+)(\S+)', bygroups(Keyword, Text, Name.Class)), (r'(INTERSECTION:)(\s+)(\S+)', bygroups(Keyword, Text, Name.Class)), (r'(PREDICATE:)(\s+)(\S+)(\s+<\s+)(\S+)', bygroups(Keyword, Text, Name.Class, Text, Name.Class)), (r'(C:)(\s+)(\S+)(\s+)(\S+)', bygroups(Keyword, Text, Name.Function, Text, Name.Class)), (r'INSTANCE:', Keyword), (r'SLOT:', Keyword), (r'MIXIN:', Keyword), (r'(?:SINGLETON|SINGLETONS):', Keyword), # other syntax (r'CONSTANT:', Keyword), (r'(?:SYMBOL|SYMBOLS):', Keyword), (r'ERROR:', Keyword), (r'SYNTAX:', Keyword), (r'(HELP:)(\s+)(\S+)', bygroups(Keyword, Text, Name.Function)), (r'(MAIN:)(\s+)(\S+)', bygroups(Keyword.Namespace, Text, Name.Function)), (r'(?:ALIEN|TYPEDEF|FUNCTION|STRUCT):', Keyword), # vocab.private # TODO: words inside vocab.private should have red names? (r'(?:)', Keyword.Namespace), # strings (r'"""\s+(?:.|\n)*?\s+"""', String), (r'"(?:\\\\|\\"|[^"])*"', String), (r'CHAR:\s+(\\[\\abfnrstv]*|\S)\s', String.Char), # comments (r'\!\s+.*$', Comment), (r'#\!\s+.*$', Comment), # boolean constants (r'(t|f)\s', Name.Constant), # numbers (r'-?\d+\.\d+\s', Number.Float), (r'-?\d+\s', Number.Integer), (r'HEX:\s+[a-fA-F\d]+\s', Number.Hex), (r'BIN:\s+[01]+\s', Number.Integer), (r'OCT:\s+[0-7]+\s', Number.Oct), # operators (r'[-+/*=<>^]\s', Operator), # keywords (r'(?:deprecated|final|foldable|flushable|inline|recursive)\s', Keyword), # builtins (builtin_kernel, Name.Builtin), (builtin_assocs, Name.Builtin), (builtin_combinators, Name.Builtin), (builtin_math, Name.Builtin), (builtin_sequences, Name.Builtin), (builtin_namespaces, Name.Builtin), (builtin_arrays, Name.Builtin), (builtin_io, Name.Builtin), (builtin_strings, Name.Builtin), (builtin_vectors, Name.Builtin), (builtin_continuations, Name.Builtin), # whitespaces - usually not relevant (r'\s+', Text), # everything else is text (r'\S+', Text), ], 'stackeffect': [ (r'\s*\(', Name.Function, 'stackeffect'), (r'\)', Name.Function, '#pop'), (r'\-\-', Name.Function), (r'\s+', Text), (r'\S+', Name.Variable), ], 'slots': [ (r'\s+', Text), (r';\s', Keyword, '#pop'), (r'\S+', Name.Variable), ], 'import': [ (r';', Keyword, '#pop'), (r'\S+', Name.Namespace), (r'\s+', Text), ], } class FancyLexer(RegexLexer): """ Pygments Lexer For `Fancy `_. Fancy is a self-hosted, pure object-oriented, dynamic, class-based, concurrent general-purpose programming language running on Rubinius, the Ruby VM. *New in Pygments 1.5.* """ name = 'Fancy' filenames = ['*.fy', '*.fancypack'] aliases = ['fancy', 'fy'] mimetypes = ['text/x-fancysrc'] tokens = { # copied from PerlLexer: 'balanced-regex': [ (r'/(\\\\|\\/|[^/])*/[egimosx]*', String.Regex, '#pop'), (r'!(\\\\|\\!|[^!])*![egimosx]*', String.Regex, '#pop'), (r'\\(\\\\|[^\\])*\\[egimosx]*', String.Regex, '#pop'), (r'{(\\\\|\\}|[^}])*}[egimosx]*', String.Regex, '#pop'), (r'<(\\\\|\\>|[^>])*>[egimosx]*', String.Regex, '#pop'), (r'\[(\\\\|\\\]|[^\]])*\][egimosx]*', String.Regex, '#pop'), (r'\((\\\\|\\\)|[^\)])*\)[egimosx]*', String.Regex, '#pop'), (r'@(\\\\|\\\@|[^\@])*@[egimosx]*', String.Regex, '#pop'), (r'%(\\\\|\\\%|[^\%])*%[egimosx]*', String.Regex, '#pop'), (r'\$(\\\\|\\\$|[^\$])*\$[egimosx]*', String.Regex, '#pop'), ], 'root': [ (r'\s+', Text), # balanced delimiters (copied from PerlLexer): (r's{(\\\\|\\}|[^}])*}\s*', String.Regex, 'balanced-regex'), (r's<(\\\\|\\>|[^>])*>\s*', String.Regex, 'balanced-regex'), (r's\[(\\\\|\\\]|[^\]])*\]\s*', String.Regex, 'balanced-regex'), (r's\((\\\\|\\\)|[^\)])*\)\s*', String.Regex, 'balanced-regex'), (r'm?/(\\\\|\\/|[^/\n])*/[gcimosx]*', String.Regex), (r'm(?=[/!\\{<\[\(@%\$])', String.Regex, 'balanced-regex'), # Comments (r'#(.*?)\n', Comment.Single), # Symbols (r'\'([^\'\s\[\]\(\)\{\}]+|\[\])', String.Symbol), # Multi-line DoubleQuotedString (r'"""(\\\\|\\"|[^"])*"""', String), # DoubleQuotedString (r'"(\\\\|\\"|[^"])*"', String), # keywords (r'(def|class|try|catch|finally|retry|return|return_local|match|' r'case|->|=>)\b', Keyword), # constants (r'(self|super|nil|false|true)\b', Name.Constant), (r'[(){};,/?\|:\\]', Punctuation), # names (r'(Object|Array|Hash|Directory|File|Class|String|Number|' r'Enumerable|FancyEnumerable|Block|TrueClass|NilClass|' r'FalseClass|Tuple|Symbol|Stack|Set|FancySpec|Method|Package|' r'Range)\b', Name.Builtin), # functions (r'[a-zA-Z]([a-zA-Z0-9_]|[-+?!=*/^><%])*:', Name.Function), # operators, must be below functions (r'[-+*/~,<>=&!?%^\[\]\.$]+', Operator), ('[A-Z][a-zA-Z0-9_]*', Name.Constant), ('@[a-zA-Z_][a-zA-Z0-9_]*', Name.Variable.Instance), ('@@[a-zA-Z_][a-zA-Z0-9_]*', Name.Variable.Class), ('@@?', Operator), ('[a-zA-Z_][a-zA-Z0-9_]*', Name), # numbers - / checks are necessary to avoid mismarking regexes, # see comment in RubyLexer (r'(0[oO]?[0-7]+(?:_[0-7]+)*)(\s*)([/?])?', bygroups(Number.Oct, Text, Operator)), (r'(0[xX][0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*)(\s*)([/?])?', bygroups(Number.Hex, Text, Operator)), (r'(0[bB][01]+(?:_[01]+)*)(\s*)([/?])?', bygroups(Number.Bin, Text, Operator)), (r'([\d]+(?:_\d+)*)(\s*)([/?])?', bygroups(Number.Integer, Text, Operator)), (r'\d+([eE][+-]?[0-9]+)|\d+\.\d+([eE][+-]?[0-9]+)?', Number.Float), (r'\d+', Number.Integer) ] } class DgLexer(RegexLexer): """ Lexer for `dg `_, a functional and object-oriented programming language running on the CPython 3 VM. *New in Pygments 1.6.* """ name = 'dg' aliases = ['dg'] filenames = ['*.dg'] mimetypes = ['text/x-dg'] tokens = { 'root': [ # Whitespace: (r'\s+', Text), (r'#.*?$', Comment.Single), # Lexemes: # Numbers (r'0[bB][01]+', Number.Bin), (r'0[oO][0-7]+', Number.Oct), (r'0[xX][\da-fA-F]+', Number.Hex), (r'[+-]?\d+\.\d+([eE][+-]?\d+)?[jJ]?', Number.Float), (r'[+-]?\d+[eE][+-]?\d+[jJ]?', Number.Float), (r'[+-]?\d+[jJ]?', Number.Integer), # Character/String Literals (r"[br]*'''", String, combined('stringescape', 'tsqs', 'string')), (r'[br]*"""', String, combined('stringescape', 'tdqs', 'string')), (r"[br]*'", String, combined('stringescape', 'sqs', 'string')), (r'[br]*"', String, combined('stringescape', 'dqs', 'string')), # Operators (r"`\w+'*`", Operator), # Infix links # Reserved infix links (r'\b(or|and|if|else|where|is|in)\b', Operator.Word), (r'[!$%&*+\-./:<-@\\^|~;,]+', Operator), # Identifiers # Python 3 types (r"(?`_ source code. *New in Pygments 1.7.* """ name = 'Perl6' aliases = ['perl6', 'pl6'] filenames = ['*.pl', '*.pm', '*.nqp', '*.p6', '*.6pl', '*.p6l', '*.pl6', '*.6pm', '*.p6m', '*.pm6'] mimetypes = ['text/x-perl6', 'application/x-perl6'] flags = re.MULTILINE | re.DOTALL | re.UNICODE PERL6_IDENTIFIER_RANGE = "['a-zA-Z0-9_:-]" PERL6_KEYWORDS = ( 'BEGIN', 'CATCH', 'CHECK', 'CONTROL', 'END', 'ENTER', 'FIRST', 'INIT', 'KEEP', 'LAST', 'LEAVE', 'NEXT', 'POST', 'PRE', 'START', 'TEMP', 'UNDO', 'as', 'assoc', 'async', 'augment', 'binary', 'break', 'but', 'cached', 'category', 'class', 'constant', 'contend', 'continue', 'copy', 'deep', 'default', 'defequiv', 'defer', 'die', 'do', 'else', 'elsif', 'enum', 'equiv', 'exit', 'export', 'fail', 'fatal', 'for', 'gather', 'given', 'goto', 'grammar', 'handles', 'has', 'if', 'inline', 'irs', 'is', 'last', 'leave', 'let', 'lift', 'loop', 'looser', 'macro', 'make', 'maybe', 'method', 'module', 'multi', 'my', 'next', 'of', 'ofs', 'only', 'oo', 'ors', 'our', 'package', 'parsed', 'prec', 'proto', 'readonly', 'redo', 'ref', 'regex', 'reparsed', 'repeat', 'require', 'required', 'return', 'returns', 'role', 'rule', 'rw', 'self', 'slang', 'state', 'sub', 'submethod', 'subset', 'supersede', 'take', 'temp', 'tighter', 'token', 'trusts', 'try', 'unary', 'unless', 'until', 'use', 'warn', 'when', 'where', 'while', 'will', ) PERL6_BUILTINS = ( 'ACCEPTS', 'HOW', 'REJECTS', 'VAR', 'WHAT', 'WHENCE', 'WHERE', 'WHICH', 'WHO', 'abs', 'acos', 'acosec', 'acosech', 'acosh', 'acotan', 'acotanh', 'all', 'any', 'approx', 'arity', 'asec', 'asech', 'asin', 'asinh' 'assuming', 'atan', 'atan2', 'atanh', 'attr', 'bless', 'body', 'by' 'bytes', 'caller', 'callsame', 'callwith', 'can', 'capitalize', 'cat', 'ceiling', 'chars', 'chmod', 'chomp', 'chop', 'chr', 'chroot', 'circumfix', 'cis', 'classify', 'clone', 'close', 'cmp_ok', 'codes', 'comb', 'connect', 'contains', 'context', 'cos', 'cosec', 'cosech', 'cosh', 'cotan', 'cotanh', 'count', 'defined', 'delete', 'diag', 'dies_ok', 'does', 'e', 'each', 'eager', 'elems', 'end', 'eof', 'eval', 'eval_dies_ok', 'eval_elsewhere', 'eval_lives_ok', 'evalfile', 'exists', 'exp', 'first', 'flip', 'floor', 'flunk', 'flush', 'fmt', 'force_todo', 'fork', 'from', 'getc', 'gethost', 'getlogin', 'getpeername', 'getpw', 'gmtime', 'graphs', 'grep', 'hints', 'hyper', 'im', 'index', 'infix', 'invert', 'is_approx', 'is_deeply', 'isa', 'isa_ok', 'isnt', 'iterator', 'join', 'key', 'keys', 'kill', 'kv', 'lastcall', 'lazy', 'lc', 'lcfirst', 'like', 'lines', 'link', 'lives_ok', 'localtime', 'log', 'log10', 'map', 'max', 'min', 'minmax', 'name', 'new', 'nextsame', 'nextwith', 'nfc', 'nfd', 'nfkc', 'nfkd', 'nok_error', 'nonce', 'none', 'normalize', 'not', 'nothing', 'ok', 'once', 'one', 'open', 'opendir', 'operator', 'ord', 'p5chomp', 'p5chop', 'pack', 'pair', 'pairs', 'pass', 'perl', 'pi', 'pick', 'plan', 'plan_ok', 'polar', 'pop', 'pos', 'postcircumfix', 'postfix', 'pred', 'prefix', 'print', 'printf', 'push', 'quasi', 'quotemeta', 'rand', 're', 'read', 'readdir', 'readline', 'reduce', 'reverse', 'rewind', 'rewinddir', 'rindex', 'roots', 'round', 'roundrobin', 'run', 'runinstead', 'sameaccent', 'samecase', 'say', 'sec', 'sech', 'sech', 'seek', 'shape', 'shift', 'sign', 'signature', 'sin', 'sinh', 'skip', 'skip_rest', 'sleep', 'slurp', 'sort', 'splice', 'split', 'sprintf', 'sqrt', 'srand', 'strand', 'subst', 'substr', 'succ', 'sum', 'symlink', 'tan', 'tanh', 'throws_ok', 'time', 'times', 'to', 'todo', 'trim', 'trim_end', 'trim_start', 'true', 'truncate', 'uc', 'ucfirst', 'undef', 'undefine', 'uniq', 'unlike', 'unlink', 'unpack', 'unpolar', 'unshift', 'unwrap', 'use_ok', 'value', 'values', 'vec', 'version_lt', 'void', 'wait', 'want', 'wrap', 'write', 'zip', ) PERL6_BUILTIN_CLASSES = ( 'Abstraction', 'Any', 'AnyChar', 'Array', 'Associative', 'Bag', 'Bit', 'Blob', 'Block', 'Bool', 'Buf', 'Byte', 'Callable', 'Capture', 'Char', 'Class', 'Code', 'Codepoint', 'Comparator', 'Complex', 'Decreasing', 'Exception', 'Failure', 'False', 'Grammar', 'Grapheme', 'Hash', 'IO', 'Increasing', 'Int', 'Junction', 'KeyBag', 'KeyExtractor', 'KeyHash', 'KeySet', 'KitchenSink', 'List', 'Macro', 'Mapping', 'Match', 'Matcher', 'Method', 'Module', 'Num', 'Object', 'Ordered', 'Ordering', 'OrderingPair', 'Package', 'Pair', 'Positional', 'Proxy', 'Range', 'Rat', 'Regex', 'Role', 'Routine', 'Scalar', 'Seq', 'Set', 'Signature', 'Str', 'StrLen', 'StrPos', 'Sub', 'Submethod', 'True', 'UInt', 'Undef', 'Version', 'Void', 'Whatever', 'bit', 'bool', 'buf', 'buf1', 'buf16', 'buf2', 'buf32', 'buf4', 'buf64', 'buf8', 'complex', 'int', 'int1', 'int16', 'int2', 'int32', 'int4', 'int64', 'int8', 'num', 'rat', 'rat1', 'rat16', 'rat2', 'rat32', 'rat4', 'rat64', 'rat8', 'uint', 'uint1', 'uint16', 'uint2', 'uint32', 'uint4', 'uint64', 'uint8', 'utf16', 'utf32', 'utf8', ) PERL6_OPERATORS = ( 'X', 'Z', 'after', 'also', 'and', 'andthen', 'before', 'cmp', 'div', 'eq', 'eqv', 'extra', 'ff', 'fff', 'ge', 'gt', 'le', 'leg', 'lt', 'm', 'mm', 'mod', 'ne', 'or', 'orelse', 'rx', 's', 'tr', 'x', 'xor', 'xx', '++', '--', '**', '!', '+', '-', '~', '?', '|', '||', '+^', '~^', '?^', '^', '*', '/', '%', '%%', '+&', '+<', '+>', '~&', '~<', '~>', '?&', 'gcd', 'lcm', '+', '-', '+|', '+^', '~|', '~^', '?|', '?^', '~', '&', '^', 'but', 'does', '<=>', '..', '..^', '^..', '^..^', '!=', '==', '<', '<=', '>', '>=', '~~', '===', '!eqv', '&&', '||', '^^', '//', 'min', 'max', '??', '!!', 'ff', 'fff', 'so', 'not', '<==', '==>', '<<==', '==>>', ) # Perl 6 has a *lot* of possible bracketing characters # this list was lifted from STD.pm6 (https://github.com/perl6/std) PERL6_BRACKETS = { u'\u0028' : u'\u0029', u'\u003c' : u'\u003e', u'\u005b' : u'\u005d', u'\u007b' : u'\u007d', u'\u00ab' : u'\u00bb', u'\u0f3a' : u'\u0f3b', u'\u0f3c' : u'\u0f3d', u'\u169b' : u'\u169c', u'\u2018' : u'\u2019', u'\u201a' : u'\u2019', u'\u201b' : u'\u2019', u'\u201c' : u'\u201d', u'\u201e' : u'\u201d', u'\u201f' : u'\u201d', u'\u2039' : u'\u203a', u'\u2045' : u'\u2046', u'\u207d' : u'\u207e', u'\u208d' : u'\u208e', u'\u2208' : u'\u220b', u'\u2209' : u'\u220c', u'\u220a' : u'\u220d', u'\u2215' : u'\u29f5', u'\u223c' : u'\u223d', u'\u2243' : u'\u22cd', u'\u2252' : u'\u2253', u'\u2254' : u'\u2255', u'\u2264' : u'\u2265', u'\u2266' : u'\u2267', u'\u2268' : u'\u2269', u'\u226a' : u'\u226b', u'\u226e' : u'\u226f', u'\u2270' : u'\u2271', u'\u2272' : u'\u2273', u'\u2274' : u'\u2275', u'\u2276' : u'\u2277', u'\u2278' : u'\u2279', u'\u227a' : u'\u227b', u'\u227c' : u'\u227d', u'\u227e' : u'\u227f', u'\u2280' : u'\u2281', u'\u2282' : u'\u2283', u'\u2284' : u'\u2285', u'\u2286' : u'\u2287', u'\u2288' : u'\u2289', u'\u228a' : u'\u228b', u'\u228f' : u'\u2290', u'\u2291' : u'\u2292', u'\u2298' : u'\u29b8', u'\u22a2' : u'\u22a3', u'\u22a6' : u'\u2ade', u'\u22a8' : u'\u2ae4', u'\u22a9' : u'\u2ae3', u'\u22ab' : u'\u2ae5', u'\u22b0' : u'\u22b1', u'\u22b2' : u'\u22b3', u'\u22b4' : u'\u22b5', u'\u22b6' : u'\u22b7', u'\u22c9' : u'\u22ca', u'\u22cb' : u'\u22cc', u'\u22d0' : u'\u22d1', u'\u22d6' : u'\u22d7', u'\u22d8' : u'\u22d9', u'\u22da' : u'\u22db', u'\u22dc' : u'\u22dd', u'\u22de' : u'\u22df', u'\u22e0' : u'\u22e1', u'\u22e2' : u'\u22e3', u'\u22e4' : u'\u22e5', u'\u22e6' : u'\u22e7', u'\u22e8' : u'\u22e9', u'\u22ea' : u'\u22eb', u'\u22ec' : u'\u22ed', u'\u22f0' : u'\u22f1', u'\u22f2' : u'\u22fa', u'\u22f3' : u'\u22fb', u'\u22f4' : u'\u22fc', u'\u22f6' : u'\u22fd', u'\u22f7' : u'\u22fe', u'\u2308' : u'\u2309', u'\u230a' : u'\u230b', u'\u2329' : u'\u232a', u'\u23b4' : u'\u23b5', u'\u2768' : u'\u2769', u'\u276a' : u'\u276b', u'\u276c' : u'\u276d', u'\u276e' : u'\u276f', u'\u2770' : u'\u2771', u'\u2772' : u'\u2773', u'\u2774' : u'\u2775', u'\u27c3' : u'\u27c4', u'\u27c5' : u'\u27c6', u'\u27d5' : u'\u27d6', u'\u27dd' : u'\u27de', u'\u27e2' : u'\u27e3', u'\u27e4' : u'\u27e5', u'\u27e6' : u'\u27e7', u'\u27e8' : u'\u27e9', u'\u27ea' : u'\u27eb', u'\u2983' : u'\u2984', u'\u2985' : u'\u2986', u'\u2987' : u'\u2988', u'\u2989' : u'\u298a', u'\u298b' : u'\u298c', u'\u298d' : u'\u298e', u'\u298f' : u'\u2990', u'\u2991' : u'\u2992', u'\u2993' : u'\u2994', u'\u2995' : u'\u2996', u'\u2997' : u'\u2998', u'\u29c0' : u'\u29c1', u'\u29c4' : u'\u29c5', u'\u29cf' : u'\u29d0', u'\u29d1' : u'\u29d2', u'\u29d4' : u'\u29d5', u'\u29d8' : u'\u29d9', u'\u29da' : u'\u29db', u'\u29f8' : u'\u29f9', u'\u29fc' : u'\u29fd', u'\u2a2b' : u'\u2a2c', u'\u2a2d' : u'\u2a2e', u'\u2a34' : u'\u2a35', u'\u2a3c' : u'\u2a3d', u'\u2a64' : u'\u2a65', u'\u2a79' : u'\u2a7a', u'\u2a7d' : u'\u2a7e', u'\u2a7f' : u'\u2a80', u'\u2a81' : u'\u2a82', u'\u2a83' : u'\u2a84', u'\u2a8b' : u'\u2a8c', u'\u2a91' : u'\u2a92', u'\u2a93' : u'\u2a94', u'\u2a95' : u'\u2a96', u'\u2a97' : u'\u2a98', u'\u2a99' : u'\u2a9a', u'\u2a9b' : u'\u2a9c', u'\u2aa1' : u'\u2aa2', u'\u2aa6' : u'\u2aa7', u'\u2aa8' : u'\u2aa9', u'\u2aaa' : u'\u2aab', u'\u2aac' : u'\u2aad', u'\u2aaf' : u'\u2ab0', u'\u2ab3' : u'\u2ab4', u'\u2abb' : u'\u2abc', u'\u2abd' : u'\u2abe', u'\u2abf' : u'\u2ac0', u'\u2ac1' : u'\u2ac2', u'\u2ac3' : u'\u2ac4', u'\u2ac5' : u'\u2ac6', u'\u2acd' : u'\u2ace', u'\u2acf' : u'\u2ad0', u'\u2ad1' : u'\u2ad2', u'\u2ad3' : u'\u2ad4', u'\u2ad5' : u'\u2ad6', u'\u2aec' : u'\u2aed', u'\u2af7' : u'\u2af8', u'\u2af9' : u'\u2afa', u'\u2e02' : u'\u2e03', u'\u2e04' : u'\u2e05', u'\u2e09' : u'\u2e0a', u'\u2e0c' : u'\u2e0d', u'\u2e1c' : u'\u2e1d', u'\u2e20' : u'\u2e21', u'\u3008' : u'\u3009', u'\u300a' : u'\u300b', u'\u300c' : u'\u300d', u'\u300e' : u'\u300f', u'\u3010' : u'\u3011', u'\u3014' : u'\u3015', u'\u3016' : u'\u3017', u'\u3018' : u'\u3019', u'\u301a' : u'\u301b', u'\u301d' : u'\u301e', u'\ufd3e' : u'\ufd3f', u'\ufe17' : u'\ufe18', u'\ufe35' : u'\ufe36', u'\ufe37' : u'\ufe38', u'\ufe39' : u'\ufe3a', u'\ufe3b' : u'\ufe3c', u'\ufe3d' : u'\ufe3e', u'\ufe3f' : u'\ufe40', u'\ufe41' : u'\ufe42', u'\ufe43' : u'\ufe44', u'\ufe47' : u'\ufe48', u'\ufe59' : u'\ufe5a', u'\ufe5b' : u'\ufe5c', u'\ufe5d' : u'\ufe5e', u'\uff08' : u'\uff09', u'\uff1c' : u'\uff1e', u'\uff3b' : u'\uff3d', u'\uff5b' : u'\uff5d', u'\uff5f' : u'\uff60', u'\uff62' : u'\uff63', } def _build_word_match(words, boundary_regex_fragment = None, prefix = '', suffix = ''): if boundary_regex_fragment is None: return r'\b(' + prefix + r'|'.join([ re.escape(x) for x in words]) + suffix + r')\b' else: return r'(? 0: next_open_pos = text.find(opening_chars, search_pos + n_chars) next_close_pos = text.find(closing_chars, search_pos + n_chars) if next_close_pos == -1: next_close_pos = len(text) nesting_level = 0 elif next_open_pos != -1 and next_open_pos < next_close_pos: nesting_level += 1 search_pos = next_open_pos else: # next_close_pos < next_open_pos nesting_level -= 1 search_pos = next_close_pos end_pos = next_close_pos if adverbs is not None and re.search(r':to\b', adverbs): heredoc_terminator = text[match.start('delimiter') + n_chars : end_pos] end_heredoc = re.search(r'^\s*' + re.escape(heredoc_terminator) + r'\s*$', text[ match.end('delimiter') : ], re.MULTILINE) if end_heredoc: end_pos = match.end('delimiter') + end_heredoc.end() else: end_pos = len(text) yield match.start(), token_class, text[match.start() : end_pos + n_chars] context.pos = end_pos + n_chars return callback def opening_brace_callback(lexer, match, context): stack = context.stack yield match.start(), Text, context.text[match.start() : match.end()] context.pos = match.end() # if we encounter an opening brace and we're one level # below a token state, it means we need to increment # the nesting level for braces so we know later when # we should return to the token rules. if len(stack) > 2 and stack[-2] == 'token': context.perl6_token_nesting_level += 1 def closing_brace_callback(lexer, match, context): stack = context.stack yield match.start(), Text, context.text[match.start() : match.end()] context.pos = match.end() # if we encounter a free closing brace and we're one level # below a token state, it means we need to check the nesting # level to see if we need to return to the token state. if len(stack) > 2 and stack[-2] == 'token': context.perl6_token_nesting_level -= 1 if context.perl6_token_nesting_level == 0: stack.pop() def embedded_perl6_callback(lexer, match, context): context.perl6_token_nesting_level = 1 yield match.start(), Text, context.text[match.start() : match.end()] context.pos = match.end() context.stack.append('root') # If you're modifying these rules, be careful if you need to process '{' or '}' characters. # We have special logic for processing these characters (due to the fact that you can nest # Perl 6 code in regex blocks), so if you need to process one of them, make sure you also # process the corresponding one! tokens = { 'common' : [ (r'#[`|=](?P(?P[' + ''.join(PERL6_BRACKETS.keys()) + r'])(?P=first_char)*)', brackets_callback(Comment.Multiline)), (r'#[^\n]*$', Comment.Singleline), (r'^(\s*)=begin\s+(\w+)\b.*?^\1=end\s+\2', Comment.Multiline), (r'^(\s*)=for.*?\n\s*?\n', Comment.Multiline), (r'^=.*?\n\s*?\n', Comment.Multiline), (r'(regex|token|rule)(\s*' + PERL6_IDENTIFIER_RANGE + '+:sym)', bygroups(Keyword, Name), 'token-sym-brackets'), (r'(regex|token|rule)(?!' + PERL6_IDENTIFIER_RANGE + ')(\s*' + PERL6_IDENTIFIER_RANGE + '+)?', bygroups(Keyword, Name), 'pre-token'), # deal with a special case in the Perl 6 grammar (role q { ... }) (r'(role)(\s+)(q)(\s*)', bygroups(Keyword, Text, Name, Text)), (_build_word_match(PERL6_KEYWORDS, PERL6_IDENTIFIER_RANGE), Keyword), (_build_word_match(PERL6_BUILTIN_CLASSES, PERL6_IDENTIFIER_RANGE, suffix = '(?::[UD])?'), Name.Builtin), (_build_word_match(PERL6_BUILTINS, PERL6_IDENTIFIER_RANGE), Name.Builtin), # copied from PerlLexer (r'[$@%&][.^:?=!~]?' + PERL6_IDENTIFIER_RANGE + u'+(?:<<.*?>>|<.*?>|«.*?»)*', Name.Variable), (r'\$[!/](?:<<.*?>>|<.*?>|«.*?»)*', Name.Variable.Global), (r'::\?\w+', Name.Variable.Global), (r'[$@%&]\*' + PERL6_IDENTIFIER_RANGE + u'+(?:<<.*?>>|<.*?>|«.*?»)*', Name.Variable.Global), (r'\$(?:<.*?>)+', Name.Variable), (r'(?:q|qq|Q)[a-zA-Z]?\s*(?P:[\w\s:]+)?\s*(?P(?P[^0-9a-zA-Z:\s])(?P=first_char)*)', brackets_callback(String)), # copied from PerlLexer (r'0_?[0-7]+(_[0-7]+)*', Number.Oct), (r'0x[0-9A-Fa-f]+(_[0-9A-Fa-f]+)*', Number.Hex), (r'0b[01]+(_[01]+)*', Number.Bin), (r'(?i)(\d*(_\d*)*\.\d+(_\d*)*|\d+(_\d*)*\.\d+(_\d*)*)(e[+-]?\d+)?', Number.Float), (r'(?i)\d+(_\d*)*e[+-]?\d+(_\d*)*', Number.Float), (r'\d+(_\d+)*', Number.Integer), (r'(?<=~~)\s*/(?:\\\\|\\/|.)*?/', String.Regex), (r'(?<=[=(,])\s*/(?:\\\\|\\/|.)*?/', String.Regex), (r'm\w+(?=\()', Name), (r'(?:m|ms|rx)\s*(?P:[\w\s:]+)?\s*(?P(?P[^0-9a-zA-Z:\s])(?P=first_char)*)', brackets_callback(String.Regex)), (r'(?:s|ss|tr)\s*(?::[\w\s:]+)?\s*/(?:\\\\|\\/|.)*?/(?:\\\\|\\/|.)*?/', String.Regex), (r'<[^\s=].*?\S>', String), (_build_word_match(PERL6_OPERATORS), Operator), (r'[0-9a-zA-Z_]' + PERL6_IDENTIFIER_RANGE + '*', Name), (r"'(\\\\|\\[^\\]|[^'\\])*'", String), (r'"(\\\\|\\[^\\]|[^"\\])*"', String), ], 'root' : [ include('common'), (r'\{', opening_brace_callback), (r'\}', closing_brace_callback), (r'.+?', Text), ], 'pre-token' : [ include('common'), (r'\{', Text, ('#pop', 'token')), (r'.+?', Text), ], 'token-sym-brackets' : [ (r'(?P(?P[' + ''.join(PERL6_BRACKETS.keys()) + '])(?P=first_char)*)', brackets_callback(Name), ('#pop', 'pre-token')), (r'', Name, ('#pop', 'pre-token')), ], 'token': [ (r'}', Text, '#pop'), (r'(?<=:)(?:my|our|state|constant|temp|let).*?;', using(this)), # make sure that quotes in character classes aren't treated as strings (r'<(?:[-!?+.]\s*)?\[.*?\]>', String.Regex), # make sure that '#' characters in quotes aren't treated as comments (r"(?