3 pygments.lexers.haskell |
3 pygments.lexers.haskell |
4 ~~~~~~~~~~~~~~~~~~~~~~~ |
4 ~~~~~~~~~~~~~~~~~~~~~~~ |
5 |
5 |
6 Lexers for Haskell and related languages. |
6 Lexers for Haskell and related languages. |
7 |
7 |
8 :copyright: Copyright 2006-2017 by the Pygments team, see AUTHORS. |
8 :copyright: Copyright 2006-2019 by the Pygments team, see AUTHORS. |
9 :license: BSD, see LICENSE for details. |
9 :license: BSD, see LICENSE for details. |
10 """ |
10 """ |
11 |
11 |
12 import re |
12 import re |
13 |
13 |
14 from pygments.lexer import Lexer, RegexLexer, bygroups, do_insertions, \ |
14 from pygments.lexer import Lexer, RegexLexer, bygroups, do_insertions, \ |
15 default, include |
15 default, include, inherit |
16 from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ |
16 from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ |
17 Number, Punctuation, Generic |
17 Number, Punctuation, Generic |
18 from pygments import unistring as uni |
18 from pygments import unistring as uni |
19 |
19 |
20 __all__ = ['HaskellLexer', 'IdrisLexer', 'AgdaLexer', 'CryptolLexer', |
20 __all__ = ['HaskellLexer', 'HspecLexer', 'IdrisLexer', 'AgdaLexer', 'CryptolLexer', |
21 'LiterateHaskellLexer', 'LiterateIdrisLexer', 'LiterateAgdaLexer', |
21 'LiterateHaskellLexer', 'LiterateIdrisLexer', 'LiterateAgdaLexer', |
22 'LiterateCryptolLexer', 'KokaLexer'] |
22 'LiterateCryptolLexer', 'KokaLexer'] |
23 |
23 |
24 |
24 |
25 line_re = re.compile('.*?\n') |
25 line_re = re.compile('.*?\n') |
64 (r"'?[_" + uni.Ll + r"][\w']*", Name), |
64 (r"'?[_" + uni.Ll + r"][\w']*", Name), |
65 (r"('')?[" + uni.Lu + r"][\w\']*", Keyword.Type), |
65 (r"('')?[" + uni.Lu + r"][\w\']*", Keyword.Type), |
66 (r"(')[" + uni.Lu + r"][\w\']*", Keyword.Type), |
66 (r"(')[" + uni.Lu + r"][\w\']*", Keyword.Type), |
67 (r"(')\[[^\]]*\]", Keyword.Type), # tuples and lists get special treatment in GHC |
67 (r"(')\[[^\]]*\]", Keyword.Type), # tuples and lists get special treatment in GHC |
68 (r"(')\([^)]*\)", Keyword.Type), # .. |
68 (r"(')\([^)]*\)", Keyword.Type), # .. |
|
69 (r"(')[:!#$%&*+.\\/<=>?@^|~-]+", Keyword.Type), # promoted type operators |
69 # Operators |
70 # Operators |
70 (r'\\(?![:!#$%&*+.\\/<=>?@^|~-]+)', Name.Function), # lambda operator |
71 (r'\\(?![:!#$%&*+.\\/<=>?@^|~-]+)', Name.Function), # lambda operator |
71 (r'(<-|::|->|=>|=)(?![:!#$%&*+.\\/<=>?@^|~-]+)', Operator.Word), # specials |
72 (r'(<-|::|->|=>|=)(?![:!#$%&*+.\\/<=>?@^|~-]+)', Operator.Word), # specials |
72 (r':[:!#$%&*+.\\/<=>?@^|~-]*', Keyword.Type), # Constructor operators |
73 (r':[:!#$%&*+.\\/<=>?@^|~-]*', Keyword.Type), # Constructor operators |
73 (r'[:!#$%&*+.\\/<=>?@^|~-]+', Operator), # Other operators |
74 (r'[:!#$%&*+.\\/<=>?@^|~-]+', Operator), # Other operators |
74 # Numbers |
75 # Numbers |
75 (r'0[xX]_*[\da-fA-F](_*[\da-fA-F])*_*[pP][+-]?\d(_*\d)*', Number.Float), |
76 (r'0[xX]_*[\da-fA-F](_*[\da-fA-F])*_*[pP][+-]?\d(_*\d)*', Number.Float), |
76 (r'0[xX]_*[\da-fA-F](_*[\da-fA-F])*\.[\da-fA-F](_*[\da-fA-F])*(_*[pP][+-]?\d(_*\d)*)?', Number.Float), |
77 (r'0[xX]_*[\da-fA-F](_*[\da-fA-F])*\.[\da-fA-F](_*[\da-fA-F])*' |
|
78 r'(_*[pP][+-]?\d(_*\d)*)?', Number.Float), |
77 (r'\d(_*\d)*_*[eE][+-]?\d(_*\d)*', Number.Float), |
79 (r'\d(_*\d)*_*[eE][+-]?\d(_*\d)*', Number.Float), |
78 (r'\d(_*\d)*\.\d(_*\d)*(_*[eE][+-]?\d(_*\d)*)?', Number.Float), |
80 (r'\d(_*\d)*\.\d(_*\d)*(_*[eE][+-]?\d(_*\d)*)?', Number.Float), |
79 (r'0[bB]_*[01](_*[01])*', Number.Bin), |
81 (r'0[bB]_*[01](_*[01])*', Number.Bin), |
80 (r'0[oO]_*[0-7](_*[0-7])*', Number.Oct), |
82 (r'0[oO]_*[0-7](_*[0-7])*', Number.Oct), |
81 (r'0[xX]_*[\da-fA-F](_*[\da-fA-F])*', Number.Hex), |
83 (r'0[xX]_*[\da-fA-F](_*[\da-fA-F])*', Number.Hex), |
155 (r'\s+\\', String.Escape, '#pop'), |
157 (r'\s+\\', String.Escape, '#pop'), |
156 ], |
158 ], |
157 } |
159 } |
158 |
160 |
159 |
161 |
|
162 class HspecLexer(HaskellLexer): |
|
163 """ |
|
164 A Haskell lexer with support for Hspec constructs. |
|
165 |
|
166 .. versionadded:: 2.4.0 |
|
167 """ |
|
168 |
|
169 name = 'Hspec' |
|
170 aliases = ['hspec'] |
|
171 filenames = [] |
|
172 mimetypes = [] |
|
173 |
|
174 tokens = { |
|
175 'root': [ |
|
176 (r'(it\s*)("[^"]*")', bygroups(Text, String.Doc)), |
|
177 (r'(describe\s*)("[^"]*")', bygroups(Text, String.Doc)), |
|
178 (r'(context\s*)("[^"]*")', bygroups(Text, String.Doc)), |
|
179 inherit, |
|
180 ], |
|
181 } |
|
182 |
|
183 |
160 class IdrisLexer(RegexLexer): |
184 class IdrisLexer(RegexLexer): |
161 """ |
185 """ |
162 A lexer for the dependently typed programming language Idris. |
186 A lexer for the dependently typed programming language Idris. |
163 |
187 |
164 Based on the Haskell and Agda Lexer. |
188 Based on the Haskell and Agda Lexer. |
172 |
196 |
173 reserved = ('case', 'class', 'data', 'default', 'using', 'do', 'else', |
197 reserved = ('case', 'class', 'data', 'default', 'using', 'do', 'else', |
174 'if', 'in', 'infix[lr]?', 'instance', 'rewrite', 'auto', |
198 'if', 'in', 'infix[lr]?', 'instance', 'rewrite', 'auto', |
175 'namespace', 'codata', 'mutual', 'private', 'public', 'abstract', |
199 'namespace', 'codata', 'mutual', 'private', 'public', 'abstract', |
176 'total', 'partial', |
200 'total', 'partial', |
|
201 'interface', 'implementation', 'export', 'covering', 'constructor', |
177 'let', 'proof', 'of', 'then', 'static', 'where', '_', 'with', |
202 'let', 'proof', 'of', 'then', 'static', 'where', '_', 'with', |
178 'pattern', 'term', 'syntax', 'prefix', |
203 'pattern', 'term', 'syntax', 'prefix', |
179 'postulate', 'parameters', 'record', 'dsl', 'impossible', 'implicit', |
204 'postulate', 'parameters', 'record', 'dsl', 'impossible', 'implicit', |
180 'tactics', 'intros', 'intro', 'compute', 'refine', 'exact', 'trivial') |
205 'tactics', 'intros', 'intro', 'compute', 'refine', 'exact', 'trivial') |
181 |
206 |
188 'default', 'logging', 'dynamic', 'name', 'error_handlers', 'language') |
213 'default', 'logging', 'dynamic', 'name', 'error_handlers', 'language') |
189 |
214 |
190 tokens = { |
215 tokens = { |
191 'root': [ |
216 'root': [ |
192 # Comments |
217 # Comments |
193 (r'^(\s*)(%%%s)' % '|'.join(directives), |
218 (r'^(\s*)(%%(%s))' % '|'.join(directives), |
194 bygroups(Text, Keyword.Reserved)), |
219 bygroups(Text, Keyword.Reserved)), |
195 (r'(\s*)(--(?![!#$%&*+./<=>?@^|_~:\\]).*?)$', bygroups(Text, Comment.Single)), |
220 (r'(\s*)(--(?![!#$%&*+./<=>?@^|_~:\\]).*?)$', bygroups(Text, Comment.Single)), |
196 (r'(\s*)(\|{3}.*?)$', bygroups(Text, Comment.Single)), |
221 (r'(\s*)(\|{3}.*?)$', bygroups(Text, Comment.Single)), |
197 (r'(\s*)(\{-)', bygroups(Text, Comment.Multiline), 'comment'), |
222 (r'(\s*)(\{-)', bygroups(Text, Comment.Multiline), 'comment'), |
198 # Declaration |
223 # Declaration |
300 (r'\{!', Comment.Directive, 'hole'), |
325 (r'\{!', Comment.Directive, 'hole'), |
301 # Lexemes: |
326 # Lexemes: |
302 # Identifiers |
327 # Identifiers |
303 (r'\b(%s)(?!\')\b' % '|'.join(reserved), Keyword.Reserved), |
328 (r'\b(%s)(?!\')\b' % '|'.join(reserved), Keyword.Reserved), |
304 (r'(import|module)(\s+)', bygroups(Keyword.Reserved, Text), 'module'), |
329 (r'(import|module)(\s+)', bygroups(Keyword.Reserved, Text), 'module'), |
305 (r'\b(Set|Prop)\b', Keyword.Type), |
330 (u'\\b(Set|Prop)[\u2080-\u2089]*\\b', Keyword.Type), |
306 # Special Symbols |
331 # Special Symbols |
307 (r'(\(|\)|\{|\})', Operator), |
332 (r'(\(|\)|\{|\})', Operator), |
308 (u'(\\.{1,3}|\\||\u039B|\u2200|\u2192|:|=|->)', Operator.Word), |
333 (u'(\\.{1,3}|\\||\u03BB|\u2200|\u2192|:|=|->)', Operator.Word), |
309 # Numbers |
334 # Numbers |
310 (r'\d+[eE][+-]?\d+', Number.Float), |
335 (r'\d+[eE][+-]?\d+', Number.Float), |
311 (r'\d+\.\d+([eE][+-]?\d+)?', Number.Float), |
336 (r'\d+\.\d+([eE][+-]?\d+)?', Number.Float), |
312 (r'0[xX][\da-fA-F]+', Number.Hex), |
337 (r'0[xX][\da-fA-F]+', Number.Hex), |
313 (r'\d+', Number.Integer), |
338 (r'\d+', Number.Integer), |
419 'funclist': [ |
444 'funclist': [ |
420 (r'\s+', Text), |
445 (r'\s+', Text), |
421 (r'[A-Z]\w*', Keyword.Type), |
446 (r'[A-Z]\w*', Keyword.Type), |
422 (r'(_[\w\']+|[a-z][\w\']*)', Name.Function), |
447 (r'(_[\w\']+|[a-z][\w\']*)', Name.Function), |
423 # TODO: these don't match the comments in docs, remove. |
448 # TODO: these don't match the comments in docs, remove. |
424 #(r'--(?![!#$%&*+./<=>?@^|_~:\\]).*?$', Comment.Single), |
449 # (r'--(?![!#$%&*+./<=>?@^|_~:\\]).*?$', Comment.Single), |
425 #(r'{-', Comment.Multiline, 'comment'), |
450 # (r'{-', Comment.Multiline, 'comment'), |
426 (r',', Punctuation), |
451 (r',', Punctuation), |
427 (r'[:!#$%&*+.\\/<=>?@^|~-]+', Operator), |
452 (r'[:!#$%&*+.\\/<=>?@^|~-]+', Operator), |
428 # (HACK, but it makes sense to push two instances, believe me) |
453 # (HACK, but it makes sense to push two instances, believe me) |
429 (r'\(', Punctuation, ('funclist', 'funclist')), |
454 (r'\(', Punctuation, ('funclist', 'funclist')), |
430 (r'\)', Punctuation, '#pop:2'), |
455 (r'\)', Punctuation, '#pop:2'), |
456 (r'\d+', String.Escape, '#pop'), |
481 (r'\d+', String.Escape, '#pop'), |
457 (r'\s+\\', String.Escape, '#pop'), |
482 (r'\s+\\', String.Escape, '#pop'), |
458 ], |
483 ], |
459 } |
484 } |
460 |
485 |
461 EXTRA_KEYWORDS = set(('join', 'split', 'reverse', 'transpose', 'width', |
486 EXTRA_KEYWORDS = {'join', 'split', 'reverse', 'transpose', 'width', |
462 'length', 'tail', '<<', '>>', '<<<', '>>>', 'const', |
487 'length', 'tail', '<<', '>>', '<<<', '>>>', 'const', |
463 'reg', 'par', 'seq', 'ASSERT', 'undefined', 'error', |
488 'reg', 'par', 'seq', 'ASSERT', 'undefined', 'error', |
464 'trace')) |
489 'trace'} |
465 |
490 |
466 def get_tokens_unprocessed(self, text): |
491 def get_tokens_unprocessed(self, text): |
467 stack = ['root'] |
492 stack = ['root'] |
468 for index, token, value in \ |
493 for index, token, value in \ |
469 RegexLexer.get_tokens_unprocessed(self, text, stack): |
494 RegexLexer.get_tokens_unprocessed(self, text, stack): |