|
""" |
|
pygments.lexers.ml |
|
~~~~~~~~~~~~~~~~~~ |
|
|
|
Lexers for ML family languages. |
|
|
|
:copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS. |
|
:license: BSD, see LICENSE for details. |
|
""" |
|
|
|
import re |
|
|
|
from pygments.lexer import RegexLexer, include, bygroups, default, words |
|
from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ |
|
Number, Punctuation, Error |
|
|
|
__all__ = ['SMLLexer', 'OcamlLexer', 'OpaLexer', 'ReasonLexer', 'FStarLexer'] |
|
|
|
|
|
class SMLLexer(RegexLexer): |
|
""" |
|
For the Standard ML language. |
|
""" |
|
|
|
name = 'Standard ML' |
|
aliases = ['sml'] |
|
filenames = ['*.sml', '*.sig', '*.fun'] |
|
mimetypes = ['text/x-standardml', 'application/x-standardml'] |
|
url = 'https://en.wikipedia.org/wiki/Standard_ML' |
|
version_added = '1.5' |
|
|
|
alphanumid_reserved = { |
|
|
|
'abstype', 'and', 'andalso', 'as', 'case', 'datatype', 'do', 'else', |
|
'end', 'exception', 'fn', 'fun', 'handle', 'if', 'in', 'infix', |
|
'infixr', 'let', 'local', 'nonfix', 'of', 'op', 'open', 'orelse', |
|
'raise', 'rec', 'then', 'type', 'val', 'with', 'withtype', 'while', |
|
|
|
'eqtype', 'functor', 'include', 'sharing', 'sig', 'signature', |
|
'struct', 'structure', 'where', |
|
} |
|
|
|
symbolicid_reserved = { |
|
|
|
':', r'\|', '=', '=>', '->', '#', |
|
|
|
':>', |
|
} |
|
|
|
nonid_reserved = {'(', ')', '[', ']', '{', '}', ',', ';', '...', '_'} |
|
|
|
alphanumid_re = r"[a-zA-Z][\w']*" |
|
symbolicid_re = r"[!%&$#+\-/:<=>?@\\~`^|*]+" |
|
|
|
|
|
|
|
|
|
|
|
|
|
def stringy(whatkind): |
|
return [ |
|
(r'[^"\\]', whatkind), |
|
(r'\\[\\"abtnvfr]', String.Escape), |
|
|
|
|
|
(r'\\\^[\x40-\x5e]', String.Escape), |
|
|
|
(r'\\[0-9]{3}', String.Escape), |
|
(r'\\u[0-9a-fA-F]{4}', String.Escape), |
|
(r'\\\s+\\', String.Interpol), |
|
(r'"', whatkind, '#pop'), |
|
] |
|
|
|
|
|
def long_id_callback(self, match): |
|
if match.group(1) in self.alphanumid_reserved: |
|
token = Error |
|
else: |
|
token = Name.Namespace |
|
yield match.start(1), token, match.group(1) |
|
yield match.start(2), Punctuation, match.group(2) |
|
|
|
def end_id_callback(self, match): |
|
if match.group(1) in self.alphanumid_reserved: |
|
token = Error |
|
elif match.group(1) in self.symbolicid_reserved: |
|
token = Error |
|
else: |
|
token = Name |
|
yield match.start(1), token, match.group(1) |
|
|
|
def id_callback(self, match): |
|
str = match.group(1) |
|
if str in self.alphanumid_reserved: |
|
token = Keyword.Reserved |
|
elif str in self.symbolicid_reserved: |
|
token = Punctuation |
|
else: |
|
token = Name |
|
yield match.start(1), token, str |
|
|
|
tokens = { |
|
|
|
'whitespace': [ |
|
(r'\s+', Text), |
|
(r'\(\*', Comment.Multiline, 'comment'), |
|
], |
|
|
|
'delimiters': [ |
|
|
|
|
|
|
|
|
|
|
|
(r'\(|\[|\{', Punctuation, 'main'), |
|
(r'\)|\]|\}', Punctuation, '#pop'), |
|
(r'\b(let|if|local)\b(?!\')', Keyword.Reserved, ('main', 'main')), |
|
(r'\b(struct|sig|while)\b(?!\')', Keyword.Reserved, 'main'), |
|
(r'\b(do|else|end|in|then)\b(?!\')', Keyword.Reserved, '#pop'), |
|
], |
|
|
|
'core': [ |
|
|
|
(r'({})'.format('|'.join(re.escape(z) for z in nonid_reserved)), |
|
Punctuation), |
|
|
|
|
|
(r'#"', String.Char, 'char'), |
|
(r'"', String.Double, 'string'), |
|
(r'~?0x[0-9a-fA-F]+', Number.Hex), |
|
(r'0wx[0-9a-fA-F]+', Number.Hex), |
|
(r'0w\d+', Number.Integer), |
|
(r'~?\d+\.\d+[eE]~?\d+', Number.Float), |
|
(r'~?\d+\.\d+', Number.Float), |
|
(r'~?\d+[eE]~?\d+', Number.Float), |
|
(r'~?\d+', Number.Integer), |
|
|
|
|
|
(r'#\s*[1-9][0-9]*', Name.Label), |
|
(rf'#\s*({alphanumid_re})', Name.Label), |
|
(rf'#\s+({symbolicid_re})', Name.Label), |
|
|
|
(r'\b(datatype|abstype)\b(?!\')', Keyword.Reserved, 'dname'), |
|
(r'\b(exception)\b(?!\')', Keyword.Reserved, 'ename'), |
|
(r'\b(functor|include|open|signature|structure)\b(?!\')', |
|
Keyword.Reserved, 'sname'), |
|
(r'\b(type|eqtype)\b(?!\')', Keyword.Reserved, 'tname'), |
|
|
|
|
|
(r'\'[\w\']*', Name.Decorator), |
|
(rf'({alphanumid_re})(\.)', long_id_callback, "dotted"), |
|
(rf'({alphanumid_re})', id_callback), |
|
(rf'({symbolicid_re})', id_callback), |
|
], |
|
'dotted': [ |
|
(rf'({alphanumid_re})(\.)', long_id_callback), |
|
(rf'({alphanumid_re})', end_id_callback, "#pop"), |
|
(rf'({symbolicid_re})', end_id_callback, "#pop"), |
|
(r'\s+', Error), |
|
(r'\S+', Error), |
|
], |
|
|
|
|
|
|
|
'root': [ |
|
default('main') |
|
], |
|
|
|
|
|
|
|
'main': [ |
|
include('whitespace'), |
|
|
|
|
|
(r'\b(val|and)\b(?!\')', Keyword.Reserved, 'vname'), |
|
(r'\b(fun)\b(?!\')', Keyword.Reserved, |
|
('#pop', 'main-fun', 'fname')), |
|
|
|
include('delimiters'), |
|
include('core'), |
|
(r'\S+', Error), |
|
], |
|
|
|
|
|
'main-fun': [ |
|
include('whitespace'), |
|
|
|
(r'\s', Text), |
|
(r'\(\*', Comment.Multiline, 'comment'), |
|
|
|
|
|
(r'\b(fun|and)\b(?!\')', Keyword.Reserved, 'fname'), |
|
(r'\b(val)\b(?!\')', Keyword.Reserved, |
|
('#pop', 'main', 'vname')), |
|
|
|
|
|
(r'\|', Punctuation, 'fname'), |
|
(r'\b(case|handle)\b(?!\')', Keyword.Reserved, |
|
('#pop', 'main')), |
|
|
|
include('delimiters'), |
|
include('core'), |
|
(r'\S+', Error), |
|
], |
|
|
|
|
|
'char': stringy(String.Char), |
|
'string': stringy(String.Double), |
|
|
|
'breakout': [ |
|
(r'(?=\b({})\b(?!\'))'.format('|'.join(alphanumid_reserved)), Text, '#pop'), |
|
], |
|
|
|
|
|
'sname': [ |
|
include('whitespace'), |
|
include('breakout'), |
|
|
|
(rf'({alphanumid_re})', Name.Namespace), |
|
default('#pop'), |
|
], |
|
|
|
|
|
'fname': [ |
|
include('whitespace'), |
|
(r'\'[\w\']*', Name.Decorator), |
|
(r'\(', Punctuation, 'tyvarseq'), |
|
|
|
(rf'({alphanumid_re})', Name.Function, '#pop'), |
|
(rf'({symbolicid_re})', Name.Function, '#pop'), |
|
|
|
|
|
default('#pop'), |
|
], |
|
|
|
|
|
'vname': [ |
|
include('whitespace'), |
|
(r'\'[\w\']*', Name.Decorator), |
|
(r'\(', Punctuation, 'tyvarseq'), |
|
|
|
(rf'({alphanumid_re})(\s*)(=(?!{symbolicid_re}))', |
|
bygroups(Name.Variable, Text, Punctuation), '#pop'), |
|
(rf'({symbolicid_re})(\s*)(=(?!{symbolicid_re}))', |
|
bygroups(Name.Variable, Text, Punctuation), '#pop'), |
|
(rf'({alphanumid_re})', Name.Variable, '#pop'), |
|
(rf'({symbolicid_re})', Name.Variable, '#pop'), |
|
|
|
|
|
default('#pop'), |
|
], |
|
|
|
|
|
'tname': [ |
|
include('whitespace'), |
|
include('breakout'), |
|
|
|
(r'\'[\w\']*', Name.Decorator), |
|
(r'\(', Punctuation, 'tyvarseq'), |
|
(rf'=(?!{symbolicid_re})', Punctuation, ('#pop', 'typbind')), |
|
|
|
(rf'({alphanumid_re})', Keyword.Type), |
|
(rf'({symbolicid_re})', Keyword.Type), |
|
(r'\S+', Error, '#pop'), |
|
], |
|
|
|
|
|
'typbind': [ |
|
include('whitespace'), |
|
|
|
(r'\b(and)\b(?!\')', Keyword.Reserved, ('#pop', 'tname')), |
|
|
|
include('breakout'), |
|
include('core'), |
|
(r'\S+', Error, '#pop'), |
|
], |
|
|
|
|
|
'dname': [ |
|
include('whitespace'), |
|
include('breakout'), |
|
|
|
(r'\'[\w\']*', Name.Decorator), |
|
(r'\(', Punctuation, 'tyvarseq'), |
|
(r'(=)(\s*)(datatype)', |
|
bygroups(Punctuation, Text, Keyword.Reserved), '#pop'), |
|
(rf'=(?!{symbolicid_re})', Punctuation, |
|
('#pop', 'datbind', 'datcon')), |
|
|
|
(rf'({alphanumid_re})', Keyword.Type), |
|
(rf'({symbolicid_re})', Keyword.Type), |
|
(r'\S+', Error, '#pop'), |
|
], |
|
|
|
|
|
'datbind': [ |
|
include('whitespace'), |
|
|
|
(r'\b(and)\b(?!\')', Keyword.Reserved, ('#pop', 'dname')), |
|
(r'\b(withtype)\b(?!\')', Keyword.Reserved, ('#pop', 'tname')), |
|
(r'\b(of)\b(?!\')', Keyword.Reserved), |
|
|
|
(rf'(\|)(\s*)({alphanumid_re})', |
|
bygroups(Punctuation, Text, Name.Class)), |
|
(rf'(\|)(\s+)({symbolicid_re})', |
|
bygroups(Punctuation, Text, Name.Class)), |
|
|
|
include('breakout'), |
|
include('core'), |
|
(r'\S+', Error), |
|
], |
|
|
|
|
|
'ename': [ |
|
include('whitespace'), |
|
|
|
(rf'(and\b)(\s+)({alphanumid_re})', |
|
bygroups(Keyword.Reserved, Text, Name.Class)), |
|
(rf'(and\b)(\s*)({symbolicid_re})', |
|
bygroups(Keyword.Reserved, Text, Name.Class)), |
|
(r'\b(of)\b(?!\')', Keyword.Reserved), |
|
(rf'({alphanumid_re})|({symbolicid_re})', Name.Class), |
|
|
|
default('#pop'), |
|
], |
|
|
|
'datcon': [ |
|
include('whitespace'), |
|
(rf'({alphanumid_re})', Name.Class, '#pop'), |
|
(rf'({symbolicid_re})', Name.Class, '#pop'), |
|
(r'\S+', Error, '#pop'), |
|
], |
|
|
|
|
|
'tyvarseq': [ |
|
(r'\s', Text), |
|
(r'\(\*', Comment.Multiline, 'comment'), |
|
|
|
(r'\'[\w\']*', Name.Decorator), |
|
(alphanumid_re, Name), |
|
(r',', Punctuation), |
|
(r'\)', Punctuation, '#pop'), |
|
(symbolicid_re, Name), |
|
], |
|
|
|
'comment': [ |
|
(r'[^(*)]', Comment.Multiline), |
|
(r'\(\*', Comment.Multiline, '#push'), |
|
(r'\*\)', Comment.Multiline, '#pop'), |
|
(r'[(*)]', Comment.Multiline), |
|
], |
|
} |
|
|
|
|
|
class OcamlLexer(RegexLexer): |
|
""" |
|
For the OCaml language. |
|
""" |
|
|
|
name = 'OCaml' |
|
url = 'https://ocaml.org/' |
|
aliases = ['ocaml'] |
|
filenames = ['*.ml', '*.mli', '*.mll', '*.mly'] |
|
mimetypes = ['text/x-ocaml'] |
|
version_added = '0.7' |
|
|
|
keywords = ( |
|
'and', 'as', 'assert', 'begin', 'class', 'constraint', 'do', 'done', |
|
'downto', 'else', 'end', 'exception', 'external', 'false', |
|
'for', 'fun', 'function', 'functor', 'if', 'in', 'include', |
|
'inherit', 'initializer', 'lazy', 'let', 'match', 'method', |
|
'module', 'mutable', 'new', 'object', 'of', 'open', 'private', |
|
'raise', 'rec', 'sig', 'struct', 'then', 'to', 'true', 'try', |
|
'type', 'val', 'virtual', 'when', 'while', 'with', |
|
) |
|
keyopts = ( |
|
'!=', '#', '&', '&&', r'\(', r'\)', r'\*', r'\+', ',', '-', |
|
r'-\.', '->', r'\.', r'\.\.', ':', '::', ':=', ':>', ';', ';;', '<', |
|
'<-', '=', '>', '>]', r'>\}', r'\?', r'\?\?', r'\[', r'\[<', r'\[>', |
|
r'\[\|', ']', '_', '`', r'\{', r'\{<', r'\|', r'\|]', r'\}', '~' |
|
) |
|
|
|
operators = r'[!$%&*+\./:<=>?@^|~-]' |
|
word_operators = ('asr', 'land', 'lor', 'lsl', 'lxor', 'mod', 'or') |
|
prefix_syms = r'[!?~]' |
|
infix_syms = r'[=<>@^|&+\*/$%-]' |
|
primitives = ('unit', 'int', 'float', 'bool', 'string', 'char', 'list', 'array') |
|
|
|
tokens = { |
|
'escape-sequence': [ |
|
(r'\\[\\"\'ntbr]', String.Escape), |
|
(r'\\[0-9]{3}', String.Escape), |
|
(r'\\x[0-9a-fA-F]{2}', String.Escape), |
|
], |
|
'root': [ |
|
(r'\s+', Text), |
|
(r'false|true|\(\)|\[\]', Name.Builtin.Pseudo), |
|
(r'\b([A-Z][\w\']*)(?=\s*\.)', Name.Namespace, 'dotted'), |
|
(r'\b([A-Z][\w\']*)', Name.Class), |
|
(r'\(\*(?![)])', Comment, 'comment'), |
|
(r'\b({})\b'.format('|'.join(keywords)), Keyword), |
|
(r'({})'.format('|'.join(keyopts[::-1])), Operator), |
|
(rf'({infix_syms}|{prefix_syms})?{operators}', Operator), |
|
(r'\b({})\b'.format('|'.join(word_operators)), Operator.Word), |
|
(r'\b({})\b'.format('|'.join(primitives)), Keyword.Type), |
|
|
|
(r"[^\W\d][\w']*", Name), |
|
|
|
(r'-?\d[\d_]*(.[\d_]*)?([eE][+\-]?\d[\d_]*)', Number.Float), |
|
(r'0[xX][\da-fA-F][\da-fA-F_]*', Number.Hex), |
|
(r'0[oO][0-7][0-7_]*', Number.Oct), |
|
(r'0[bB][01][01_]*', Number.Bin), |
|
(r'\d[\d_]*', Number.Integer), |
|
|
|
(r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2}))'", |
|
String.Char), |
|
(r"'.'", String.Char), |
|
(r"'", Keyword), |
|
|
|
(r'"', String.Double, 'string'), |
|
|
|
(r'[~?][a-z][\w\']*:', Name.Variable), |
|
], |
|
'comment': [ |
|
(r'[^(*)]+', Comment), |
|
(r'\(\*', Comment, '#push'), |
|
(r'\*\)', Comment, '#pop'), |
|
(r'[(*)]', Comment), |
|
], |
|
'string': [ |
|
(r'[^\\"]+', String.Double), |
|
include('escape-sequence'), |
|
(r'\\\n', String.Double), |
|
(r'"', String.Double, '#pop'), |
|
], |
|
'dotted': [ |
|
(r'\s+', Text), |
|
(r'\.', Punctuation), |
|
(r'[A-Z][\w\']*(?=\s*\.)', Name.Namespace), |
|
(r'[A-Z][\w\']*', Name.Class, '#pop'), |
|
(r'[a-z_][\w\']*', Name, '#pop'), |
|
default('#pop'), |
|
], |
|
} |
|
|
|
|
|
class OpaLexer(RegexLexer): |
|
""" |
|
Lexer for the Opa language. |
|
""" |
|
|
|
name = 'Opa' |
|
aliases = ['opa'] |
|
filenames = ['*.opa'] |
|
mimetypes = ['text/x-opa'] |
|
url = 'http://opalang.org' |
|
version_added = '1.5' |
|
|
|
|
|
|
|
|
|
keywords = ( |
|
'and', 'as', 'begin', 'case', 'client', 'css', 'database', 'db', 'do', |
|
'else', 'end', 'external', 'forall', 'function', 'if', 'import', |
|
'match', 'module', 'or', 'package', 'parser', 'rec', 'server', 'then', |
|
'type', 'val', 'with', 'xml_parser', |
|
) |
|
|
|
|
|
ident_re = r'(([a-zA-Z_]\w*)|(`[^`]*`))' |
|
|
|
op_re = r'[.=\-<>,@~%/+?*&^!]' |
|
punc_re = r'[()\[\],;|]' |
|
|
|
|
|
tokens = { |
|
|
|
'escape-sequence': [ |
|
(r'\\[\\"\'ntr}]', String.Escape), |
|
(r'\\[0-9]{3}', String.Escape), |
|
(r'\\x[0-9a-fA-F]{2}', String.Escape), |
|
], |
|
|
|
|
|
'comments': [ |
|
(r'/\*', Comment, 'nested-comment'), |
|
(r'//.*?$', Comment), |
|
], |
|
'comments-and-spaces': [ |
|
include('comments'), |
|
(r'\s+', Text), |
|
], |
|
|
|
'root': [ |
|
include('comments-and-spaces'), |
|
|
|
(words(keywords, prefix=r'\b', suffix=r'\b'), Keyword), |
|
|
|
|
|
|
|
|
|
|
|
(r'@' + ident_re + r'\b', Name.Builtin.Pseudo), |
|
|
|
|
|
(r'-?.[\d]+([eE][+\-]?\d+)', Number.Float), |
|
(r'-?\d+.\d*([eE][+\-]?\d+)', Number.Float), |
|
(r'-?\d+[eE][+\-]?\d+', Number.Float), |
|
(r'0[xX][\da-fA-F]+', Number.Hex), |
|
(r'0[oO][0-7]+', Number.Oct), |
|
(r'0[bB][01]+', Number.Bin), |
|
(r'\d+', Number.Integer), |
|
|
|
(r'#[\da-fA-F]{3,6}', Number.Integer), |
|
|
|
|
|
(r'"', String.Double, 'string'), |
|
|
|
|
|
(r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2})|.)'", |
|
String.Char), |
|
|
|
|
|
|
|
|
|
|
|
|
|
(r'\{', Operator, '#push'), |
|
(r'\}', Operator, '#pop'), |
|
|
|
|
|
|
|
|
|
|
|
|
|
(r'<(?=[a-zA-Z>])', String.Single, 'html-open-tag'), |
|
|
|
|
|
|
|
|
|
|
|
|
|
(r'[@?!]?(/\w+)+(\[_\])?', Name.Variable), |
|
|
|
|
|
(r'<-(?!'+op_re+r')', Name.Variable), |
|
|
|
|
|
|
|
|
|
|
|
(r'\b([A-Z]\w*)(?=\.)', Name.Namespace), |
|
|
|
|
|
|
|
|
|
|
|
(r'=(?!'+op_re+r')', Keyword), |
|
(rf'({op_re})+', Operator), |
|
(rf'({punc_re})+', Operator), |
|
|
|
|
|
(r':', Operator, 'type'), |
|
|
|
|
|
|
|
("'"+ident_re, Keyword.Type), |
|
|
|
|
|
(r'#'+ident_re, String.Single), |
|
(r'#(?=\{)', String.Single), |
|
|
|
|
|
|
|
(ident_re, Text), |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
'type': [ |
|
include('comments-and-spaces'), |
|
(r'->', Keyword.Type), |
|
default(('#pop', 'type-lhs-1', 'type-with-slash')), |
|
], |
|
|
|
|
|
|
|
|
|
'type-1': [ |
|
include('comments-and-spaces'), |
|
(r'\(', Keyword.Type, ('#pop', 'type-tuple')), |
|
(r'~?\{', Keyword.Type, ('#pop', 'type-record')), |
|
(ident_re+r'\(', Keyword.Type, ('#pop', 'type-tuple')), |
|
(ident_re, Keyword.Type, '#pop'), |
|
("'"+ident_re, Keyword.Type), |
|
|
|
|
|
|
|
|
|
default('#pop'), |
|
], |
|
|
|
|
|
|
|
|
|
'type-with-slash': [ |
|
include('comments-and-spaces'), |
|
default(('#pop', 'slash-type-1', 'type-1')), |
|
], |
|
'slash-type-1': [ |
|
include('comments-and-spaces'), |
|
('/', Keyword.Type, ('#pop', 'type-1')), |
|
|
|
default('#pop'), |
|
], |
|
|
|
|
|
|
|
|
|
|
|
|
|
'type-lhs-1': [ |
|
include('comments-and-spaces'), |
|
(r'->', Keyword.Type, ('#pop', 'type')), |
|
(r'(?=,)', Keyword.Type, ('#pop', 'type-arrow')), |
|
default('#pop'), |
|
], |
|
'type-arrow': [ |
|
include('comments-and-spaces'), |
|
|
|
|
|
(r',(?=[^:]*?->)', Keyword.Type, 'type-with-slash'), |
|
(r'->', Keyword.Type, ('#pop', 'type')), |
|
|
|
default('#pop'), |
|
], |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
'type-tuple': [ |
|
include('comments-and-spaces'), |
|
(r'[^()/*]+', Keyword.Type), |
|
(r'[/*]', Keyword.Type), |
|
(r'\(', Keyword.Type, '#push'), |
|
(r'\)', Keyword.Type, '#pop'), |
|
], |
|
'type-record': [ |
|
include('comments-and-spaces'), |
|
(r'[^{}/*]+', Keyword.Type), |
|
(r'[/*]', Keyword.Type), |
|
(r'\{', Keyword.Type, '#push'), |
|
(r'\}', Keyword.Type, '#pop'), |
|
], |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
'nested-comment': [ |
|
(r'[^/*]+', Comment), |
|
(r'/\*', Comment, '#push'), |
|
(r'\*/', Comment, '#pop'), |
|
(r'[/*]', Comment), |
|
], |
|
|
|
|
|
|
|
'string': [ |
|
(r'[^\\"{]+', String.Double), |
|
(r'"', String.Double, '#pop'), |
|
(r'\{', Operator, 'root'), |
|
include('escape-sequence'), |
|
], |
|
'single-string': [ |
|
(r'[^\\\'{]+', String.Double), |
|
(r'\'', String.Double, '#pop'), |
|
(r'\{', Operator, 'root'), |
|
include('escape-sequence'), |
|
], |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
'html-open-tag': [ |
|
(r'[\w\-:]+', String.Single, ('#pop', 'html-attr')), |
|
(r'>', String.Single, ('#pop', 'html-content')), |
|
], |
|
|
|
|
|
|
|
'html-end-tag': [ |
|
|
|
(r'[\w\-:]*>', String.Single, '#pop'), |
|
], |
|
|
|
|
|
|
|
'html-attr': [ |
|
(r'\s+', Text), |
|
(r'[\w\-:]+=', String.Single, 'html-attr-value'), |
|
(r'/>', String.Single, '#pop'), |
|
(r'>', String.Single, ('#pop', 'html-content')), |
|
], |
|
|
|
'html-attr-value': [ |
|
(r"'", String.Single, ('#pop', 'single-string')), |
|
(r'"', String.Single, ('#pop', 'string')), |
|
(r'#'+ident_re, String.Single, '#pop'), |
|
(r'#(?=\{)', String.Single, ('#pop', 'root')), |
|
(r'[^"\'{`=<>]+', String.Single, '#pop'), |
|
(r'\{', Operator, ('#pop', 'root')), |
|
], |
|
|
|
|
|
'html-content': [ |
|
(r'<!--', Comment, 'html-comment'), |
|
(r'</', String.Single, ('#pop', 'html-end-tag')), |
|
(r'<', String.Single, 'html-open-tag'), |
|
(r'\{', Operator, 'root'), |
|
(r'[^<{]+', String.Single), |
|
], |
|
|
|
'html-comment': [ |
|
(r'-->', Comment, '#pop'), |
|
(r'[^\-]+|-', Comment), |
|
], |
|
} |
|
|
|
|
|
class ReasonLexer(RegexLexer): |
|
""" |
|
For the ReasonML language. |
|
""" |
|
|
|
name = 'ReasonML' |
|
url = 'https://reasonml.github.io/' |
|
aliases = ['reasonml', 'reason'] |
|
filenames = ['*.re', '*.rei'] |
|
mimetypes = ['text/x-reasonml'] |
|
version_added = '2.6' |
|
|
|
keywords = ( |
|
'as', 'assert', 'begin', 'class', 'constraint', 'do', 'done', 'downto', |
|
'else', 'end', 'exception', 'external', 'false', 'for', 'fun', 'esfun', |
|
'function', 'functor', 'if', 'in', 'include', 'inherit', 'initializer', 'lazy', |
|
'let', 'switch', 'module', 'pub', 'mutable', 'new', 'nonrec', 'object', 'of', |
|
'open', 'pri', 'rec', 'sig', 'struct', 'then', 'to', 'true', 'try', |
|
'type', 'val', 'virtual', 'when', 'while', 'with', |
|
) |
|
keyopts = ( |
|
'!=', '#', '&', '&&', r'\(', r'\)', r'\*', r'\+', ',', '-', |
|
r'-\.', '=>', r'\.', r'\.\.', r'\.\.\.', ':', '::', ':=', ':>', ';', ';;', '<', |
|
'<-', '=', '>', '>]', r'>\}', r'\?', r'\?\?', r'\[', r'\[<', r'\[>', |
|
r'\[\|', ']', '_', '`', r'\{', r'\{<', r'\|', r'\|\|', r'\|]', r'\}', '~' |
|
) |
|
|
|
operators = r'[!$%&*+\./:<=>?@^|~-]' |
|
word_operators = ('and', 'asr', 'land', 'lor', 'lsl', 'lsr', 'lxor', 'mod', 'or') |
|
prefix_syms = r'[!?~]' |
|
infix_syms = r'[=<>@^|&+\*/$%-]' |
|
primitives = ('unit', 'int', 'float', 'bool', 'string', 'char', 'list', 'array') |
|
|
|
tokens = { |
|
'escape-sequence': [ |
|
(r'\\[\\"\'ntbr]', String.Escape), |
|
(r'\\[0-9]{3}', String.Escape), |
|
(r'\\x[0-9a-fA-F]{2}', String.Escape), |
|
], |
|
'root': [ |
|
(r'\s+', Text), |
|
(r'false|true|\(\)|\[\]', Name.Builtin.Pseudo), |
|
(r'\b([A-Z][\w\']*)(?=\s*\.)', Name.Namespace, 'dotted'), |
|
(r'\b([A-Z][\w\']*)', Name.Class), |
|
(r'//.*?\n', Comment.Single), |
|
(r'\/\*(?!/)', Comment.Multiline, 'comment'), |
|
(r'\b({})\b'.format('|'.join(keywords)), Keyword), |
|
(r'({})'.format('|'.join(keyopts[::-1])), Operator.Word), |
|
(rf'({infix_syms}|{prefix_syms})?{operators}', Operator), |
|
(r'\b({})\b'.format('|'.join(word_operators)), Operator.Word), |
|
(r'\b({})\b'.format('|'.join(primitives)), Keyword.Type), |
|
|
|
(r"[^\W\d][\w']*", Name), |
|
|
|
(r'-?\d[\d_]*(.[\d_]*)?([eE][+\-]?\d[\d_]*)', Number.Float), |
|
(r'0[xX][\da-fA-F][\da-fA-F_]*', Number.Hex), |
|
(r'0[oO][0-7][0-7_]*', Number.Oct), |
|
(r'0[bB][01][01_]*', Number.Bin), |
|
(r'\d[\d_]*', Number.Integer), |
|
|
|
(r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2}))'", |
|
String.Char), |
|
(r"'.'", String.Char), |
|
(r"'", Keyword), |
|
|
|
(r'"', String.Double, 'string'), |
|
|
|
(r'[~?][a-z][\w\']*:', Name.Variable), |
|
], |
|
'comment': [ |
|
(r'[^/*]+', Comment.Multiline), |
|
(r'\/\*', Comment.Multiline, '#push'), |
|
(r'\*\/', Comment.Multiline, '#pop'), |
|
(r'\*', Comment.Multiline), |
|
], |
|
'string': [ |
|
(r'[^\\"]+', String.Double), |
|
include('escape-sequence'), |
|
(r'\\\n', String.Double), |
|
(r'"', String.Double, '#pop'), |
|
], |
|
'dotted': [ |
|
(r'\s+', Text), |
|
(r'\.', Punctuation), |
|
(r'[A-Z][\w\']*(?=\s*\.)', Name.Namespace), |
|
(r'[A-Z][\w\']*', Name.Class, '#pop'), |
|
(r'[a-z_][\w\']*', Name, '#pop'), |
|
default('#pop'), |
|
], |
|
} |
|
|
|
|
|
class FStarLexer(RegexLexer): |
|
""" |
|
For the F* language. |
|
""" |
|
|
|
name = 'FStar' |
|
url = 'https://www.fstar-lang.org/' |
|
aliases = ['fstar'] |
|
filenames = ['*.fst', '*.fsti'] |
|
mimetypes = ['text/x-fstar'] |
|
version_added = '2.7' |
|
|
|
keywords = ( |
|
'abstract', 'attributes', 'noeq', 'unopteq', 'and' |
|
'begin', 'by', 'default', 'effect', 'else', 'end', 'ensures', |
|
'exception', 'exists', 'false', 'forall', 'fun', 'function', 'if', |
|
'in', 'include', 'inline', 'inline_for_extraction', 'irreducible', |
|
'logic', 'match', 'module', 'mutable', 'new', 'new_effect', 'noextract', |
|
'of', 'open', 'opaque', 'private', 'range_of', 'reifiable', |
|
'reify', 'reflectable', 'requires', 'set_range_of', 'sub_effect', |
|
'synth', 'then', 'total', 'true', 'try', 'type', 'unfold', 'unfoldable', |
|
'val', 'when', 'with', 'not' |
|
) |
|
decl_keywords = ('let', 'rec') |
|
assume_keywords = ('assume', 'admit', 'assert', 'calc') |
|
keyopts = ( |
|
r'~', r'-', r'/\\', r'\\/', r'<:', r'<@', r'\(\|', r'\|\)', r'#', r'u#', |
|
r'&', r'\(', r'\)', r'\(\)', r',', r'~>', r'->', r'<-', r'<--', r'<==>', |
|
r'==>', r'\.', r'\?', r'\?\.', r'\.\[', r'\.\(', r'\.\(\|', r'\.\[\|', |
|
r'\{:pattern', r':', r'::', r':=', r';', r';;', r'=', r'%\[', r'!\{', |
|
r'\[', r'\[@', r'\[\|', r'\|>', r'\]', r'\|\]', r'\{', r'\|', r'\}', r'\$' |
|
) |
|
|
|
operators = r'[!$%&*+\./:<=>?@^|~-]' |
|
prefix_syms = r'[!?~]' |
|
infix_syms = r'[=<>@^|&+\*/$%-]' |
|
primitives = ('unit', 'int', 'float', 'bool', 'string', 'char', 'list', 'array') |
|
|
|
tokens = { |
|
'escape-sequence': [ |
|
(r'\\[\\"\'ntbr]', String.Escape), |
|
(r'\\[0-9]{3}', String.Escape), |
|
(r'\\x[0-9a-fA-F]{2}', String.Escape), |
|
], |
|
'root': [ |
|
(r'\s+', Text), |
|
(r'false|true|False|True|\(\)|\[\]', Name.Builtin.Pseudo), |
|
(r'\b([A-Z][\w\']*)(?=\s*\.)', Name.Namespace, 'dotted'), |
|
(r'\b([A-Z][\w\']*)', Name.Class), |
|
(r'\(\*(?![)])', Comment, 'comment'), |
|
(r'\/\/.+$', Comment), |
|
(r'\b({})\b'.format('|'.join(keywords)), Keyword), |
|
(r'\b({})\b'.format('|'.join(assume_keywords)), Name.Exception), |
|
(r'\b({})\b'.format('|'.join(decl_keywords)), Keyword.Declaration), |
|
(r'({})'.format('|'.join(keyopts[::-1])), Operator), |
|
(rf'({infix_syms}|{prefix_syms})?{operators}', Operator), |
|
(r'\b({})\b'.format('|'.join(primitives)), Keyword.Type), |
|
|
|
(r"[^\W\d][\w']*", Name), |
|
|
|
(r'-?\d[\d_]*(.[\d_]*)?([eE][+\-]?\d[\d_]*)', Number.Float), |
|
(r'0[xX][\da-fA-F][\da-fA-F_]*', Number.Hex), |
|
(r'0[oO][0-7][0-7_]*', Number.Oct), |
|
(r'0[bB][01][01_]*', Number.Bin), |
|
(r'\d[\d_]*', Number.Integer), |
|
|
|
(r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2}))'", |
|
String.Char), |
|
(r"'.'", String.Char), |
|
(r"'", Keyword), |
|
(r"\`([\w\'.]+)\`", Operator.Word), |
|
(r"\`", Keyword), |
|
(r'"', String.Double, 'string'), |
|
|
|
(r'[~?][a-z][\w\']*:', Name.Variable), |
|
], |
|
'comment': [ |
|
(r'[^(*)]+', Comment), |
|
(r'\(\*', Comment, '#push'), |
|
(r'\*\)', Comment, '#pop'), |
|
(r'[(*)]', Comment), |
|
], |
|
'string': [ |
|
(r'[^\\"]+', String.Double), |
|
include('escape-sequence'), |
|
(r'\\\n', String.Double), |
|
(r'"', String.Double, '#pop'), |
|
], |
|
'dotted': [ |
|
(r'\s+', Text), |
|
(r'\.', Punctuation), |
|
(r'[A-Z][\w\']*(?=\s*\.)', Name.Namespace), |
|
(r'[A-Z][\w\']*', Name.Class, '#pop'), |
|
(r'[a-z_][\w\']*', Name, '#pop'), |
|
default('#pop'), |
|
], |
|
} |
|
|