summaryrefslogtreecommitdiff
path: root/pygments/lexers/dotnet.py
diff options
context:
space:
mode:
Diffstat (limited to 'pygments/lexers/dotnet.py')
-rw-r--r--pygments/lexers/dotnet.py177
1 files changed, 107 insertions, 70 deletions
diff --git a/pygments/lexers/dotnet.py b/pygments/lexers/dotnet.py
index 890d46d9..0754ba02 100644
--- a/pygments/lexers/dotnet.py
+++ b/pygments/lexers/dotnet.py
@@ -5,7 +5,7 @@
Lexers for .net languages.
- :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS.
+ :copyright: Copyright 2006-2014 by the Pygments team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import re
@@ -14,7 +14,7 @@ from pygments.lexer import RegexLexer, DelegatingLexer, bygroups, include, \
using, this
from pygments.token import Punctuation, \
Text, Comment, Operator, Keyword, Name, String, Number, Literal, Other
-from pygments.util import get_choice_opt
+from pygments.util import get_choice_opt, iteritems
from pygments import unistring as uni
from pygments.lexers.web import XmlLexer
@@ -23,10 +23,6 @@ __all__ = ['CSharpLexer', 'NemerleLexer', 'BooLexer', 'VbNetLexer',
'CSharpAspxLexer', 'VbNetAspxLexer', 'FSharpLexer']
-def _escape(st):
- return st.replace(u'\\', ur'\\').replace(u'-', ur'\-').\
- replace(u'[', ur'\[').replace(u']', ur'\]')
-
class CSharpLexer(RegexLexer):
"""
For `C# <http://msdn2.microsoft.com/en-us/vcsharp/default.aspx>`_
@@ -48,7 +44,7 @@ class CSharpLexer(RegexLexer):
The default value is ``basic``.
- *New in Pygments 0.8.*
+ .. versionadded:: 0.8
"""
name = 'C#'
@@ -67,16 +63,15 @@ class CSharpLexer(RegexLexer):
'[' + uni.Lu + uni.Ll + uni.Lt + uni.Lm + uni.Nl +
uni.Nd + uni.Pc + uni.Cf + uni.Mn + uni.Mc + ']*'),
'full': ('@?(?:_|[^' +
- _escape(uni.allexcept('Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl')) + '])'
- + '[^' + _escape(uni.allexcept('Lu', 'Ll', 'Lt', 'Lm', 'Lo',
- 'Nl', 'Nd', 'Pc', 'Cf', 'Mn',
- 'Mc')) + ']*'),
+ uni.allexcept('Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl') + '])'
+ + '[^' + uni.allexcept('Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl',
+ 'Nd', 'Pc', 'Cf', 'Mn', 'Mc') + ']*'),
}
tokens = {}
token_variants = True
- for levelname, cs_ident in levels.items():
+ for levelname, cs_ident in iteritems(levels):
tokens[levelname] = {
'root': [
# method names
@@ -88,7 +83,7 @@ class CSharpLexer(RegexLexer):
(r'[^\S\n]+', Text),
(r'\\\n', Text), # line continuation
(r'//.*?\n', Comment.Single),
- (r'/[*](.|\n)*?[*]/', Comment.Multiline),
+ (r'/[*].*?[*]/', Comment.Multiline),
(r'\n', Text),
(r'[~!%^&*()+=|\[\]:;,.<>/?-]', Punctuation),
(r'[{}]', Punctuation),
@@ -131,7 +126,7 @@ class CSharpLexer(RegexLexer):
}
def __init__(self, **options):
- level = get_choice_opt(options, 'unicodelevel', self.tokens.keys(), 'basic')
+ level = get_choice_opt(options, 'unicodelevel', list(self.tokens), 'basic')
if level not in self._all_tokens:
# compile the regexes now
self._tokens = self.__class__.process_tokendef(level)
@@ -161,7 +156,7 @@ class NemerleLexer(RegexLexer):
The default value is ``basic``.
- *New in Pygments 1.5.*
+ .. versionadded:: 1.5
"""
name = 'Nemerle'
@@ -179,17 +174,16 @@ class NemerleLexer(RegexLexer):
basic = ('@?[_' + uni.Lu + uni.Ll + uni.Lt + uni.Lm + uni.Nl + ']' +
'[' + uni.Lu + uni.Ll + uni.Lt + uni.Lm + uni.Nl +
uni.Nd + uni.Pc + uni.Cf + uni.Mn + uni.Mc + ']*'),
- full = ('@?(?:_|[^' + _escape(uni.allexcept('Lu', 'Ll', 'Lt', 'Lm',
- 'Lo', 'Nl')) + '])'
- + '[^' + _escape(uni.allexcept('Lu', 'Ll', 'Lt', 'Lm', 'Lo',
- 'Nl', 'Nd', 'Pc', 'Cf', 'Mn',
- 'Mc')) + ']*'),
+ full = ('@?(?:_|[^' + uni.allexcept('Lu', 'Ll', 'Lt', 'Lm', 'Lo',
+ 'Nl') + '])'
+ + '[^' + uni.allexcept('Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl',
+ 'Nd', 'Pc', 'Cf', 'Mn', 'Mc') + ']*'),
)
tokens = {}
token_variants = True
- for levelname, cs_ident in levels.items():
+ for levelname, cs_ident in iteritems(levels):
tokens[levelname] = {
'root': [
# method names
@@ -290,7 +284,7 @@ class NemerleLexer(RegexLexer):
}
def __init__(self, **options):
- level = get_choice_opt(options, 'unicodelevel', self.tokens.keys(),
+ level = get_choice_opt(options, 'unicodelevel', list(self.tokens),
'basic')
if level not in self._all_tokens:
# compile the regexes now
@@ -535,9 +529,9 @@ class VbNetAspxLexer(DelegatingLexer):
# Very close to functional.OcamlLexer
class FSharpLexer(RegexLexer):
"""
- For the F# language.
+ For the F# language (version 3.0).
- *New in Pygments 1.5.*
+ .. versionadded:: 1.5
"""
name = 'FSharp'
@@ -546,91 +540,134 @@ class FSharpLexer(RegexLexer):
mimetypes = ['text/x-fsharp']
keywords = [
- 'abstract', 'and', 'as', 'assert', 'base', 'begin', 'class',
- 'default', 'delegate', 'do', 'do!', 'done', 'downcast',
- 'downto', 'elif', 'else', 'end', 'exception', 'extern',
- 'false', 'finally', 'for', 'fun', 'function', 'global', 'if',
- 'in', 'inherit', 'inline', 'interface', 'internal', 'lazy',
- 'let', 'let!', 'match', 'member', 'module', 'mutable',
- 'namespace', 'new', 'null', 'of', 'open', 'or', 'override',
- 'private', 'public', 'rec', 'return', 'return!', 'sig',
- 'static', 'struct', 'then', 'to', 'true', 'try', 'type',
- 'upcast', 'use', 'use!', 'val', 'void', 'when', 'while',
- 'with', 'yield', 'yield!'
+ 'abstract', 'as', 'assert', 'base', 'begin', 'class', 'default',
+ 'delegate', 'do!', 'do', 'done', 'downcast', 'downto', 'elif', 'else',
+ 'end', 'exception', 'extern', 'false', 'finally', 'for', 'function',
+ 'fun', 'global', 'if', 'inherit', 'inline', 'interface', 'internal',
+ 'in', 'lazy', 'let!', 'let', 'match', 'member', 'module', 'mutable',
+ 'namespace', 'new', 'null', 'of', 'open', 'override', 'private', 'public',
+ 'rec', 'return!', 'return', 'select', 'static', 'struct', 'then', 'to',
+ 'true', 'try', 'type', 'upcast', 'use!', 'use', 'val', 'void', 'when',
+ 'while', 'with', 'yield!', 'yield',
+ ]
+ # Reserved words; cannot hurt to color them as keywords too.
+ keywords += [
+ 'atomic', 'break', 'checked', 'component', 'const', 'constraint',
+ 'constructor', 'continue', 'eager', 'event', 'external', 'fixed',
+ 'functor', 'include', 'method', 'mixin', 'object', 'parallel',
+ 'process', 'protected', 'pure', 'sealed', 'tailcall', 'trait',
+ 'virtual', 'volatile',
]
keyopts = [
- '!=','#','&&','&','\(','\)','\*','\+',',','-\.',
- '->','-','\.\.','\.','::',':=',':>',':',';;',';','<-',
- '<','>]','>','\?\?','\?','\[<','\[>','\[\|','\[',
- ']','_','`','{','\|\]','\|','}','~','<@','=','@>'
+ '!=', '#', '&&', '&', '\(', '\)', '\*', '\+', ',', '-\.',
+ '->', '-', '\.\.', '\.', '::', ':=', ':>', ':', ';;', ';', '<-',
+ '<\]', '<', '>\]', '>', '\?\?', '\?', '\[<', '\[\|', '\[', '\]',
+ '_', '`', '{', '\|\]', '\|', '}', '~', '<@@', '<@', '=', '@>', '@@>',
]
operators = r'[!$%&*+\./:<=>?@^|~-]'
- word_operators = ['and', 'asr', 'land', 'lor', 'lsl', 'lxor', 'mod', 'not', 'or']
+ word_operators = ['and', 'or', 'not']
prefix_syms = r'[!?~]'
infix_syms = r'[=<>@^|&+\*/$%-]'
- primitives = ['unit', 'int', 'float', 'bool', 'string', 'char', 'list', 'array',
- 'byte', 'sbyte', 'int16', 'uint16', 'uint32', 'int64', 'uint64'
- 'nativeint', 'unativeint', 'decimal', 'void', 'float32', 'single',
- 'double']
+ primitives = [
+ 'sbyte', 'byte', 'char', 'nativeint', 'unativeint', 'float32', 'single',
+ 'float', 'double', 'int8', 'uint8', 'int16', 'uint16', 'int32',
+ 'uint32', 'int64', 'uint64', 'decimal', 'unit', 'bool', 'string',
+ 'list', 'exn', 'obj', 'enum',
+ ]
+
+ # See http://msdn.microsoft.com/en-us/library/dd233181.aspx and/or
+ # http://fsharp.org/about/files/spec.pdf for reference. Good luck.
tokens = {
'escape-sequence': [
- (r'\\[\\\"\'ntbr]', String.Escape),
+ (r'\\[\\\"\'ntbrafv]', String.Escape),
(r'\\[0-9]{3}', String.Escape),
- (r'\\x[0-9a-fA-F]{2}', String.Escape),
+ (r'\\u[0-9a-fA-F]{4}', String.Escape),
+ (r'\\U[0-9a-fA-F]{8}', String.Escape),
],
'root': [
(r'\s+', Text),
- (r'false|true|\(\)|\[\]', Name.Builtin.Pseudo),
- (r'\b([A-Z][A-Za-z0-9_\']*)(?=\s*\.)',
+ (r'\(\)|\[\]', Name.Builtin.Pseudo),
+ (r'\b(?<!\.)([A-Z][A-Za-z0-9_\']*)(?=\s*\.)',
Name.Namespace, 'dotted'),
- (r'\b([A-Z][A-Za-z0-9_\']*)', Name.Class),
+ (r'\b([A-Z][A-Za-z0-9_\']*)', Name),
+ (r'///.*?\n', String.Doc),
(r'//.*?\n', Comment.Single),
(r'\(\*(?!\))', Comment, 'comment'),
+
+ (r'@"', String, 'lstring'),
+ (r'"""', String, 'tqs'),
+ (r'"', String, 'string'),
+
+ (r'\b(open|module)(\s+)([a-zA-Z0-9_.]+)',
+ bygroups(Keyword, Text, Name.Namespace)),
+ (r'\b(let!?)(\s+)([a-zA-Z0-9_]+)',
+ bygroups(Keyword, Text, Name.Variable)),
+ (r'\b(type)(\s+)([a-zA-Z0-9_]+)',
+ bygroups(Keyword, Text, Name.Class)),
+ (r'\b(member|override)(\s+)([a-zA-Z0-9_]+)(\.)([a-zA-Z0-9_]+)',
+ bygroups(Keyword, Text, Name, Punctuation, Name.Function)),
(r'\b(%s)\b' % '|'.join(keywords), Keyword),
(r'(%s)' % '|'.join(keyopts), Operator),
(r'(%s|%s)?%s' % (infix_syms, prefix_syms, operators), Operator),
(r'\b(%s)\b' % '|'.join(word_operators), Operator.Word),
(r'\b(%s)\b' % '|'.join(primitives), Keyword.Type),
-
- (r'#[ \t]*(if|endif|else|line|nowarn|light)\b.*?\n',
+ (r'#[ \t]*(if|endif|else|line|nowarn|light|\d+)\b.*?\n',
Comment.Preproc),
(r"[^\W\d][\w']*", Name),
- (r'\d[\d_]*', Number.Integer),
- (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.Binary),
- (r'-?\d[\d_]*(.[\d_]*)?([eE][+\-]?\d[\d_]*)', Number.Float),
+ (r'\d[\d_]*[uU]?[yslLnQRZINGmM]?', Number.Integer),
+ (r'0[xX][\da-fA-F][\da-fA-F_]*[uU]?[yslLn]?[fF]?', Number.Hex),
+ (r'0[oO][0-7][0-7_]*[uU]?[yslLn]?', Number.Oct),
+ (r'0[bB][01][01_]*[uU]?[yslLn]?', Number.Binary),
+ (r'-?\d[\d_]*(.[\d_]*)?([eE][+\-]?\d[\d_]*)[fFmM]?',
+ Number.Float),
- (r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2}))'",
+ (r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2}))'B?",
String.Char),
(r"'.'", String.Char),
(r"'", Keyword), # a stray quote is another syntax element
- (r'"', String.Double, 'string'),
-
(r'[~?][a-z][\w\']*:', Name.Variable),
],
+ 'dotted': [
+ (r'\s+', Text),
+ (r'\.', Punctuation),
+ (r'[A-Z][A-Za-z0-9_\']*(?=\s*\.)', Name.Namespace),
+ (r'[A-Z][A-Za-z0-9_\']*', Name, '#pop'),
+ (r'[a-z_][A-Za-z0-9_\']*', Name, '#pop'),
+ # e.g. dictionary index access
+ (r'', Text, '#pop'),
+ ],
'comment': [
- (r'[^(*)]+', Comment),
+ (r'[^(*)@"]+', Comment),
(r'\(\*', Comment, '#push'),
(r'\*\)', Comment, '#pop'),
- (r'[(*)]', Comment),
+ # comments cannot be closed within strings in comments
+ (r'@"', String, 'lstring'),
+ (r'"""', String, 'tqs'),
+ (r'"', String, 'string'),
+ (r'[(*)@]', Comment),
],
'string': [
- (r'[^\\"]+', String.Double),
+ (r'[^\\"]+', String),
include('escape-sequence'),
- (r'\\\n', String.Double),
- (r'"', String.Double, '#pop'),
+ (r'\\\n', String),
+ (r'\n', String), # newlines are allowed in any string
+ (r'"B?', String, '#pop'),
],
- 'dotted': [
- (r'\s+', Text),
- (r'\.', Punctuation),
- (r'[A-Z][A-Za-z0-9_\']*(?=\s*\.)', Name.Namespace),
- (r'[A-Z][A-Za-z0-9_\']*', Name.Class, '#pop'),
- (r'[a-z_][A-Za-z0-9_\']*', Name, '#pop'),
+ 'lstring': [
+ (r'[^"]+', String),
+ (r'\n', String),
+ (r'""', String),
+ (r'"B?', String, '#pop'),
+ ],
+ 'tqs': [
+ (r'[^"]+', String),
+ (r'\n', String),
+ (r'"""B?', String, '#pop'),
+ (r'"', String),
],
}