eric6/ThirdParty/Pygments/pygments/lexers/dsls.py

changeset 8258
82b608e352ec
parent 8257
28146736bbfc
child 8259
2bbec88047dd
equal deleted inserted replaced
8257:28146736bbfc 8258:82b608e352ec
1 # -*- coding: utf-8 -*-
2 """
3 pygments.lexers.dsls
4 ~~~~~~~~~~~~~~~~~~~~
5
6 Lexers for various domain-specific languages.
7
8 :copyright: Copyright 2006-2021 by the Pygments team, see AUTHORS.
9 :license: BSD, see LICENSE for details.
10 """
11
12 import re
13
14 from pygments.lexer import ExtendedRegexLexer, RegexLexer, bygroups, words, \
15 include, default, this, using, combined
16 from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
17 Number, Punctuation, Whitespace
18
19 __all__ = ['ProtoBufLexer', 'ZeekLexer', 'PuppetLexer', 'RslLexer',
20 'MscgenLexer', 'VGLLexer', 'AlloyLexer', 'PanLexer',
21 'CrmshLexer', 'ThriftLexer', 'FlatlineLexer', 'SnowballLexer']
22
23
24 class ProtoBufLexer(RegexLexer):
25 """
26 Lexer for `Protocol Buffer <http://code.google.com/p/protobuf/>`_
27 definition files.
28
29 .. versionadded:: 1.4
30 """
31
32 name = 'Protocol Buffer'
33 aliases = ['protobuf', 'proto']
34 filenames = ['*.proto']
35
36 tokens = {
37 'root': [
38 (r'[ \t]+', Text),
39 (r'[,;{}\[\]()<>]', Punctuation),
40 (r'/(\\\n)?/(\n|(.|\n)*?[^\\]\n)', Comment.Single),
41 (r'/(\\\n)?\*(.|\n)*?\*(\\\n)?/', Comment.Multiline),
42 (words((
43 'import', 'option', 'optional', 'required', 'repeated',
44 'reserved', 'default', 'packed', 'ctype', 'extensions', 'to',
45 'max', 'rpc', 'returns', 'oneof', 'syntax'), prefix=r'\b', suffix=r'\b'),
46 Keyword),
47 (words((
48 'int32', 'int64', 'uint32', 'uint64', 'sint32', 'sint64',
49 'fixed32', 'fixed64', 'sfixed32', 'sfixed64',
50 'float', 'double', 'bool', 'string', 'bytes'), suffix=r'\b'),
51 Keyword.Type),
52 (r'(true|false)\b', Keyword.Constant),
53 (r'(package)(\s+)', bygroups(Keyword.Namespace, Text), 'package'),
54 (r'(message|extend)(\s+)',
55 bygroups(Keyword.Declaration, Text), 'message'),
56 (r'(enum|group|service)(\s+)',
57 bygroups(Keyword.Declaration, Text), 'type'),
58 (r'\".*?\"', String),
59 (r'\'.*?\'', String),
60 (r'(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+[LlUu]*', Number.Float),
61 (r'(\d+\.\d*|\.\d+|\d+[fF])[fF]?', Number.Float),
62 (r'(\-?(inf|nan))\b', Number.Float),
63 (r'0x[0-9a-fA-F]+[LlUu]*', Number.Hex),
64 (r'0[0-7]+[LlUu]*', Number.Oct),
65 (r'\d+[LlUu]*', Number.Integer),
66 (r'[+-=]', Operator),
67 (r'([a-zA-Z_][\w.]*)([ \t]*)(=)',
68 bygroups(Name.Attribute, Text, Operator)),
69 (r'[a-zA-Z_][\w.]*', Name),
70 ],
71 'package': [
72 (r'[a-zA-Z_]\w*', Name.Namespace, '#pop'),
73 default('#pop'),
74 ],
75 'message': [
76 (r'[a-zA-Z_]\w*', Name.Class, '#pop'),
77 default('#pop'),
78 ],
79 'type': [
80 (r'[a-zA-Z_]\w*', Name, '#pop'),
81 default('#pop'),
82 ],
83 }
84
85
86 class ThriftLexer(RegexLexer):
87 """
88 For `Thrift <https://thrift.apache.org/>`__ interface definitions.
89
90 .. versionadded:: 2.1
91 """
92 name = 'Thrift'
93 aliases = ['thrift']
94 filenames = ['*.thrift']
95 mimetypes = ['application/x-thrift']
96
97 tokens = {
98 'root': [
99 include('whitespace'),
100 include('comments'),
101 (r'"', String.Double, combined('stringescape', 'dqs')),
102 (r'\'', String.Single, combined('stringescape', 'sqs')),
103 (r'(namespace)(\s+)',
104 bygroups(Keyword.Namespace, Text.Whitespace), 'namespace'),
105 (r'(enum|union|struct|service|exception)(\s+)',
106 bygroups(Keyword.Declaration, Text.Whitespace), 'class'),
107 (r'((?:(?:[^\W\d]|\$)[\w.\[\]$<>]*\s+)+?)' # return arguments
108 r'((?:[^\W\d]|\$)[\w$]*)' # method name
109 r'(\s*)(\()', # signature start
110 bygroups(using(this), Name.Function, Text, Operator)),
111 include('keywords'),
112 include('numbers'),
113 (r'[&=]', Operator),
114 (r'[:;,{}()<>\[\]]', Punctuation),
115 (r'[a-zA-Z_](\.\w|\w)*', Name),
116 ],
117 'whitespace': [
118 (r'\n', Text.Whitespace),
119 (r'\s+', Text.Whitespace),
120 ],
121 'comments': [
122 (r'#.*$', Comment),
123 (r'//.*?\n', Comment),
124 (r'/\*[\w\W]*?\*/', Comment.Multiline),
125 ],
126 'stringescape': [
127 (r'\\([\\nrt"\'])', String.Escape),
128 ],
129 'dqs': [
130 (r'"', String.Double, '#pop'),
131 (r'[^\\"\n]+', String.Double),
132 ],
133 'sqs': [
134 (r"'", String.Single, '#pop'),
135 (r'[^\\\'\n]+', String.Single),
136 ],
137 'namespace': [
138 (r'[a-z*](\.\w|\w)*', Name.Namespace, '#pop'),
139 default('#pop'),
140 ],
141 'class': [
142 (r'[a-zA-Z_]\w*', Name.Class, '#pop'),
143 default('#pop'),
144 ],
145 'keywords': [
146 (r'(async|oneway|extends|throws|required|optional)\b', Keyword),
147 (r'(true|false)\b', Keyword.Constant),
148 (r'(const|typedef)\b', Keyword.Declaration),
149 (words((
150 'cpp_namespace', 'cpp_include', 'cpp_type', 'java_package',
151 'cocoa_prefix', 'csharp_namespace', 'delphi_namespace',
152 'php_namespace', 'py_module', 'perl_package',
153 'ruby_namespace', 'smalltalk_category', 'smalltalk_prefix',
154 'xsd_all', 'xsd_optional', 'xsd_nillable', 'xsd_namespace',
155 'xsd_attrs', 'include'), suffix=r'\b'),
156 Keyword.Namespace),
157 (words((
158 'void', 'bool', 'byte', 'i16', 'i32', 'i64', 'double',
159 'string', 'binary', 'map', 'list', 'set', 'slist',
160 'senum'), suffix=r'\b'),
161 Keyword.Type),
162 (words((
163 'BEGIN', 'END', '__CLASS__', '__DIR__', '__FILE__',
164 '__FUNCTION__', '__LINE__', '__METHOD__', '__NAMESPACE__',
165 'abstract', 'alias', 'and', 'args', 'as', 'assert', 'begin',
166 'break', 'case', 'catch', 'class', 'clone', 'continue',
167 'declare', 'def', 'default', 'del', 'delete', 'do', 'dynamic',
168 'elif', 'else', 'elseif', 'elsif', 'end', 'enddeclare',
169 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile',
170 'ensure', 'except', 'exec', 'finally', 'float', 'for',
171 'foreach', 'function', 'global', 'goto', 'if', 'implements',
172 'import', 'in', 'inline', 'instanceof', 'interface', 'is',
173 'lambda', 'module', 'native', 'new', 'next', 'nil', 'not',
174 'or', 'pass', 'public', 'print', 'private', 'protected',
175 'raise', 'redo', 'rescue', 'retry', 'register', 'return',
176 'self', 'sizeof', 'static', 'super', 'switch', 'synchronized',
177 'then', 'this', 'throw', 'transient', 'try', 'undef',
178 'unless', 'unsigned', 'until', 'use', 'var', 'virtual',
179 'volatile', 'when', 'while', 'with', 'xor', 'yield'),
180 prefix=r'\b', suffix=r'\b'),
181 Keyword.Reserved),
182 ],
183 'numbers': [
184 (r'[+-]?(\d+\.\d+([eE][+-]?\d+)?|\.?\d+[eE][+-]?\d+)', Number.Float),
185 (r'[+-]?0x[0-9A-Fa-f]+', Number.Hex),
186 (r'[+-]?[0-9]+', Number.Integer),
187 ],
188 }
189
190
191 class ZeekLexer(RegexLexer):
192 """
193 For `Zeek <https://www.zeek.org/>`_ scripts.
194
195 .. versionadded:: 2.5
196 """
197 name = 'Zeek'
198 aliases = ['zeek', 'bro']
199 filenames = ['*.zeek', '*.bro']
200
201 _hex = r'[0-9a-fA-F]'
202 _float = r'((\d*\.?\d+)|(\d+\.?\d*))([eE][-+]?\d+)?'
203 _h = r'[A-Za-z0-9][-A-Za-z0-9]*'
204
205 tokens = {
206 'root': [
207 include('whitespace'),
208 include('comments'),
209 include('directives'),
210 include('attributes'),
211 include('types'),
212 include('keywords'),
213 include('literals'),
214 include('operators'),
215 include('punctuation'),
216 (r'((?:[A-Za-z_]\w*)(?:::(?:[A-Za-z_]\w*))*)(?=\s*\()',
217 Name.Function),
218 include('identifiers'),
219 ],
220
221 'whitespace': [
222 (r'\n', Text),
223 (r'\s+', Text),
224 (r'\\\n', Text),
225 ],
226
227 'comments': [
228 (r'#.*$', Comment),
229 ],
230
231 'directives': [
232 (r'@(load-plugin|load-sigs|load|unload)\b.*$', Comment.Preproc),
233 (r'@(DEBUG|DIR|FILENAME|deprecated|if|ifdef|ifndef|else|endif)\b', Comment.Preproc),
234 (r'(@prefixes)\s*(\+?=).*$', Comment.Preproc),
235 ],
236
237 'attributes': [
238 (words(('redef', 'priority', 'log', 'optional', 'default', 'add_func',
239 'delete_func', 'expire_func', 'read_expire', 'write_expire',
240 'create_expire', 'synchronized', 'persistent', 'rotate_interval',
241 'rotate_size', 'encrypt', 'raw_output', 'mergeable', 'error_handler',
242 'type_column', 'deprecated'),
243 prefix=r'&', suffix=r'\b'),
244 Keyword.Pseudo),
245 ],
246
247 'types': [
248 (words(('any',
249 'enum', 'record', 'set', 'table', 'vector',
250 'function', 'hook', 'event',
251 'addr', 'bool', 'count', 'double', 'file', 'int', 'interval',
252 'pattern', 'port', 'string', 'subnet', 'time'),
253 suffix=r'\b'),
254 Keyword.Type),
255
256 (r'(opaque)(\s+)(of)(\s+)((?:[A-Za-z_]\w*)(?:::(?:[A-Za-z_]\w*))*)\b',
257 bygroups(Keyword.Type, Text, Operator.Word, Text, Keyword.Type)),
258
259 (r'(type)(\s+)((?:[A-Za-z_]\w*)(?:::(?:[A-Za-z_]\w*))*)(\s*)(:)(\s*)\b(record|enum)\b',
260 bygroups(Keyword, Text, Name.Class, Text, Operator, Text, Keyword.Type)),
261
262 (r'(type)(\s+)((?:[A-Za-z_]\w*)(?:::(?:[A-Za-z_]\w*))*)(\s*)(:)',
263 bygroups(Keyword, Text, Name, Text, Operator)),
264
265 (r'(redef)(\s+)(record|enum)(\s+)((?:[A-Za-z_]\w*)(?:::(?:[A-Za-z_]\w*))*)\b',
266 bygroups(Keyword, Text, Keyword.Type, Text, Name.Class)),
267 ],
268
269 'keywords': [
270 (words(('redef', 'export', 'if', 'else', 'for', 'while',
271 'return', 'break', 'next', 'continue', 'fallthrough',
272 'switch', 'default', 'case',
273 'add', 'delete',
274 'when', 'timeout', 'schedule'),
275 suffix=r'\b'),
276 Keyword),
277 (r'(print)\b', Keyword),
278 (r'(global|local|const|option)\b', Keyword.Declaration),
279 (r'(module)(\s+)(([A-Za-z_]\w*)(?:::([A-Za-z_]\w*))*)\b',
280 bygroups(Keyword.Namespace, Text, Name.Namespace)),
281 ],
282
283 'literals': [
284 (r'"', String, 'string'),
285
286 # Not the greatest match for patterns, but generally helps
287 # disambiguate between start of a pattern and just a division
288 # operator.
289 (r'/(?=.*/)', String.Regex, 'regex'),
290
291 (r'(T|F)\b', Keyword.Constant),
292
293 # Port
294 (r'\d{1,5}/(udp|tcp|icmp|unknown)\b', Number),
295
296 # IPv4 Address
297 (r'(\d{1,3}.){3}(\d{1,3})\b', Number),
298
299 # IPv6 Address
300 (r'\[([0-9a-fA-F]{0,4}:){2,7}([0-9a-fA-F]{0,4})?((\d{1,3}.){3}(\d{1,3}))?\]', Number),
301
302 # Numeric
303 (r'0[xX]' + _hex + r'+\b', Number.Hex),
304 (_float + r'\s*(day|hr|min|sec|msec|usec)s?\b', Number.Float),
305 (_float + r'\b', Number.Float),
306 (r'(\d+)\b', Number.Integer),
307
308 # Hostnames
309 (_h + r'(\.' + _h + r')+', String),
310 ],
311
312 'operators': [
313 (r'[!%*/+<=>~|&^-]', Operator),
314 (r'([-+=&|]{2}|[+=!><-]=)', Operator),
315 (r'(in|as|is|of)\b', Operator.Word),
316 (r'\??\$', Operator),
317 ],
318
319 'punctuation': [
320 (r'[{}()\[\],;.]', Punctuation),
321 # The "ternary if", which uses '?' and ':', could instead be
322 # treated as an Operator, but colons are more frequently used to
323 # separate field/identifier names from their types, so the (often)
324 # less-prominent Punctuation is used even with '?' for consistency.
325 (r'[?:]', Punctuation),
326 ],
327
328 'identifiers': [
329 (r'([a-zA-Z_]\w*)(::)', bygroups(Name, Punctuation)),
330 (r'[a-zA-Z_]\w*', Name)
331 ],
332
333 'string': [
334 (r'\\.', String.Escape),
335 (r'%-?[0-9]*(\.[0-9]+)?[DTd-gsx]', String.Escape),
336 (r'"', String, '#pop'),
337 (r'.', String),
338 ],
339
340 'regex': [
341 (r'\\.', String.Escape),
342 (r'/', String.Regex, '#pop'),
343 (r'.', String.Regex),
344 ],
345 }
346
347
348 BroLexer = ZeekLexer
349
350
351 class PuppetLexer(RegexLexer):
352 """
353 For `Puppet <http://puppetlabs.com/>`__ configuration DSL.
354
355 .. versionadded:: 1.6
356 """
357 name = 'Puppet'
358 aliases = ['puppet']
359 filenames = ['*.pp']
360
361 tokens = {
362 'root': [
363 include('comments'),
364 include('keywords'),
365 include('names'),
366 include('numbers'),
367 include('operators'),
368 include('strings'),
369
370 (r'[]{}:(),;[]', Punctuation),
371 (r'[^\S\n]+', Text),
372 ],
373
374 'comments': [
375 (r'\s*#.*$', Comment),
376 (r'/(\\\n)?[*](.|\n)*?[*](\\\n)?/', Comment.Multiline),
377 ],
378
379 'operators': [
380 (r'(=>|\?|<|>|=|\+|-|/|\*|~|!|\|)', Operator),
381 (r'(in|and|or|not)\b', Operator.Word),
382 ],
383
384 'names': [
385 (r'[a-zA-Z_]\w*', Name.Attribute),
386 (r'(\$\S+)(\[)(\S+)(\])', bygroups(Name.Variable, Punctuation,
387 String, Punctuation)),
388 (r'\$\S+', Name.Variable),
389 ],
390
391 'numbers': [
392 # Copypasta from the Python lexer
393 (r'(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?j?', Number.Float),
394 (r'\d+[eE][+-]?[0-9]+j?', Number.Float),
395 (r'0[0-7]+j?', Number.Oct),
396 (r'0[xX][a-fA-F0-9]+', Number.Hex),
397 (r'\d+L', Number.Integer.Long),
398 (r'\d+j?', Number.Integer)
399 ],
400
401 'keywords': [
402 # Left out 'group' and 'require'
403 # Since they're often used as attributes
404 (words((
405 'absent', 'alert', 'alias', 'audit', 'augeas', 'before', 'case',
406 'check', 'class', 'computer', 'configured', 'contained',
407 'create_resources', 'crit', 'cron', 'debug', 'default',
408 'define', 'defined', 'directory', 'else', 'elsif', 'emerg',
409 'err', 'exec', 'extlookup', 'fail', 'false', 'file',
410 'filebucket', 'fqdn_rand', 'generate', 'host', 'if', 'import',
411 'include', 'info', 'inherits', 'inline_template', 'installed',
412 'interface', 'k5login', 'latest', 'link', 'loglevel',
413 'macauthorization', 'mailalias', 'maillist', 'mcx', 'md5',
414 'mount', 'mounted', 'nagios_command', 'nagios_contact',
415 'nagios_contactgroup', 'nagios_host', 'nagios_hostdependency',
416 'nagios_hostescalation', 'nagios_hostextinfo', 'nagios_hostgroup',
417 'nagios_service', 'nagios_servicedependency', 'nagios_serviceescalation',
418 'nagios_serviceextinfo', 'nagios_servicegroup', 'nagios_timeperiod',
419 'node', 'noop', 'notice', 'notify', 'package', 'present', 'purged',
420 'realize', 'regsubst', 'resources', 'role', 'router', 'running',
421 'schedule', 'scheduled_task', 'search', 'selboolean', 'selmodule',
422 'service', 'sha1', 'shellquote', 'split', 'sprintf',
423 'ssh_authorized_key', 'sshkey', 'stage', 'stopped', 'subscribe',
424 'tag', 'tagged', 'template', 'tidy', 'true', 'undef', 'unmounted',
425 'user', 'versioncmp', 'vlan', 'warning', 'yumrepo', 'zfs', 'zone',
426 'zpool'), prefix='(?i)', suffix=r'\b'),
427 Keyword),
428 ],
429
430 'strings': [
431 (r'"([^"])*"', String),
432 (r"'(\\'|[^'])*'", String),
433 ],
434
435 }
436
437
438 class RslLexer(RegexLexer):
439 """
440 `RSL <http://en.wikipedia.org/wiki/RAISE>`_ is the formal specification
441 language used in RAISE (Rigorous Approach to Industrial Software Engineering)
442 method.
443
444 .. versionadded:: 2.0
445 """
446 name = 'RSL'
447 aliases = ['rsl']
448 filenames = ['*.rsl']
449 mimetypes = ['text/rsl']
450
451 flags = re.MULTILINE | re.DOTALL
452
453 tokens = {
454 'root': [
455 (words((
456 'Bool', 'Char', 'Int', 'Nat', 'Real', 'Text', 'Unit', 'abs',
457 'all', 'always', 'any', 'as', 'axiom', 'card', 'case', 'channel',
458 'chaos', 'class', 'devt_relation', 'dom', 'elems', 'else', 'elif',
459 'end', 'exists', 'extend', 'false', 'for', 'hd', 'hide', 'if',
460 'in', 'is', 'inds', 'initialise', 'int', 'inter', 'isin', 'len',
461 'let', 'local', 'ltl_assertion', 'object', 'of', 'out', 'post',
462 'pre', 'read', 'real', 'rng', 'scheme', 'skip', 'stop', 'swap',
463 'then', 'theory', 'test_case', 'tl', 'transition_system', 'true',
464 'type', 'union', 'until', 'use', 'value', 'variable', 'while',
465 'with', 'write', '~isin', '-inflist', '-infset', '-list',
466 '-set'), prefix=r'\b', suffix=r'\b'),
467 Keyword),
468 (r'(variable|value)\b', Keyword.Declaration),
469 (r'--.*?\n', Comment),
470 (r'<:.*?:>', Comment),
471 (r'\{!.*?!\}', Comment),
472 (r'/\*.*?\*/', Comment),
473 (r'^[ \t]*([\w]+)[ \t]*:[^:]', Name.Function),
474 (r'(^[ \t]*)([\w]+)([ \t]*\([\w\s,]*\)[ \t]*)(is|as)',
475 bygroups(Text, Name.Function, Text, Keyword)),
476 (r'\b[A-Z]\w*\b', Keyword.Type),
477 (r'(true|false)\b', Keyword.Constant),
478 (r'".*"', String),
479 (r'\'.\'', String.Char),
480 (r'(><|->|-m->|/\\|<=|<<=|<\.|\|\||\|\^\||-~->|-~m->|\\/|>=|>>|'
481 r'\.>|\+\+|-\\|<->|=>|:-|~=|\*\*|<<|>>=|\+>|!!|\|=\||#)',
482 Operator),
483 (r'[0-9]+\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
484 (r'0x[0-9a-f]+', Number.Hex),
485 (r'[0-9]+', Number.Integer),
486 (r'.', Text),
487 ],
488 }
489
490 def analyse_text(text):
491 """
492 Check for the most common text in the beginning of a RSL file.
493 """
494 if re.search(r'scheme\s*.*?=\s*class\s*type', text, re.I) is not None:
495 return 1.0
496
497
498 class MscgenLexer(RegexLexer):
499 """
500 For `Mscgen <http://www.mcternan.me.uk/mscgen/>`_ files.
501
502 .. versionadded:: 1.6
503 """
504 name = 'Mscgen'
505 aliases = ['mscgen', 'msc']
506 filenames = ['*.msc']
507
508 _var = r'(\w+|"(?:\\"|[^"])*")'
509
510 tokens = {
511 'root': [
512 (r'msc\b', Keyword.Type),
513 # Options
514 (r'(hscale|HSCALE|width|WIDTH|wordwraparcs|WORDWRAPARCS'
515 r'|arcgradient|ARCGRADIENT)\b', Name.Property),
516 # Operators
517 (r'(abox|ABOX|rbox|RBOX|box|BOX|note|NOTE)\b', Operator.Word),
518 (r'(\.|-|\|){3}', Keyword),
519 (r'(?:-|=|\.|:){2}'
520 r'|<<=>>|<->|<=>|<<>>|<:>'
521 r'|->|=>>|>>|=>|:>|-x|-X'
522 r'|<-|<<=|<<|<=|<:|x-|X-|=', Operator),
523 # Names
524 (r'\*', Name.Builtin),
525 (_var, Name.Variable),
526 # Other
527 (r'\[', Punctuation, 'attrs'),
528 (r'\{|\}|,|;', Punctuation),
529 include('comments')
530 ],
531 'attrs': [
532 (r'\]', Punctuation, '#pop'),
533 (_var + r'(\s*)(=)(\s*)' + _var,
534 bygroups(Name.Attribute, Text.Whitespace, Operator, Text.Whitespace,
535 String)),
536 (r',', Punctuation),
537 include('comments')
538 ],
539 'comments': [
540 (r'(?://|#).*?\n', Comment.Single),
541 (r'/\*(?:.|\n)*?\*/', Comment.Multiline),
542 (r'[ \t\r\n]+', Text.Whitespace)
543 ]
544 }
545
546
547 class VGLLexer(RegexLexer):
548 """
549 For `SampleManager VGL <http://www.thermoscientific.com/samplemanager>`_
550 source code.
551
552 .. versionadded:: 1.6
553 """
554 name = 'VGL'
555 aliases = ['vgl']
556 filenames = ['*.rpf']
557
558 flags = re.MULTILINE | re.DOTALL | re.IGNORECASE
559
560 tokens = {
561 'root': [
562 (r'\{[^}]*\}', Comment.Multiline),
563 (r'declare', Keyword.Constant),
564 (r'(if|then|else|endif|while|do|endwhile|and|or|prompt|object'
565 r'|create|on|line|with|global|routine|value|endroutine|constant'
566 r'|global|set|join|library|compile_option|file|exists|create|copy'
567 r'|delete|enable|windows|name|notprotected)(?! *[=<>.,()])',
568 Keyword),
569 (r'(true|false|null|empty|error|locked)', Keyword.Constant),
570 (r'[~^*#!%&\[\]()<>|+=:;,./?-]', Operator),
571 (r'"[^"]*"', String),
572 (r'(\.)([a-z_$][\w$]*)', bygroups(Operator, Name.Attribute)),
573 (r'[0-9][0-9]*(\.[0-9]+(e[+\-]?[0-9]+)?)?', Number),
574 (r'[a-z_$][\w$]*', Name),
575 (r'[\r\n]+', Text),
576 (r'\s+', Text)
577 ]
578 }
579
580
581 class AlloyLexer(RegexLexer):
582 """
583 For `Alloy <http://alloy.mit.edu>`_ source code.
584
585 .. versionadded:: 2.0
586 """
587
588 name = 'Alloy'
589 aliases = ['alloy']
590 filenames = ['*.als']
591 mimetypes = ['text/x-alloy']
592
593 flags = re.MULTILINE | re.DOTALL
594
595 iden_rex = r'[a-zA-Z_][\w\']*'
596 text_tuple = (r'[^\S\n]+', Text)
597
598 tokens = {
599 'sig': [
600 (r'(extends)\b', Keyword, '#pop'),
601 (iden_rex, Name),
602 text_tuple,
603 (r',', Punctuation),
604 (r'\{', Operator, '#pop'),
605 ],
606 'module': [
607 text_tuple,
608 (iden_rex, Name, '#pop'),
609 ],
610 'fun': [
611 text_tuple,
612 (r'\{', Operator, '#pop'),
613 (iden_rex, Name, '#pop'),
614 ],
615 'root': [
616 (r'--.*?$', Comment.Single),
617 (r'//.*?$', Comment.Single),
618 (r'/\*.*?\*/', Comment.Multiline),
619 text_tuple,
620 (r'(module|open)(\s+)', bygroups(Keyword.Namespace, Text),
621 'module'),
622 (r'(sig|enum)(\s+)', bygroups(Keyword.Declaration, Text), 'sig'),
623 (r'(iden|univ|none)\b', Keyword.Constant),
624 (r'(int|Int)\b', Keyword.Type),
625 (r'(this|abstract|extends|set|seq|one|lone|let)\b', Keyword),
626 (r'(all|some|no|sum|disj|when|else)\b', Keyword),
627 (r'(run|check|for|but|exactly|expect|as)\b', Keyword),
628 (r'(and|or|implies|iff|in)\b', Operator.Word),
629 (r'(fun|pred|fact|assert)(\s+)', bygroups(Keyword, Text), 'fun'),
630 (r'!|#|&&|\+\+|<<|>>|>=|<=>|<=|\.|->', Operator),
631 (r'[-+/*%=<>&!^|~{}\[\]().]', Operator),
632 (iden_rex, Name),
633 (r'[:,]', Punctuation),
634 (r'[0-9]+', Number.Integer),
635 (r'"(\\\\|\\[^\\]|[^"\\])*"', String),
636 (r'\n', Text),
637 ]
638 }
639
640
641 class PanLexer(RegexLexer):
642 """
643 Lexer for `pan <https://github.com/quattor/pan/>`_ source files.
644
645 Based on tcsh lexer.
646
647 .. versionadded:: 2.0
648 """
649
650 name = 'Pan'
651 aliases = ['pan']
652 filenames = ['*.pan']
653
654 tokens = {
655 'root': [
656 include('basic'),
657 (r'\(', Keyword, 'paren'),
658 (r'\{', Keyword, 'curly'),
659 include('data'),
660 ],
661 'basic': [
662 (words((
663 'if', 'for', 'with', 'else', 'type', 'bind', 'while', 'valid', 'final',
664 'prefix', 'unique', 'object', 'foreach', 'include', 'template',
665 'function', 'variable', 'structure', 'extensible', 'declaration'),
666 prefix=r'\b', suffix=r'\s*\b'),
667 Keyword),
668 (words((
669 'file_contents', 'format', 'index', 'length', 'match', 'matches',
670 'replace', 'splice', 'split', 'substr', 'to_lowercase', 'to_uppercase',
671 'debug', 'error', 'traceback', 'deprecated', 'base64_decode',
672 'base64_encode', 'digest', 'escape', 'unescape', 'append', 'create',
673 'first', 'nlist', 'key', 'list', 'merge', 'next', 'prepend', 'is_boolean',
674 'is_defined', 'is_double', 'is_list', 'is_long', 'is_nlist', 'is_null',
675 'is_number', 'is_property', 'is_resource', 'is_string', 'to_boolean',
676 'to_double', 'to_long', 'to_string', 'clone', 'delete', 'exists',
677 'path_exists', 'if_exists', 'return', 'value'),
678 prefix=r'\b', suffix=r'\s*\b'),
679 Name.Builtin),
680 (r'#.*', Comment),
681 (r'\\[\w\W]', String.Escape),
682 (r'(\b\w+)(\s*)(=)', bygroups(Name.Variable, Text, Operator)),
683 (r'[\[\]{}()=]+', Operator),
684 (r'<<\s*(\'?)\\?(\w+)[\w\W]+?\2', String),
685 (r';', Punctuation),
686 ],
687 'data': [
688 (r'(?s)"(\\\\|\\[0-7]+|\\.|[^"\\])*"', String.Double),
689 (r"(?s)'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single),
690 (r'\s+', Text),
691 (r'[^=\s\[\]{}()$"\'`\\;#]+', Text),
692 (r'\d+(?= |\Z)', Number),
693 ],
694 'curly': [
695 (r'\}', Keyword, '#pop'),
696 (r':-', Keyword),
697 (r'\w+', Name.Variable),
698 (r'[^}:"\'`$]+', Punctuation),
699 (r':', Punctuation),
700 include('root'),
701 ],
702 'paren': [
703 (r'\)', Keyword, '#pop'),
704 include('root'),
705 ],
706 }
707
708
709 class CrmshLexer(RegexLexer):
710 """
711 Lexer for `crmsh <http://crmsh.github.io/>`_ configuration files
712 for Pacemaker clusters.
713
714 .. versionadded:: 2.1
715 """
716 name = 'Crmsh'
717 aliases = ['crmsh', 'pcmk']
718 filenames = ['*.crmsh', '*.pcmk']
719 mimetypes = []
720
721 elem = words((
722 'node', 'primitive', 'group', 'clone', 'ms', 'location',
723 'colocation', 'order', 'fencing_topology', 'rsc_ticket',
724 'rsc_template', 'property', 'rsc_defaults',
725 'op_defaults', 'acl_target', 'acl_group', 'user', 'role',
726 'tag'), suffix=r'(?![\w#$-])')
727 sub = words((
728 'params', 'meta', 'operations', 'op', 'rule',
729 'attributes', 'utilization'), suffix=r'(?![\w#$-])')
730 acl = words(('read', 'write', 'deny'), suffix=r'(?![\w#$-])')
731 bin_rel = words(('and', 'or'), suffix=r'(?![\w#$-])')
732 un_ops = words(('defined', 'not_defined'), suffix=r'(?![\w#$-])')
733 date_exp = words(('in_range', 'date', 'spec', 'in'), suffix=r'(?![\w#$-])')
734 acl_mod = (r'(?:tag|ref|reference|attribute|type|xpath)')
735 bin_ops = (r'(?:lt|gt|lte|gte|eq|ne)')
736 val_qual = (r'(?:string|version|number)')
737 rsc_role_action = (r'(?:Master|Started|Slave|Stopped|'
738 r'start|promote|demote|stop)')
739
740 tokens = {
741 'root': [
742 (r'^#.*\n?', Comment),
743 # attr=value (nvpair)
744 (r'([\w#$-]+)(=)("(?:""|[^"])*"|\S+)',
745 bygroups(Name.Attribute, Punctuation, String)),
746 # need this construct, otherwise numeric node ids
747 # are matched as scores
748 # elem id:
749 (r'(node)(\s+)([\w#$-]+)(:)',
750 bygroups(Keyword, Whitespace, Name, Punctuation)),
751 # scores
752 (r'([+-]?([0-9]+|inf)):', Number),
753 # keywords (elements and other)
754 (elem, Keyword),
755 (sub, Keyword),
756 (acl, Keyword),
757 # binary operators
758 (r'(?:%s:)?(%s)(?![\w#$-])' % (val_qual, bin_ops), Operator.Word),
759 # other operators
760 (bin_rel, Operator.Word),
761 (un_ops, Operator.Word),
762 (date_exp, Operator.Word),
763 # builtin attributes (e.g. #uname)
764 (r'#[a-z]+(?![\w#$-])', Name.Builtin),
765 # acl_mod:blah
766 (r'(%s)(:)("(?:""|[^"])*"|\S+)' % acl_mod,
767 bygroups(Keyword, Punctuation, Name)),
768 # rsc_id[:(role|action)]
769 # NB: this matches all other identifiers
770 (r'([\w#$-]+)(?:(:)(%s))?(?![\w#$-])' % rsc_role_action,
771 bygroups(Name, Punctuation, Operator.Word)),
772 # punctuation
773 (r'(\\(?=\n)|[\[\](){}/:@])', Punctuation),
774 (r'\s+|\n', Whitespace),
775 ],
776 }
777
778
779 class FlatlineLexer(RegexLexer):
780 """
781 Lexer for `Flatline <https://github.com/bigmlcom/flatline>`_ expressions.
782
783 .. versionadded:: 2.2
784 """
785 name = 'Flatline'
786 aliases = ['flatline']
787 filenames = []
788 mimetypes = ['text/x-flatline']
789
790 special_forms = ('let',)
791
792 builtins = (
793 "!=", "*", "+", "-", "<", "<=", "=", ">", ">=", "abs", "acos", "all",
794 "all-but", "all-with-defaults", "all-with-numeric-default", "and",
795 "asin", "atan", "avg", "avg-window", "bin-center", "bin-count", "call",
796 "category-count", "ceil", "cond", "cond-window", "cons", "cos", "cosh",
797 "count", "diff-window", "div", "ensure-value", "ensure-weighted-value",
798 "epoch", "epoch-day", "epoch-fields", "epoch-hour", "epoch-millisecond",
799 "epoch-minute", "epoch-month", "epoch-second", "epoch-weekday",
800 "epoch-year", "exp", "f", "field", "field-prop", "fields", "filter",
801 "first", "floor", "head", "if", "in", "integer", "language", "length",
802 "levenshtein", "linear-regression", "list", "ln", "log", "log10", "map",
803 "matches", "matches?", "max", "maximum", "md5", "mean", "median", "min",
804 "minimum", "missing", "missing-count", "missing?", "missing_count",
805 "mod", "mode", "normalize", "not", "nth", "occurrences", "or",
806 "percentile", "percentile-label", "population", "population-fraction",
807 "pow", "preferred", "preferred?", "quantile-label", "rand", "rand-int",
808 "random-value", "re-quote", "real", "replace", "replace-first", "rest",
809 "round", "row-number", "segment-label", "sha1", "sha256", "sin", "sinh",
810 "sqrt", "square", "standard-deviation", "standard_deviation", "str",
811 "subs", "sum", "sum-squares", "sum-window", "sum_squares", "summary",
812 "summary-no", "summary-str", "tail", "tan", "tanh", "to-degrees",
813 "to-radians", "variance", "vectorize", "weighted-random-value", "window",
814 "winnow", "within-percentiles?", "z-score",
815 )
816
817 valid_name = r'(?!#)[\w!$%*+<=>?/.#-]+'
818
819 tokens = {
820 'root': [
821 # whitespaces - usually not relevant
822 (r'[,\s]+', Text),
823
824 # numbers
825 (r'-?\d+\.\d+', Number.Float),
826 (r'-?\d+', Number.Integer),
827 (r'0x-?[a-f\d]+', Number.Hex),
828
829 # strings, symbols and characters
830 (r'"(\\\\|\\[^\\]|[^"\\])*"', String),
831 (r"\\(.|[a-z]+)", String.Char),
832
833 # expression template placeholder
834 (r'_', String.Symbol),
835
836 # highlight the special forms
837 (words(special_forms, suffix=' '), Keyword),
838
839 # highlight the builtins
840 (words(builtins, suffix=' '), Name.Builtin),
841
842 # the remaining functions
843 (r'(?<=\()' + valid_name, Name.Function),
844
845 # find the remaining variables
846 (valid_name, Name.Variable),
847
848 # parentheses
849 (r'(\(|\))', Punctuation),
850 ],
851 }
852
853
854 class SnowballLexer(ExtendedRegexLexer):
855 """
856 Lexer for `Snowball <http://snowballstem.org/>`_ source code.
857
858 .. versionadded:: 2.2
859 """
860
861 name = 'Snowball'
862 aliases = ['snowball']
863 filenames = ['*.sbl']
864
865 _ws = r'\n\r\t '
866
867 def __init__(self, **options):
868 self._reset_stringescapes()
869 ExtendedRegexLexer.__init__(self, **options)
870
871 def _reset_stringescapes(self):
872 self._start = "'"
873 self._end = "'"
874
875 def _string(do_string_first):
876 def callback(lexer, match, ctx):
877 s = match.start()
878 text = match.group()
879 string = re.compile(r'([^%s]*)(.)' % re.escape(lexer._start)).match
880 escape = re.compile(r'([^%s]*)(.)' % re.escape(lexer._end)).match
881 pos = 0
882 do_string = do_string_first
883 while pos < len(text):
884 if do_string:
885 match = string(text, pos)
886 yield s + match.start(1), String.Single, match.group(1)
887 if match.group(2) == "'":
888 yield s + match.start(2), String.Single, match.group(2)
889 ctx.stack.pop()
890 break
891 yield s + match.start(2), String.Escape, match.group(2)
892 pos = match.end()
893 match = escape(text, pos)
894 yield s + match.start(), String.Escape, match.group()
895 if match.group(2) != lexer._end:
896 ctx.stack[-1] = 'escape'
897 break
898 pos = match.end()
899 do_string = True
900 ctx.pos = s + match.end()
901 return callback
902
903 def _stringescapes(lexer, match, ctx):
904 lexer._start = match.group(3)
905 lexer._end = match.group(5)
906 return bygroups(Keyword.Reserved, Text, String.Escape, Text,
907 String.Escape)(lexer, match, ctx)
908
909 tokens = {
910 'root': [
911 (words(('len', 'lenof'), suffix=r'\b'), Operator.Word),
912 include('root1'),
913 ],
914 'root1': [
915 (r'[%s]+' % _ws, Text),
916 (r'\d+', Number.Integer),
917 (r"'", String.Single, 'string'),
918 (r'[()]', Punctuation),
919 (r'/\*[\w\W]*?\*/', Comment.Multiline),
920 (r'//.*', Comment.Single),
921 (r'[!*+\-/<=>]=|[-=]>|<[+-]|[$*+\-/<=>?\[\]]', Operator),
922 (words(('as', 'get', 'hex', 'among', 'define', 'decimal',
923 'backwardmode'), suffix=r'\b'),
924 Keyword.Reserved),
925 (words(('strings', 'booleans', 'integers', 'routines', 'externals',
926 'groupings'), suffix=r'\b'),
927 Keyword.Reserved, 'declaration'),
928 (words(('do', 'or', 'and', 'for', 'hop', 'non', 'not', 'set', 'try',
929 'fail', 'goto', 'loop', 'next', 'test', 'true',
930 'false', 'unset', 'atmark', 'attach', 'delete', 'gopast',
931 'insert', 'repeat', 'sizeof', 'tomark', 'atleast',
932 'atlimit', 'reverse', 'setmark', 'tolimit', 'setlimit',
933 'backwards', 'substring'), suffix=r'\b'),
934 Operator.Word),
935 (words(('size', 'limit', 'cursor', 'maxint', 'minint'),
936 suffix=r'\b'),
937 Name.Builtin),
938 (r'(stringdef\b)([%s]*)([^%s]+)' % (_ws, _ws),
939 bygroups(Keyword.Reserved, Text, String.Escape)),
940 (r'(stringescapes\b)([%s]*)(.)([%s]*)(.)' % (_ws, _ws),
941 _stringescapes),
942 (r'[A-Za-z]\w*', Name),
943 ],
944 'declaration': [
945 (r'\)', Punctuation, '#pop'),
946 (words(('len', 'lenof'), suffix=r'\b'), Name,
947 ('root1', 'declaration')),
948 include('root1'),
949 ],
950 'string': [
951 (r"[^']*'", _string(True)),
952 ],
953 'escape': [
954 (r"[^']*'", _string(False)),
955 ],
956 }
957
958 def get_tokens_unprocessed(self, text=None, context=None):
959 self._reset_stringescapes()
960 return ExtendedRegexLexer.get_tokens_unprocessed(self, text, context)

eric ide

mercurial