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
(r'"', String, 'string'),
385
# after "funclist" state
386
(r'\)', Punctuation, '#pop'),
387
(r'qualified\b', Keyword),
389
(r'([A-Z][a-zA-Z0-9_.]*)(\s+)(as)(\s+)([A-Z][a-zA-Z0-9_.]*)',
390
bygroups(Name.Namespace, Text, Keyword, Text, Name), '#pop'),
391
# import X hiding (functions)
392
(r'([A-Z][a-zA-Z0-9_.]*)(\s+)(hiding)(\s+)(\()',
393
bygroups(Name.Namespace, Text, Keyword, Text, Punctuation), 'funclist'),
394
# import X (functions)
395
(r'([A-Z][a-zA-Z0-9_.]*)(\s+)(\()',
396
bygroups(Name.Namespace, Text, Punctuation), 'funclist'),
398
(r'[a-zA-Z0-9_.]+', Name.Namespace, '#pop'),
402
(r'([A-Z][a-zA-Z0-9_.]*)(\s+)(\()',
403
bygroups(Name.Namespace, Text, Punctuation), 'funclist'),
404
(r'[A-Z][a-zA-Z0-9_.]*', Name.Namespace, '#pop'),
408
(r'[A-Z][a-zA-Z0-9_]*', Keyword.Type),
409
(r'[_a-z][\w\']+', Name.Function),
410
(r'--.*$', Comment.Single),
411
(r'{-', Comment.Multiline, 'comment'),
413
(r'[:!#$%&*+.\\/<=>?@^|~-]+', Operator),
414
# (HACK, but it makes sense to push two instances, believe me)
415
(r'\(', Punctuation, ('funclist', 'funclist')),
416
(r'\)', Punctuation, '#pop:2'),
420
(r'[^-{}]+', Comment.Multiline),
421
(r'{-', Comment.Multiline, '#push'),
422
(r'-}', Comment.Multiline, '#pop'),
423
(r'[-{}]', Comment.Multiline),
426
# Allows multi-chars, incorrectly.
427
(r"[^\\']", String.Char),
428
(r"\\", String.Escape, 'escape'),
429
("'", String.Char, '#pop'),
432
(r'[^\\"]+', String),
433
(r"\\", String.Escape, 'escape'),
434
('"', String, '#pop'),
437
(r'[abfnrtv"\'&\\]', String.Escape, '#pop'),
438
(r'\^[][A-Z@\^_]', String.Escape, '#pop'),
439
('|'.join(ascii), String.Escape, '#pop'),
440
(r'o[0-7]+', String.Escape, '#pop'),
441
(r'x[\da-fA-F]+', String.Escape, '#pop'),
442
(r'\d+', String.Escape, '#pop'),
443
(r'\s+\\', String.Escape, '#pop'),
448
line_re = re.compile('.*?\n')
449
bird_re = re.compile(r'(>[ \t]*)(.*\n)')
451
class LiterateHaskellLexer(Lexer):
453
For Literate Haskell (Bird-style or LaTeX) source.
455
Additional options accepted:
458
If given, must be ``"bird"`` or ``"latex"``. If not given, the style
459
is autodetected: if the first non-whitespace character in the source
460
is a backslash or percent character, LaTeX is assumed, else Bird.
462
*New in Pygments 0.9.*
464
name = 'Literate Haskell'
465
aliases = ['lhs', 'literate-haskell']
466
filenames = ['*.lhs']
467
mimetypes = ['text/x-literate-haskell']
469
def get_tokens_unprocessed(self, text):
470
hslexer = HaskellLexer(**self.options)
472
style = self.options.get('litstyle')
474
style = (text.lstrip()[0:1] in '%\\') and 'latex' or 'bird'
480
for match in line_re.finditer(text):
482
m = bird_re.match(line)
484
insertions.append((len(code),
485
[(0, Comment.Special, m.group(1))]))
488
insertions.append((len(code), [(0, Text, line)]))
491
from pygments.lexers.text import TexLexer
492
lxlexer = TexLexer(**self.options)
496
for match in line_re.finditer(text):
499
if line.lstrip().startswith('\\end{code}'):
504
elif line.lstrip().startswith('\\begin{code}'):
507
insertions.append((len(code),
508
list(lxlexer.get_tokens_unprocessed(latex))))
512
insertions.append((len(code),
513
list(lxlexer.get_tokens_unprocessed(latex))))
514
for item in do_insertions(insertions, hslexer.get_tokens_unprocessed(code)):
518
class OcamlLexer(RegexLexer):
520
For the OCaml language.
522
*New in Pygments 0.7.*
527
filenames = ['*.ml', '*.mli', '*.mll', '*.mly']
528
mimetypes = ['text/x-ocaml']
531
'as', 'assert', 'begin', 'class', 'constraint', 'do', 'done',
532
'downto', 'else', 'end', 'exception', 'external', 'false',
533
'for', 'fun', 'function', 'functor', 'if', 'in', 'include',
534
'inherit', 'initializer', 'lazy', 'let', 'match', 'method',
535
'module', 'mutable', 'new', 'object', 'of', 'open', 'private',
536
'raise', 'rec', 'sig', 'struct', 'then', 'to', 'true', 'try',
537
'type', 'val', 'virtual', 'when', 'while', 'with'
540
'!=','#','&','&&','\(','\)','\*','\+',',','-',
541
'-\.','->','\.','\.\.',':','::',':=',':>',';',';;','<',
542
'<-','=','>','>]','>}','\?','\?\?','\[','\[<','\[>','\[\|',
543
']','_','`','{','{<','\|','\|]','}','~'
546
operators = r'[!$%&*+\./:<=>?@^|~-]'
547
word_operators = ['and', 'asr', 'land', 'lor', 'lsl', 'lxor', 'mod', 'or']
548
prefix_syms = r'[!?~]'
549
infix_syms = r'[=<>@^|&+\*/$%-]'
550
primitives = ['unit', 'int', 'float', 'bool', 'string', 'char', 'list', 'array']
554
(r'\\[\\\"\'ntbr]', String.Escape),
555
(r'\\[0-9]{3}', String.Escape),
556
(r'\\x[0-9a-fA-F]{2}', String.Escape),
560
(r'false|true|\(\)|\[\]', Name.Builtin.Pseudo),
561
(r'\b([A-Z][A-Za-z0-9_\']*)(?=\s*\.)',
562
Name.Namespace, 'dotted'),
563
(r'\b([A-Z][A-Za-z0-9_\']*)', Name.Class),
564
(r'\(\*', Comment, 'comment'),
565
(r'\b(%s)\b' % '|'.join(keywords), Keyword),
566
(r'(%s)' % '|'.join(keyopts), Operator),
567
(r'(%s|%s)?%s' % (infix_syms, prefix_syms, operators), Operator),
568
(r'\b(%s)\b' % '|'.join(word_operators), Operator.Word),
569
(r'\b(%s)\b' % '|'.join(primitives), Keyword.Type),
571
(r"[^\W\d][\w']*", Name),
573
(r'\d[\d_]*', Number.Integer),
574
(r'0[xX][\da-fA-F][\da-fA-F_]*', Number.Hex),
575
(r'0[oO][0-7][0-7_]*', Number.Oct),
576
(r'0[bB][01][01_]*', Number.Binary),
577
(r'-?\d[\d_]*(.[\d_]*)?([eE][+\-]?\d[\d_]*)', Number.Float),
579
(r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2}))'",
581
(r"'.'", String.Char),
582
(r"'", Keyword), # a stray quote is another syntax element
584
(r'"', String.Double, 'string'),
586
(r'[~?][a-z][\w\']*:', Name.Variable),
589
(r'[^(*)]+', Comment),
590
(r'\(\*', Comment, '#push'),
591
(r'\*\)', Comment, '#pop'),
595
(r'[^\\"]+', String.Double),
596
include('escape-sequence'),
597
(r'\\\n', String.Double),
598
(r'"', String.Double, '#pop'),
602
(r'\.', Punctuation),
603
(r'[A-Z][A-Za-z0-9_\']*(?=\s*\.)', Name.Namespace),
604
(r'[A-Z][A-Za-z0-9_\']*', Name.Class, '#pop'),
605
(r'[a-z_][A-Za-z0-9_\']*', Name, '#pop'),
610
class ErlangLexer(RegexLexer):
612
For the Erlang functional programming language.
614
Blame Jeremy Thurgood (http://jerith.za.net/).
616
*New in Pygments 0.9.*
621
filenames = ['*.erl', '*.hrl']
622
mimetypes = ['text/x-erlang']
625
'after', 'begin', 'case', 'catch', 'cond', 'end', 'fun', 'if',
626
'let', 'of', 'query', 'receive', 'try', 'when',
629
builtins = [ # See erlang(3) man page
630
'abs', 'append_element', 'apply', 'atom_to_list', 'binary_to_list',
631
'bitstring_to_list', 'binary_to_term', 'bit_size', 'bump_reductions',
632
'byte_size', 'cancel_timer', 'check_process_code', 'delete_module',
633
'demonitor', 'disconnect_node', 'display', 'element', 'erase', 'exit',
634
'float', 'float_to_list', 'fun_info', 'fun_to_list',
635
'function_exported', 'garbage_collect', 'get', 'get_keys',
636
'group_leader', 'hash', 'hd', 'integer_to_list', 'iolist_to_binary',
637
'iolist_size', 'is_atom', 'is_binary', 'is_bitstring', 'is_boolean',
638
'is_builtin', 'is_float', 'is_function', 'is_integer', 'is_list',
639
'is_number', 'is_pid', 'is_port', 'is_process_alive', 'is_record',
640
'is_reference', 'is_tuple', 'length', 'link', 'list_to_atom',
641
'list_to_binary', 'list_to_bitstring', 'list_to_existing_atom',
642
'list_to_float', 'list_to_integer', 'list_to_pid', 'list_to_tuple',
643
'load_module', 'localtime_to_universaltime', 'make_tuple', 'md5',
644
'md5_final', 'md5_update', 'memory', 'module_loaded', 'monitor',
645
'monitor_node', 'node', 'nodes', 'open_port', 'phash', 'phash2',
646
'pid_to_list', 'port_close', 'port_command', 'port_connect',
647
'port_control', 'port_call', 'port_info', 'port_to_list',
648
'process_display', 'process_flag', 'process_info', 'purge_module',
649
'put', 'read_timer', 'ref_to_list', 'register', 'resume_process',
650
'round', 'send', 'send_after', 'send_nosuspend', 'set_cookie',
651
'setelement', 'size', 'spawn', 'spawn_link', 'spawn_monitor',
652
'spawn_opt', 'split_binary', 'start_timer', 'statistics',
653
'suspend_process', 'system_flag', 'system_info', 'system_monitor',
654
'system_profile', 'term_to_binary', 'tl', 'trace', 'trace_delivered',
655
'trace_info', 'trace_pattern', 'trunc', 'tuple_size', 'tuple_to_list',
656
'universaltime_to_localtime', 'unlink', 'unregister', 'whereis'
659
operators = r'(\+|-|\*|/|<|>|=|==|/=|=:=|=/=|=<|>=|\+\+|--|<-|!)'
661
'and', 'andalso', 'band', 'bnot', 'bor', 'bsl', 'bsr', 'bxor',
662
'div', 'not', 'or', 'orelse', 'rem', 'xor'
665
atom_re = r"(?:[a-z][a-zA-Z0-9_]*|'[^\n']*[^\\]')"
667
variable_re = r'(?:[A-Z_][a-zA-Z0-9_]*)'
669
escape_re = r'(?:\\(?:[bdefnrstv\'"\\/]|[0-7][0-7]?[0-7]?|\^[a-zA-Z]))'
671
macro_re = r'(?:'+variable_re+r'|'+atom_re+r')'
673
base_re = r'(?:[2-9]|[12][0-9]|3[0-6])'
679
('(' + '|'.join(keywords) + r')\b', Keyword),
680
('(' + '|'.join(builtins) + r')\b', Name.Builtin),
681
('(' + '|'.join(word_operators) + r')\b', Operator.Word),
682
(r'^-', Punctuation, 'directive'),
683
(operators, Operator),
684
(r'"', String, 'string'),
687
(r'('+atom_re+')(:)', bygroups(Name.Namespace, Punctuation)),
688
(r'^('+atom_re+r')(\s*)(\()', bygroups(Name.Function, Text, Punctuation)),
689
(r'[+-]?'+base_re+r'#[0-9a-zA-Z]+', Number.Integer),
690
(r'[+-]?\d+', Number.Integer),
691
(r'[+-]?\d+.\d+', Number.Float),
692
(r'[]\[:_@\".{}()|;,]', Punctuation),
693
(variable_re, Name.Variable),
695
(r'\?'+macro_re, Name.Constant),
696
(r'\$(?:'+escape_re+r'|\\[ %]|[^\\])', String.Char),
697
(r'#'+atom_re+r'(:?\.'+atom_re+r')?', Name.Label),
700
(escape_re, String.Escape),
701
(r'"', String, '#pop'),
702
(r'~[0-9.*]*[~#+bBcdefginpPswWxX]', String.Interpol),
703
(r'[^"\\~]+', String),
707
(r'(define)(\s*)(\()('+macro_re+r')',
708
bygroups(Name.Entity, Text, Punctuation, Name.Constant), '#pop'),
709
(r'(record)(\s*)(\()('+macro_re+r')',
710
bygroups(Name.Entity, Text, Punctuation, Name.Label), '#pop'),
711
(atom_re, Name.Entity, '#pop'),
716
class ErlangShellLexer(Lexer):
718
Shell sessions in erl (for Erlang code).
720
*New in Pygments 1.1.*
722
name = 'Erlang erl session'
724
filenames = ['*.erl-sh']
725
mimetypes = ['text/x-erl-shellsession']
727
_prompt_re = re.compile(r'\d+>(?=\s|\Z)')
729
def get_tokens_unprocessed(self, text):
730
erlexer = ErlangLexer(**self.options)
734
for match in line_re.finditer(text):
736
m = self._prompt_re.match(line)
739
insertions.append((len(curcode),
740
[(0, Generic.Prompt, line[:end])]))
741
curcode += line[end:]
744
for item in do_insertions(insertions,
745
erlexer.get_tokens_unprocessed(curcode)):
749
if line.startswith('*'):
750
yield match.start(), Generic.Traceback, line
752
yield match.start(), Generic.Output, line
754
for item in do_insertions(insertions,
755
erlexer.get_tokens_unprocessed(curcode)):