summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian McKenna <brian@brianmckenna.org>2011-03-28 20:24:41 +1100
committerBrian McKenna <brian@brianmckenna.org>2011-03-28 20:24:41 +1100
commit898243409003a269cbcb167806af85d7cd287bf3 (patch)
tree7c44b9a75733b89a8cc9cfd31833c815daeb959d
parent6f44865a9277c52a5260c7f3efa7b25a4d3d419a (diff)
downloadpygments-898243409003a269cbcb167806af85d7cd287bf3.tar.gz
Added F# lexer
-rw-r--r--pygments/lexers/_mapping.py1
-rw-r--r--pygments/lexers/dotnet.py107
2 files changed, 106 insertions, 2 deletions
diff --git a/pygments/lexers/_mapping.py b/pygments/lexers/_mapping.py
index b3ab5b14..a4edf83e 100644
--- a/pygments/lexers/_mapping.py
+++ b/pygments/lexers/_mapping.py
@@ -83,6 +83,7 @@ LEXERS = {
'FancyLexer': ('pygments.lexers.agile', 'Fancy', ('fancy', 'fy'), ('*.fy', '*.fancypack'), ('text/x-fancysrc',)),
'FelixLexer': ('pygments.lexers.compiled', 'Felix', ('felix', 'flx'), ('*.flx', '*.flxh'), ('text/x-felix',)),
'FortranLexer': ('pygments.lexers.compiled', 'Fortran', ('fortran',), ('*.f', '*.f90'), ('text/x-fortran',)),
+ 'FSharpLexer': ('pygments.lexers.dotnet', 'FSharp', ('fsharp',), ('*.fs', '*.fsi'), ('text/x-fsharp',)),
'GLShaderLexer': ('pygments.lexers.compiled', 'GLSL', ('glsl',), ('*.vert', '*.frag', '*.geo'), ('text/x-glslsrc',)),
'GasLexer': ('pygments.lexers.asm', 'GAS', ('gas',), ('*.s', '*.S'), ('text/x-gas',)),
'GenshiLexer': ('pygments.lexers.templates', 'Genshi', ('genshi', 'kid', 'xml+genshi', 'xml+kid'), ('*.kid',), ('application/x-genshi', 'application/x-kid')),
diff --git a/pygments/lexers/dotnet.py b/pygments/lexers/dotnet.py
index 48feeb85..ff3e6d30 100644
--- a/pygments/lexers/dotnet.py
+++ b/pygments/lexers/dotnet.py
@@ -10,7 +10,8 @@
"""
import re
-from pygments.lexer import RegexLexer, DelegatingLexer, bygroups, using, this
+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
@@ -19,7 +20,7 @@ from pygments import unistring as uni
from pygments.lexers.web import XmlLexer
__all__ = ['CSharpLexer', 'BooLexer', 'VbNetLexer', 'CSharpAspxLexer',
- 'VbNetAspxLexer']
+ 'VbNetAspxLexer', 'FSharpLexer']
def _escape(st):
@@ -365,3 +366,105 @@ class VbNetAspxLexer(DelegatingLexer):
return 0.2
elif re.search(r'script[^>]+language=["\']vb', text, re.I) is not None:
return 0.15
+
+
+# Very close to functional.OcamlLexer
+class FSharpLexer(RegexLexer):
+ """
+ For the F# language.
+ """
+
+ name = 'FSharp'
+ aliases = ['fsharp']
+ filenames = ['*.fs', '*.fsi']
+ 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!'
+ ]
+ keyopts = [
+ '!=','#','&','&&','\(','\)','\*','\+',',','-',
+ '-\.','->','\.','\.\.',':','::',':=',':>',';',';;','<',
+ '<-','>','>]','\?','\?\?','\[','\[<','\[>','\[\|',
+ ']','_','`','{','\|','\|]','}','~','<@','=','@>'
+ ]
+
+ operators = r'[!$%&*+\./:<=>?@^|~-]'
+ word_operators = ['and', 'asr', 'land', 'lor', 'lsl', 'lxor', 'mod', 'not', 'or']
+ 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']
+
+ 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][A-Za-z0-9_\']*)(?=\s*\.)',
+ Name.Namespace, 'dotted'),
+ (r'\b([A-Z][A-Za-z0-9_\']*)', Name.Class),
+ (r'//.*?\n', Comment.Single),
+ (r'\(\*', Comment, 'comment'),
+ (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',
+ 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"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2}))'",
+ String.Char),
+ (r"'.'", String.Char),
+ (r"'", Keyword), # a stray quote is another syntax element
+
+ (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][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'),
+ ],
+ }