1
# -*- coding: utf-8 -*-
3
pygments.lexers.functional
4
~~~~~~~~~~~~~~~~~~~~~~~~~~
6
Lexers for functional languages.
8
:copyright: Copyright 2006-2010 by the Pygments team, see AUTHORS.
9
:license: BSD, see LICENSE for details.
14
from pygments.lexer import Lexer, RegexLexer, bygroups, include, do_insertions
15
from pygments.token import Text, Comment, Operator, Keyword, Name, \
16
String, Number, Punctuation, Literal, Generic
19
__all__ = ['SchemeLexer', 'CommonLispLexer', 'HaskellLexer', 'LiterateHaskellLexer',
20
'OcamlLexer', 'ErlangLexer', 'ErlangShellLexer']
23
class SchemeLexer(RegexLexer):
25
A Scheme lexer, parsing a stream and outputting the tokens
26
needed to highlight scheme code.
27
This lexer could be most probably easily subclassed to parse
28
other LISP-Dialects like Common Lisp, Emacs Lisp or AutoLisp.
30
This parser is checked with pastes from the LISP pastebin
31
at http://paste.lisp.org/ to cover as much syntax as possible.
33
It supports the full Scheme syntax as defined in R5RS.
35
*New in Pygments 0.6.*
38
aliases = ['scheme', 'scm']
40
mimetypes = ['text/x-scheme', 'application/x-scheme']
42
# list of known keywords and builtins taken form vim 6.4 scheme.vim
45
'lambda', 'define', 'if', 'else', 'cond', 'and', 'or', 'case', 'let',
46
'let*', 'letrec', 'begin', 'do', 'delay', 'set!', '=>', 'quote',
47
'quasiquote', 'unquote', 'unquote-splicing', 'define-syntax',
48
'let-syntax', 'letrec-syntax', 'syntax-rules'
51
'*', '+', '-', '/', '<', '<=', '=', '>', '>=', 'abs', 'acos', 'angle',
52
'append', 'apply', 'asin', 'assoc', 'assq', 'assv', 'atan',
53
'boolean?', 'caaaar', 'caaadr', 'caaar', 'caadar', 'caaddr', 'caadr',
54
'caar', 'cadaar', 'cadadr', 'cadar', 'caddar', 'cadddr', 'caddr',
55
'cadr', 'call-with-current-continuation', 'call-with-input-file',
56
'call-with-output-file', 'call-with-values', 'call/cc', 'car',
57
'cdaaar', 'cdaadr', 'cdaar', 'cdadar', 'cdaddr', 'cdadr', 'cdar',
58
'cddaar', 'cddadr', 'cddar', 'cdddar', 'cddddr', 'cdddr', 'cddr',
59
'cdr', 'ceiling', 'char->integer', 'char-alphabetic?', 'char-ci<=?',
60
'char-ci<?', 'char-ci=?', 'char-ci>=?', 'char-ci>?', 'char-downcase',
61
'char-lower-case?', 'char-numeric?', 'char-ready?', 'char-upcase',
62
'char-upper-case?', 'char-whitespace?', 'char<=?', 'char<?', 'char=?',
63
'char>=?', 'char>?', 'char?', 'close-input-port', 'close-output-port',
64
'complex?', 'cons', 'cos', 'current-input-port', 'current-output-port',
65
'denominator', 'display', 'dynamic-wind', 'eof-object?', 'eq?',
66
'equal?', 'eqv?', 'eval', 'even?', 'exact->inexact', 'exact?', 'exp',
67
'expt', 'floor', 'for-each', 'force', 'gcd', 'imag-part',
68
'inexact->exact', 'inexact?', 'input-port?', 'integer->char',
69
'integer?', 'interaction-environment', 'lcm', 'length', 'list',
70
'list->string', 'list->vector', 'list-ref', 'list-tail', 'list?',
71
'load', 'log', 'magnitude', 'make-polar', 'make-rectangular',
72
'make-string', 'make-vector', 'map', 'max', 'member', 'memq', 'memv',
73
'min', 'modulo', 'negative?', 'newline', 'not', 'null-environment',
74
'null?', 'number->string', 'number?', 'numerator', 'odd?',
75
'open-input-file', 'open-output-file', 'output-port?', 'pair?',
76
'peek-char', 'port?', 'positive?', 'procedure?', 'quotient',
77
'rational?', 'rationalize', 'read', 'read-char', 'real-part', 'real?',
78
'remainder', 'reverse', 'round', 'scheme-report-environment',
79
'set-car!', 'set-cdr!', 'sin', 'sqrt', 'string', 'string->list',
80
'string->number', 'string->symbol', 'string-append', 'string-ci<=?',
81
'string-ci<?', 'string-ci=?', 'string-ci>=?', 'string-ci>?',
82
'string-copy', 'string-fill!', 'string-length', 'string-ref',
83
'string-set!', 'string<=?', 'string<?', 'string=?', 'string>=?',
84
'string>?', 'string?', 'substring', 'symbol->string', 'symbol?',
85
'tan', 'transcript-off', 'transcript-on', 'truncate', 'values',
86
'vector', 'vector->list', 'vector-fill!', 'vector-length',
87
'vector-ref', 'vector-set!', 'vector?', 'with-input-from-file',
88
'with-output-to-file', 'write', 'write-char', 'zero?'
91
# valid names for identifiers
92
# well, names can only not consist fully of numbers
93
# but this should be good enough for now
94
valid_name = r'[a-zA-Z0-9!$%&*+,/:<=>?@^_~|-]+'
98
# the comments - always starting with semicolon
99
# and going to the end of the line
100
(r';.*$', Comment.Single),
102
# whitespaces - usually not relevant
106
(r'-?\d+\.\d+', Number.Float),
107
(r'-?\d+', Number.Integer),
108
# support for uncommon kinds of numbers -
109
# have to figure out what the characters mean
110
#(r'(#e|#i|#b|#o|#d|#x)[\d.]+', Number),
112
# strings, symbols and characters
113
(r'"(\\\\|\\"|[^"])*"', String),
114
(r"'" + valid_name, String.Symbol),
115
(r"#\\([()/'\".'_!Ā§$%& ?=+-]{1}|[a-zA-Z0-9]+)", String.Char),
118
(r'(#t|#f)', Name.Constant),
121
(r"('|#|`|,@|,|\.)", Operator),
123
# highlight the keywords
125
re.escape(entry) + ' ' for entry in keywords]),
129
# first variable in a quoted string like
130
# '(this is syntactic sugar)
131
(r"(?<='\()" + valid_name, Name.Variable),
132
(r"(?<=#\()" + valid_name, Name.Variable),
134
# highlight the builtins
135
("(?<=\()(%s)" % '|'.join([
136
re.escape(entry) + ' ' for entry in builtins]),
140
# the remaining functions
141
(r'(?<=\()' + valid_name, Name.Function),
142
# find the remaining variables
143
(valid_name, Name.Variable),
145
# the famous parentheses!
146
(r'(\(|\))', Punctuation),
151
class CommonLispLexer(RegexLexer):
155
*New in Pygments 0.9.*
158
aliases = ['common-lisp', 'cl']
159
filenames = ['*.cl', '*.lisp', '*.el'] # use for Elisp too
160
mimetypes = ['text/x-common-lisp']
162
flags = re.IGNORECASE | re.MULTILINE
164
### couple of useful regexes
166
# characters that are not macro-characters and can be used to begin a symbol
167
nonmacro = r'\\.|[a-zA-Z0-9!$%&*+-/<=>?@\[\]^_{}~]'
168
constituent = nonmacro + '|[#.:]'
169
terminated = r'(?=[ "()\'\n,;`])' # whitespace or terminating macro characters
171
### symbol token, reverse-engineered from hyperspec
172
# Take a deep breath...
173
symbol = r'(\|[^|]+\||(?:%s)(?:%s)*)' % (nonmacro, constituent)
175
def __init__(self, **options):
176
from pygments.lexers._clbuiltins import BUILTIN_FUNCTIONS, \
177
SPECIAL_FORMS, MACROS, LAMBDA_LIST_KEYWORDS, DECLARATIONS, \
178
BUILTIN_TYPES, BUILTIN_CLASSES
179
self.builtin_function = BUILTIN_FUNCTIONS
180
self.special_forms = SPECIAL_FORMS
182
self.lambda_list_keywords = LAMBDA_LIST_KEYWORDS
183
self.declarations = DECLARATIONS
184
self.builtin_types = BUILTIN_TYPES
185
self.builtin_classes = BUILTIN_CLASSES
186
RegexLexer.__init__(self, **options)
188
def get_tokens_unprocessed(self, text):
190
for index, token, value in RegexLexer.get_tokens_unprocessed(self, text, stack):
191
if token is Name.Variable:
192
if value in self.builtin_function:
193
yield index, Name.Builtin, value
195
if value in self.special_forms:
196
yield index, Keyword, value
198
if value in self.macros:
199
yield index, Name.Builtin, value
201
if value in self.lambda_list_keywords:
202
yield index, Keyword, value
204
if value in self.declarations:
205
yield index, Keyword, value
207
if value in self.builtin_types:
208
yield index, Keyword.Type, value
210
if value in self.builtin_classes:
211
yield index, Name.Class, value
213
yield index, token, value
219
'multiline-comment' : [
220
(r'#\|', Comment.Multiline, '#push'), # (cf. Hyperspec 2.4.8.19)
221
(r'\|#', Comment.Multiline, '#pop'),
222
(r'[^|#]+', Comment.Multiline),
223
(r'[|#]', Comment.Multiline),
226
(r'\(', Comment.Preproc, '#push'),
227
(r'\)', Comment.Preproc, '#pop'),
228
(r'[^()]+', Comment.Preproc),
234
# single-line comment
235
(r';.*$', Comment.Single),
238
(r'#\|', Comment.Multiline, 'multiline-comment'),
240
# encoding comment (?)
241
(r'#\d*Y.*$', Comment.Special),
243
# strings and characters
244
(r'"(\\.|[^"\\])*"', String),
246
(r":" + symbol, String.Symbol),
247
(r"'" + symbol, String.Symbol),
252
(r'[-+]?\d+\.?' + terminated, Number.Integer),
253
(r'[-+]?\d+/\d+' + terminated, Number),
254
(r'[-+]?(\d*\.\d+([defls][-+]?\d+)?|\d+(\.\d*)?[defls][-+]?\d+)' \
255
+ terminated, Number.Float),
257
# sharpsign strings and characters
258
(r"#\\." + terminated, String.Char),
259
(r"#\\" + symbol, String.Char),
262
(r'#\(', Operator, 'body'),
265
(r'#\d*\*[01]*', Literal.Other),
268
(r'#:' + symbol, String.Symbol),
270
# read-time and load-time evaluation
271
(r'#[.,]', Operator),
274
(r'#\'', Name.Function),
277
(r'#[bB][+-]?[01]+(/[01]+)?', Number),
280
(r'#[oO][+-]?[0-7]+(/[0-7]+)?', Number.Oct),
283
(r'#[xX][+-]?[0-9a-fA-F]+(/[0-9a-fA-F]+)?', Number.Hex),
286
(r'#\d+[rR][+-]?[0-9a-zA-Z]+(/[0-9a-zA-Z]+)?', Number),
289
(r'(#[cC])(\()', bygroups(Number, Punctuation), 'body'),
292
(r'(#\d+[aA])(\()', bygroups(Literal.Other, Punctuation), 'body'),
295
(r'(#[sS])(\()', bygroups(Literal.Other, Punctuation), 'body'),
298
(r'#[pP]?"(\\.|[^"])*"', Literal.Other),
301
(r'#\d+=', Operator),
302
(r'#\d+#', Operator),
305
(r'#+nil' + terminated + '\s*\(', Comment.Preproc, 'commented-form'),
307
# read-time conditional
308
(r'#[+-]', Operator),
310
# special operators that should have been parsed already
311
(r'(,@|,|\.)', Operator),
314
(r'(t|nil)' + terminated, Name.Constant),
316
# functions and variables
317
(r'\*' + symbol + '\*', Name.Variable.Global),
318
(symbol, Name.Variable),
321
(r'\(', Punctuation, 'body'),
322
(r'\)', Punctuation, '#pop'),
327
class HaskellLexer(RegexLexer):
329
A Haskell lexer based on the lexemes defined in the Haskell 98 Report.
331
*New in Pygments 0.8.*
334
aliases = ['haskell', 'hs']
336
mimetypes = ['text/x-haskell']
338
reserved = ['case','class','data','default','deriving','do','else',
339
'if','in','infix[lr]?','instance',
340
'let','newtype','of','then','type','where','_']
341
ascii = ['NUL','SOH','[SE]TX','EOT','ENQ','ACK',
342
'BEL','BS','HT','LF','VT','FF','CR','S[OI]','DLE',
343
'DC[1-4]','NAK','SYN','ETB','CAN',
344
'EM','SUB','ESC','[FGRU]S','SP','DEL']
350
#(r'--\s*|.*$', Comment.Doc),
351
(r'--(?![!#$%&*+./<=>?@\^|_~]).*?$', Comment.Single),
352
(r'{-', Comment.Multiline, 'comment'),
355
(r'\bimport\b', Keyword.Reserved, 'import'),
356
(r'\bmodule\b', Keyword.Reserved, 'module'),
357
(r'\berror\b', Name.Exception),
358
(r'\b(%s)(?!\')\b' % '|'.join(reserved), Keyword.Reserved),
359
(r'^[_a-z][\w\']*', Name.Function),
360
(r'[_a-z][\w\']*', Name),
361
(r'[A-Z][\w\']*', Keyword.Type),
363
(r'\\(?![:!#$%&*+.\\/<=>?@^|~-]+)', Name.Function), # lambda operator
364
(r'(<-|::|->|=>|=)(?![:!#$%&*+.\\/<=>?@^|~-]+)', Operator.Word), # specials
365
(r':[:!#$%&*+.\\/<=>?@^|~-]*', Keyword.Type), # Constructor operators
366
(r'[:!#$%&*+.\\/<=>?@^|~-]+', Operator), # Other operators
368
(r'\d+[eE][+-]?\d+', Number.Float),
369
(r'\d+\.\d+([eE][+-]?\d+)?', Number.Float),
370
(r'0[oO][0-7]+', Number.Oct),
371
(r'0[xX][\da-fA-F]+', Number.Hex),
372
(r'\d+', Number.Integer),
373
# Character/String Literals
374
(r"'", String.Char, 'character'),
375
(r'"', String, 'string'),
377
(r'\[\]', Keyword.Type),
378
(r'\(\)', Name.Builtin),
379
(r'[][(),;`{}]', Punctuation),
384
# after "funclist" state
385
(r'\)', Punctuation, '#pop'),
386
(r'qualified\b', Keyword),
388
(r'([A-Z][a-zA-Z0-9_.]*)(\s+)(as)(\s+)([A-Z][a-zA-Z0-9_.]*)',
389
bygroups(Name.Namespace, Text, Keyword, Text, Name), '#pop'),
390
# import X hiding (functions)
391
(r'([A-Z][a-zA-Z0-9_.]*)(\s+)(hiding)(\s+)(\()',
392
bygroups(Name.Namespace, Text, Keyword, Text, Punctuation), 'funclist'),
393
# import X (functions)
394
(r'([A-Z][a-zA-Z0-9_.]*)(\s+)(\()',
395
bygroups(Name.Namespace, Text, Punctuation), 'funclist'),
397
(r'[a-zA-Z0-9_.]+', Name.Namespace, '#pop'),
401
(r'([A-Z][a-zA-Z0-9_.]*)(\s+)(\()',
402
bygroups(Name.Namespace, Text, Punctuation), 'funclist'),
403
(r'[A-Z][a-zA-Z0-9_.]*', Name.Namespace, '#pop'),
407
(r'[A-Z][a-zA-Z0-9_]*', Keyword.Type),
408
(r'[_a-z][\w\']+', Name.Function),
409
(r'--.*$', Comment.Single),
410
(r'{-', Comment.Multiline, 'comment'),
412
(r'[:!#$%&*+.\\/<=>?@^|~-]+', Operator),
413
# (HACK, but it makes sense to push two instances, believe me)
414
(r'\(', Punctuation, ('funclist', 'funclist')),
415
(r'\)', Punctuation, '#pop:2'),
419
(r'[^-{}]+', Comment.Multiline),
420
(r'{-', Comment.Multiline, '#push'),
421
(r'-}', Comment.Multiline, '#pop'),
422
(r'[-{}]', Comment.Multiline),
425
# Allows multi-chars, incorrectly.
426
(r"[^\\']", String.Char),
427
(r"\\", String.Escape, 'escape'),
428
("'", String.Char, '#pop'),
431
(r'[^\\"]+', String),
432
(r"\\", String.Escape, 'escape'),
433
('"', String, '#pop'),
436
(r'[abfnrtv"\'&\\]', String.Escape, '#pop'),
437
(r'\^[][A-Z@\^_]', String.Escape, '#pop'),
438
('|'.join(ascii), String.Escape, '#pop'),
439
(r'o[0-7]+', String.Escape, '#pop'),
440
(r'x[\da-fA-F]+', String.Escape, '#pop'),
441
(r'\d+', String.Escape, '#pop'),
442
(r'\s+\\', String.Escape, '#pop'),
447
line_re = re.compile('.*?\n')
448
bird_re = re.compile(r'(>[ \t]*)(.*\n)')
450
class LiterateHaskellLexer(Lexer):
452
For Literate Haskell (Bird-style or LaTeX) source.
454
Additional options accepted:
457
If given, must be ``"bird"`` or ``"latex"``. If not given, the style
458
is autodetected: if the first non-whitespace character in the source
459
is a backslash or percent character, LaTeX is assumed, else Bird.
461
*New in Pygments 0.9.*
463
name = 'Literate Haskell'
464
aliases = ['lhs', 'literate-haskell']
465
filenames = ['*.lhs']
466
mimetypes = ['text/x-literate-haskell']
468
def get_tokens_unprocessed(self, text):
469
hslexer = HaskellLexer(**self.options)
471
style = self.options.get('litstyle')
473
style = (text.lstrip()[0:1] in '%\\') and 'latex' or 'bird'
479
for match in line_re.finditer(text):
481
m = bird_re.match(line)
483
insertions.append((len(code),
484
[(0, Comment.Special, m.group(1))]))
487
insertions.append((len(code), [(0, Text, line)]))
490
from pygments.lexers.text import TexLexer
491
lxlexer = TexLexer(**self.options)
495
for match in line_re.finditer(text):
498
if line.lstrip().startswith('\\end{code}'):
503
elif line.lstrip().startswith('\\begin{code}'):
506
insertions.append((len(code),
507
list(lxlexer.get_tokens_unprocessed(latex))))
511
insertions.append((len(code),
512
list(lxlexer.get_tokens_unprocessed(latex))))
513
for item in do_insertions(insertions, hslexer.get_tokens_unprocessed(code)):
517
class OcamlLexer(RegexLexer):
519
For the OCaml language.
521
*New in Pygments 0.7.*
526
filenames = ['*.ml', '*.mli', '*.mll', '*.mly']
527
mimetypes = ['text/x-ocaml']
530
'as', 'assert', 'begin', 'class', 'constraint', 'do', 'done',
531
'downto', 'else', 'end', 'exception', 'external', 'false',
532
'for', 'fun', 'function', 'functor', 'if', 'in', 'include',
533
'inherit', 'initializer', 'lazy', 'let', 'match', 'method',
534
'module', 'mutable', 'new', 'object', 'of', 'open', 'private',
535
'raise', 'rec', 'sig', 'struct', 'then', 'to', 'true', 'try',
536
'type', 'val', 'virtual', 'when', 'while', 'with'
539
'!=','#','&','&&','\(','\)','\*','\+',',','-',
540
'-\.','->','\.','\.\.',':','::',':=',':>',';',';;','<',
541
'<-','=','>','>]','>}','\?','\?\?','\[','\[<','\[>','\[\|',
542
']','_','`','{','{<','\|','\|]','}','~'
545
operators = r'[!$%&*+\./:<=>?@^|~-]'
546
word_operators = ['and', 'asr', 'land', 'lor', 'lsl', 'lxor', 'mod', 'or']
547
prefix_syms = r'[!?~]'
548
infix_syms = r'[=<>@^|&+\*/$%-]'
549
primitives = ['unit', 'int', 'float', 'bool', 'string', 'char', 'list', 'array']
553
(r'\\[\"\'ntbr]', String.Escape),
554
(r'\\[0-9]{3}', String.Escape),
555
(r'\\x[0-9a-fA-F]{2}', String.Escape),
559
(r'false|true|\(\)|\[\]', Name.Builtin.Pseudo),
560
(r'\b([A-Z][A-Za-z0-9_\']*)(?=\s*\.)',
561
Name.Namespace, 'dotted'),
562
(r'\b([A-Z][A-Za-z0-9_\']*)', Name.Class),
563
(r'\(\*', Comment, 'comment'),
564
(r'\b(%s)\b' % '|'.join(keywords), Keyword),
565
(r'(%s)' % '|'.join(keyopts), Operator),
566
(r'(%s|%s)?%s' % (infix_syms, prefix_syms, operators), Operator),
567
(r'\b(%s)\b' % '|'.join(word_operators), Operator.Word),
568
(r'\b(%s)\b' % '|'.join(primitives), Keyword.Type),
570
(r"[^\W\d][\w']*", Name),
572
(r'\d[\d_]*', Number.Integer),
573
(r'0[xX][\da-fA-F][\da-fA-F_]*', Number.Hex),
574
(r'0[oO][0-7][0-7_]*', Number.Oct),
575
(r'0[bB][01][01_]*', Number.Binary),
576
(r'-?\d[\d_]*(.[\d_]*)?([eE][+\-]?\d[\d_]*)', Number.Float),
578
(r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2}))'",
580
(r"'.'", String.Char),
581
(r"'", Keyword), # a stray quote is another syntax element
583
(r'"', String.Double, 'string'),
585
(r'[~?][a-z][\w\']*:', Name.Variable),
588
(r'[^(*)]+', Comment),
589
(r'\(\*', Comment, '#push'),
590
(r'\*\)', Comment, '#pop'),
594
(r'[^\\"]+', String.Double),
595
include('escape-sequence'),
596
(r'\\\n', String.Double),
597
(r'"', String.Double, '#pop'),
601
(r'\.', Punctuation),
602
(r'[A-Z][A-Za-z0-9_\']*(?=\s*\.)', Name.Namespace),
603
(r'[A-Z][A-Za-z0-9_\']*', Name.Class, '#pop'),
604
(r'[a-z][a-z0-9_\']*', Name, '#pop'),
609
class ErlangLexer(RegexLexer):
611
For the Erlang functional programming language.
613
Blame Jeremy Thurgood (http://jerith.za.net/).
615
*New in Pygments 0.9.*
620
filenames = ['*.erl', '*.hrl']
621
mimetypes = ['text/x-erlang']
624
'after', 'begin', 'case', 'catch', 'cond', 'end', 'fun', 'if',
625
'let', 'of', 'query', 'receive', 'try', 'when',
628
builtins = [ # See erlang(3) man page
629
'abs', 'append_element', 'apply', 'atom_to_list', 'binary_to_list',
630
'bitstring_to_list', 'binary_to_term', 'bit_size', 'bump_reductions',
631
'byte_size', 'cancel_timer', 'check_process_code', 'delete_module',
632
'demonitor', 'disconnect_node', 'display', 'element', 'erase', 'exit',
633
'float', 'float_to_list', 'fun_info', 'fun_to_list',
634
'function_exported', 'garbage_collect', 'get', 'get_keys',
635
'group_leader', 'hash', 'hd', 'integer_to_list', 'iolist_to_binary',
636
'iolist_size', 'is_atom', 'is_binary', 'is_bitstring', 'is_boolean',
637
'is_builtin', 'is_float', 'is_function', 'is_integer', 'is_list',
638
'is_number', 'is_pid', 'is_port', 'is_process_alive', 'is_record',
639
'is_reference', 'is_tuple', 'length', 'link', 'list_to_atom',
640
'list_to_binary', 'list_to_bitstring', 'list_to_existing_atom',
641
'list_to_float', 'list_to_integer', 'list_to_pid', 'list_to_tuple',
642
'load_module', 'localtime_to_universaltime', 'make_tuple', 'md5',
643
'md5_final', 'md5_update', 'memory', 'module_loaded', 'monitor',
644
'monitor_node', 'node', 'nodes', 'open_port', 'phash', 'phash2',
645
'pid_to_list', 'port_close', 'port_command', 'port_connect',
646
'port_control', 'port_call', 'port_info', 'port_to_list',
647
'process_display', 'process_flag', 'process_info', 'purge_module',
648
'put', 'read_timer', 'ref_to_list', 'register', 'resume_process',
649
'round', 'send', 'send_after', 'send_nosuspend', 'set_cookie',
650
'setelement', 'size', 'spawn', 'spawn_link', 'spawn_monitor',
651
'spawn_opt', 'split_binary', 'start_timer', 'statistics',
652
'suspend_process', 'system_flag', 'system_info', 'system_monitor',
653
'system_profile', 'term_to_binary', 'tl', 'trace', 'trace_delivered',
654
'trace_info', 'trace_pattern', 'trunc', 'tuple_size', 'tuple_to_list',
655
'universaltime_to_localtime', 'unlink', 'unregister', 'whereis'
658
operators = r'(\+|-|\*|/|<|>|=|==|/=|=:=|=/=|=<|>=|\+\+|--|<-|!)'
660
'and', 'andalso', 'band', 'bnot', 'bor', 'bsl', 'bsr', 'bxor',
661
'div', 'not', 'or', 'orelse', 'rem', 'xor'
664
atom_re = r"(?:[a-z][a-zA-Z0-9_]*|'[^\n']*[^\\]')"
666
variable_re = r'(?:[A-Z_][a-zA-Z0-9_]*)'
668
escape_re = r'(?:\\(?:[bdefnrstv\'"\\/]|[0-7][0-7]?[0-7]?|\^[a-zA-Z]))'
670
macro_re = r'(?:'+variable_re+r'|'+atom_re+r')'
672
base_re = r'(?:[2-9]|[12][0-9]|3[0-6])'
678
('(' + '|'.join(keywords) + r')\b', Keyword),
679
('(' + '|'.join(builtins) + r')\b', Name.Builtin),
680
('(' + '|'.join(word_operators) + r')\b', Operator.Word),
681
(r'^-', Punctuation, 'directive'),
682
(operators, Operator),
683
(r'"', String, 'string'),
686
(r'('+atom_re+')(:)', bygroups(Name.Namespace, Punctuation)),
687
(r'^('+atom_re+r')(\s*)(\()', bygroups(Name.Function, Text, Punctuation)),
688
(r'[+-]?'+base_re+r'#[0-9a-zA-Z]+', Number.Integer),
689
(r'[+-]?\d+', Number.Integer),
690
(r'[+-]?\d+.\d+', Number.Float),
691
(r'[][:_@\".{}()|;,]', Punctuation),
692
(variable_re, Name.Variable),
694
(r'\?'+macro_re, Name.Constant),
695
(r'\$(?:'+escape_re+r'|\\[ %]|[^\\])', String.Char),
696
(r'#'+atom_re+r'(:?\.'+atom_re+r')?', Name.Label),
699
(escape_re, String.Escape),
700
(r'"', String, '#pop'),
701
(r'~[0-9.*]*[~#+bBcdefginpPswWxX]', String.Interpol),
702
(r'[^"\\~]+', String),
706
(r'(define)(\s*)(\()('+macro_re+r')',
707
bygroups(Name.Entity, Text, Punctuation, Name.Constant), '#pop'),
708
(r'(record)(\s*)(\()('+macro_re+r')',
709
bygroups(Name.Entity, Text, Punctuation, Name.Label), '#pop'),
710
(atom_re, Name.Entity, '#pop'),
715
class ErlangShellLexer(Lexer):
717
Shell sessions in erl (for Erlang code).
719
*New in Pygments 1.1.*
721
name = 'Erlang erl session'
723
filenames = ['*.erl-sh']
724
mimetypes = ['text/x-erl-shellsession']
726
_prompt_re = re.compile(r'\d+>(?=\s|\Z)')
728
def get_tokens_unprocessed(self, text):
729
erlexer = ErlangLexer(**self.options)
733
for match in line_re.finditer(text):
735
m = self._prompt_re.match(line)
738
insertions.append((len(curcode),
739
[(0, Generic.Prompt, line[:end])]))
740
curcode += line[end:]
743
for item in do_insertions(insertions,
744
erlexer.get_tokens_unprocessed(curcode)):
748
if line.startswith('*'):
749
yield match.start(), Generic.Traceback, line
751
yield match.start(), Generic.Output, line
753
for item in do_insertions(insertions,
754
erlexer.get_tokens_unprocessed(curcode)):