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

changeset 6942
2602857055c5
parent 6651
e8f3b5568b21
child 7547
21b0534faebc
equal deleted inserted replaced
6941:f99d60d6b59b 6942:2602857055c5
1 # -*- coding: utf-8 -*-
2 """
3 pygments.lexers.dsls
4 ~~~~~~~~~~~~~~~~~~~~
5
6 Lexers for various domain-specific languages.
7
8 :copyright: Copyright 2006-2017 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, Literal, Whitespace
18
19 __all__ = ['ProtoBufLexer', 'BroLexer', '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', 'default',
44 'packed', 'ctype', 'extensions', 'to', 'max', 'rpc', 'returns',
45 'oneof'), 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 BroLexer(RegexLexer):
192 """
193 For `Bro <http://bro-ids.org/>`_ scripts.
194
195 .. versionadded:: 1.5
196 """
197 name = 'Bro'
198 aliases = ['bro']
199 filenames = ['*.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 # Whitespace
208 (r'^@.*?\n', Comment.Preproc),
209 (r'#.*?\n', Comment.Single),
210 (r'\n', Text),
211 (r'\s+', Text),
212 (r'\\\n', Text),
213 # Keywords
214 (r'(add|alarm|break|case|const|continue|delete|do|else|enum|event'
215 r'|export|for|function|if|global|hook|local|module|next'
216 r'|of|print|redef|return|schedule|switch|type|when|while)\b', Keyword),
217 (r'(addr|any|bool|count|counter|double|file|int|interval|net'
218 r'|pattern|port|record|set|string|subnet|table|time|timer'
219 r'|vector)\b', Keyword.Type),
220 (r'(T|F)\b', Keyword.Constant),
221 (r'(&)((?:add|delete|expire)_func|attr|(?:create|read|write)_expire'
222 r'|default|disable_print_hook|raw_output|encrypt|group|log'
223 r'|mergeable|optional|persistent|priority|redef'
224 r'|rotate_(?:interval|size)|synchronized)\b',
225 bygroups(Punctuation, Keyword)),
226 (r'\s+module\b', Keyword.Namespace),
227 # Addresses, ports and networks
228 (r'\d+/(tcp|udp|icmp|unknown)\b', Number),
229 (r'(\d+\.){3}\d+', Number),
230 (r'(' + _hex + r'){7}' + _hex, Number),
231 (r'0x' + _hex + r'(' + _hex + r'|:)*::(' + _hex + r'|:)*', Number),
232 (r'((\d+|:)(' + _hex + r'|:)*)?::(' + _hex + r'|:)*', Number),
233 (r'(\d+\.\d+\.|(\d+\.){2}\d+)', Number),
234 # Hostnames
235 (_h + r'(\.' + _h + r')+', String),
236 # Numeric
237 (_float + r'\s+(day|hr|min|sec|msec|usec)s?\b', Literal.Date),
238 (r'0[xX]' + _hex, Number.Hex),
239 (_float, Number.Float),
240 (r'\d+', Number.Integer),
241 (r'/', String.Regex, 'regex'),
242 (r'"', String, 'string'),
243 # Operators
244 (r'[!%*/+:<=>?~|-]', Operator),
245 (r'([-+=&|]{2}|[+=!><-]=)', Operator),
246 (r'(in|match)\b', Operator.Word),
247 (r'[{}()\[\]$.,;]', Punctuation),
248 # Identfier
249 (r'([_a-zA-Z]\w*)(::)', bygroups(Name, Name.Namespace)),
250 (r'[a-zA-Z_]\w*', Name)
251 ],
252 'string': [
253 (r'"', String, '#pop'),
254 (r'\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})', String.Escape),
255 (r'[^\\"\n]+', String),
256 (r'\\\n', String),
257 (r'\\', String)
258 ],
259 'regex': [
260 (r'/', String.Regex, '#pop'),
261 (r'\\[\\nt/]', String.Regex), # String.Escape is too intense here.
262 (r'[^\\/\n]+', String.Regex),
263 (r'\\\n', String.Regex),
264 (r'\\', String.Regex)
265 ]
266 }
267
268
269 class PuppetLexer(RegexLexer):
270 """
271 For `Puppet <http://puppetlabs.com/>`__ configuration DSL.
272
273 .. versionadded:: 1.6
274 """
275 name = 'Puppet'
276 aliases = ['puppet']
277 filenames = ['*.pp']
278
279 tokens = {
280 'root': [
281 include('comments'),
282 include('keywords'),
283 include('names'),
284 include('numbers'),
285 include('operators'),
286 include('strings'),
287
288 (r'[]{}:(),;[]', Punctuation),
289 (r'[^\S\n]+', Text),
290 ],
291
292 'comments': [
293 (r'\s*#.*$', Comment),
294 (r'/(\\\n)?[*](.|\n)*?[*](\\\n)?/', Comment.Multiline),
295 ],
296
297 'operators': [
298 (r'(=>|\?|<|>|=|\+|-|/|\*|~|!|\|)', Operator),
299 (r'(in|and|or|not)\b', Operator.Word),
300 ],
301
302 'names': [
303 (r'[a-zA-Z_]\w*', Name.Attribute),
304 (r'(\$\S+)(\[)(\S+)(\])', bygroups(Name.Variable, Punctuation,
305 String, Punctuation)),
306 (r'\$\S+', Name.Variable),
307 ],
308
309 'numbers': [
310 # Copypasta from the Python lexer
311 (r'(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?j?', Number.Float),
312 (r'\d+[eE][+-]?[0-9]+j?', Number.Float),
313 (r'0[0-7]+j?', Number.Oct),
314 (r'0[xX][a-fA-F0-9]+', Number.Hex),
315 (r'\d+L', Number.Integer.Long),
316 (r'\d+j?', Number.Integer)
317 ],
318
319 'keywords': [
320 # Left out 'group' and 'require'
321 # Since they're often used as attributes
322 (words((
323 'absent', 'alert', 'alias', 'audit', 'augeas', 'before', 'case',
324 'check', 'class', 'computer', 'configured', 'contained',
325 'create_resources', 'crit', 'cron', 'debug', 'default',
326 'define', 'defined', 'directory', 'else', 'elsif', 'emerg',
327 'err', 'exec', 'extlookup', 'fail', 'false', 'file',
328 'filebucket', 'fqdn_rand', 'generate', 'host', 'if', 'import',
329 'include', 'info', 'inherits', 'inline_template', 'installed',
330 'interface', 'k5login', 'latest', 'link', 'loglevel',
331 'macauthorization', 'mailalias', 'maillist', 'mcx', 'md5',
332 'mount', 'mounted', 'nagios_command', 'nagios_contact',
333 'nagios_contactgroup', 'nagios_host', 'nagios_hostdependency',
334 'nagios_hostescalation', 'nagios_hostextinfo', 'nagios_hostgroup',
335 'nagios_service', 'nagios_servicedependency', 'nagios_serviceescalation',
336 'nagios_serviceextinfo', 'nagios_servicegroup', 'nagios_timeperiod',
337 'node', 'noop', 'notice', 'notify', 'package', 'present', 'purged',
338 'realize', 'regsubst', 'resources', 'role', 'router', 'running',
339 'schedule', 'scheduled_task', 'search', 'selboolean', 'selmodule',
340 'service', 'sha1', 'shellquote', 'split', 'sprintf',
341 'ssh_authorized_key', 'sshkey', 'stage', 'stopped', 'subscribe',
342 'tag', 'tagged', 'template', 'tidy', 'true', 'undef', 'unmounted',
343 'user', 'versioncmp', 'vlan', 'warning', 'yumrepo', 'zfs', 'zone',
344 'zpool'), prefix='(?i)', suffix=r'\b'),
345 Keyword),
346 ],
347
348 'strings': [
349 (r'"([^"])*"', String),
350 (r"'(\\'|[^'])*'", String),
351 ],
352
353 }
354
355
356 class RslLexer(RegexLexer):
357 """
358 `RSL <http://en.wikipedia.org/wiki/RAISE>`_ is the formal specification
359 language used in RAISE (Rigorous Approach to Industrial Software Engineering)
360 method.
361
362 .. versionadded:: 2.0
363 """
364 name = 'RSL'
365 aliases = ['rsl']
366 filenames = ['*.rsl']
367 mimetypes = ['text/rsl']
368
369 flags = re.MULTILINE | re.DOTALL
370
371 tokens = {
372 'root': [
373 (words((
374 'Bool', 'Char', 'Int', 'Nat', 'Real', 'Text', 'Unit', 'abs',
375 'all', 'always', 'any', 'as', 'axiom', 'card', 'case', 'channel',
376 'chaos', 'class', 'devt_relation', 'dom', 'elems', 'else', 'elif',
377 'end', 'exists', 'extend', 'false', 'for', 'hd', 'hide', 'if',
378 'in', 'is', 'inds', 'initialise', 'int', 'inter', 'isin', 'len',
379 'let', 'local', 'ltl_assertion', 'object', 'of', 'out', 'post',
380 'pre', 'read', 'real', 'rng', 'scheme', 'skip', 'stop', 'swap',
381 'then', 'theory', 'test_case', 'tl', 'transition_system', 'true',
382 'type', 'union', 'until', 'use', 'value', 'variable', 'while',
383 'with', 'write', '~isin', '-inflist', '-infset', '-list',
384 '-set'), prefix=r'\b', suffix=r'\b'),
385 Keyword),
386 (r'(variable|value)\b', Keyword.Declaration),
387 (r'--.*?\n', Comment),
388 (r'<:.*?:>', Comment),
389 (r'\{!.*?!\}', Comment),
390 (r'/\*.*?\*/', Comment),
391 (r'^[ \t]*([\w]+)[ \t]*:[^:]', Name.Function),
392 (r'(^[ \t]*)([\w]+)([ \t]*\([\w\s,]*\)[ \t]*)(is|as)',
393 bygroups(Text, Name.Function, Text, Keyword)),
394 (r'\b[A-Z]\w*\b', Keyword.Type),
395 (r'(true|false)\b', Keyword.Constant),
396 (r'".*"', String),
397 (r'\'.\'', String.Char),
398 (r'(><|->|-m->|/\\|<=|<<=|<\.|\|\||\|\^\||-~->|-~m->|\\/|>=|>>|'
399 r'\.>|\+\+|-\\|<->|=>|:-|~=|\*\*|<<|>>=|\+>|!!|\|=\||#)',
400 Operator),
401 (r'[0-9]+\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
402 (r'0x[0-9a-f]+', Number.Hex),
403 (r'[0-9]+', Number.Integer),
404 (r'.', Text),
405 ],
406 }
407
408 def analyse_text(text):
409 """
410 Check for the most common text in the beginning of a RSL file.
411 """
412 if re.search(r'scheme\s*.*?=\s*class\s*type', text, re.I) is not None:
413 return 1.0
414
415
416 class MscgenLexer(RegexLexer):
417 """
418 For `Mscgen <http://www.mcternan.me.uk/mscgen/>`_ files.
419
420 .. versionadded:: 1.6
421 """
422 name = 'Mscgen'
423 aliases = ['mscgen', 'msc']
424 filenames = ['*.msc']
425
426 _var = r'(\w+|"(?:\\"|[^"])*")'
427
428 tokens = {
429 'root': [
430 (r'msc\b', Keyword.Type),
431 # Options
432 (r'(hscale|HSCALE|width|WIDTH|wordwraparcs|WORDWRAPARCS'
433 r'|arcgradient|ARCGRADIENT)\b', Name.Property),
434 # Operators
435 (r'(abox|ABOX|rbox|RBOX|box|BOX|note|NOTE)\b', Operator.Word),
436 (r'(\.|-|\|){3}', Keyword),
437 (r'(?:-|=|\.|:){2}'
438 r'|<<=>>|<->|<=>|<<>>|<:>'
439 r'|->|=>>|>>|=>|:>|-x|-X'
440 r'|<-|<<=|<<|<=|<:|x-|X-|=', Operator),
441 # Names
442 (r'\*', Name.Builtin),
443 (_var, Name.Variable),
444 # Other
445 (r'\[', Punctuation, 'attrs'),
446 (r'\{|\}|,|;', Punctuation),
447 include('comments')
448 ],
449 'attrs': [
450 (r'\]', Punctuation, '#pop'),
451 (_var + r'(\s*)(=)(\s*)' + _var,
452 bygroups(Name.Attribute, Text.Whitespace, Operator, Text.Whitespace,
453 String)),
454 (r',', Punctuation),
455 include('comments')
456 ],
457 'comments': [
458 (r'(?://|#).*?\n', Comment.Single),
459 (r'/\*(?:.|\n)*?\*/', Comment.Multiline),
460 (r'[ \t\r\n]+', Text.Whitespace)
461 ]
462 }
463
464
465 class VGLLexer(RegexLexer):
466 """
467 For `SampleManager VGL <http://www.thermoscientific.com/samplemanager>`_
468 source code.
469
470 .. versionadded:: 1.6
471 """
472 name = 'VGL'
473 aliases = ['vgl']
474 filenames = ['*.rpf']
475
476 flags = re.MULTILINE | re.DOTALL | re.IGNORECASE
477
478 tokens = {
479 'root': [
480 (r'\{[^}]*\}', Comment.Multiline),
481 (r'declare', Keyword.Constant),
482 (r'(if|then|else|endif|while|do|endwhile|and|or|prompt|object'
483 r'|create|on|line|with|global|routine|value|endroutine|constant'
484 r'|global|set|join|library|compile_option|file|exists|create|copy'
485 r'|delete|enable|windows|name|notprotected)(?! *[=<>.,()])',
486 Keyword),
487 (r'(true|false|null|empty|error|locked)', Keyword.Constant),
488 (r'[~^*#!%&\[\]()<>|+=:;,./?-]', Operator),
489 (r'"[^"]*"', String),
490 (r'(\.)([a-z_$][\w$]*)', bygroups(Operator, Name.Attribute)),
491 (r'[0-9][0-9]*(\.[0-9]+(e[+\-]?[0-9]+)?)?', Number),
492 (r'[a-z_$][\w$]*', Name),
493 (r'[\r\n]+', Text),
494 (r'\s+', Text)
495 ]
496 }
497
498
499 class AlloyLexer(RegexLexer):
500 """
501 For `Alloy <http://alloy.mit.edu>`_ source code.
502
503 .. versionadded:: 2.0
504 """
505
506 name = 'Alloy'
507 aliases = ['alloy']
508 filenames = ['*.als']
509 mimetypes = ['text/x-alloy']
510
511 flags = re.MULTILINE | re.DOTALL
512
513 iden_rex = r'[a-zA-Z_][\w\']*'
514 text_tuple = (r'[^\S\n]+', Text)
515
516 tokens = {
517 'sig': [
518 (r'(extends)\b', Keyword, '#pop'),
519 (iden_rex, Name),
520 text_tuple,
521 (r',', Punctuation),
522 (r'\{', Operator, '#pop'),
523 ],
524 'module': [
525 text_tuple,
526 (iden_rex, Name, '#pop'),
527 ],
528 'fun': [
529 text_tuple,
530 (r'\{', Operator, '#pop'),
531 (iden_rex, Name, '#pop'),
532 ],
533 'root': [
534 (r'--.*?$', Comment.Single),
535 (r'//.*?$', Comment.Single),
536 (r'/\*.*?\*/', Comment.Multiline),
537 text_tuple,
538 (r'(module|open)(\s+)', bygroups(Keyword.Namespace, Text),
539 'module'),
540 (r'(sig|enum)(\s+)', bygroups(Keyword.Declaration, Text), 'sig'),
541 (r'(iden|univ|none)\b', Keyword.Constant),
542 (r'(int|Int)\b', Keyword.Type),
543 (r'(this|abstract|extends|set|seq|one|lone|let)\b', Keyword),
544 (r'(all|some|no|sum|disj|when|else)\b', Keyword),
545 (r'(run|check|for|but|exactly|expect|as)\b', Keyword),
546 (r'(and|or|implies|iff|in)\b', Operator.Word),
547 (r'(fun|pred|fact|assert)(\s+)', bygroups(Keyword, Text), 'fun'),
548 (r'!|#|&&|\+\+|<<|>>|>=|<=>|<=|\.|->', Operator),
549 (r'[-+/*%=<>&!^|~{}\[\]().]', Operator),
550 (iden_rex, Name),
551 (r'[:,]', Punctuation),
552 (r'[0-9]+', Number.Integer),
553 (r'"(\\\\|\\"|[^"])*"', String),
554 (r'\n', Text),
555 ]
556 }
557
558
559 class PanLexer(RegexLexer):
560 """
561 Lexer for `pan <http://github.com/quattor/pan/>`_ source files.
562
563 Based on tcsh lexer.
564
565 .. versionadded:: 2.0
566 """
567
568 name = 'Pan'
569 aliases = ['pan']
570 filenames = ['*.pan']
571
572 tokens = {
573 'root': [
574 include('basic'),
575 (r'\(', Keyword, 'paren'),
576 (r'\{', Keyword, 'curly'),
577 include('data'),
578 ],
579 'basic': [
580 (words((
581 'if', 'for', 'with', 'else', 'type', 'bind', 'while', 'valid', 'final',
582 'prefix', 'unique', 'object', 'foreach', 'include', 'template',
583 'function', 'variable', 'structure', 'extensible', 'declaration'),
584 prefix=r'\b', suffix=r'\s*\b'),
585 Keyword),
586 (words((
587 'file_contents', 'format', 'index', 'length', 'match', 'matches',
588 'replace', 'splice', 'split', 'substr', 'to_lowercase', 'to_uppercase',
589 'debug', 'error', 'traceback', 'deprecated', 'base64_decode',
590 'base64_encode', 'digest', 'escape', 'unescape', 'append', 'create',
591 'first', 'nlist', 'key', 'list', 'merge', 'next', 'prepend', 'is_boolean',
592 'is_defined', 'is_double', 'is_list', 'is_long', 'is_nlist', 'is_null',
593 'is_number', 'is_property', 'is_resource', 'is_string', 'to_boolean',
594 'to_double', 'to_long', 'to_string', 'clone', 'delete', 'exists',
595 'path_exists', 'if_exists', 'return', 'value'),
596 prefix=r'\b', suffix=r'\s*\b'),
597 Name.Builtin),
598 (r'#.*', Comment),
599 (r'\\[\w\W]', String.Escape),
600 (r'(\b\w+)(\s*)(=)', bygroups(Name.Variable, Text, Operator)),
601 (r'[\[\]{}()=]+', Operator),
602 (r'<<\s*(\'?)\\?(\w+)[\w\W]+?\2', String),
603 (r';', Punctuation),
604 ],
605 'data': [
606 (r'(?s)"(\\\\|\\[0-7]+|\\.|[^"\\])*"', String.Double),
607 (r"(?s)'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single),
608 (r'\s+', Text),
609 (r'[^=\s\[\]{}()$"\'`\\;#]+', Text),
610 (r'\d+(?= |\Z)', Number),
611 ],
612 'curly': [
613 (r'\}', Keyword, '#pop'),
614 (r':-', Keyword),
615 (r'\w+', Name.Variable),
616 (r'[^}:"\'`$]+', Punctuation),
617 (r':', Punctuation),
618 include('root'),
619 ],
620 'paren': [
621 (r'\)', Keyword, '#pop'),
622 include('root'),
623 ],
624 }
625
626
627 class CrmshLexer(RegexLexer):
628 """
629 Lexer for `crmsh <http://crmsh.github.io/>`_ configuration files
630 for Pacemaker clusters.
631
632 .. versionadded:: 2.1
633 """
634 name = 'Crmsh'
635 aliases = ['crmsh', 'pcmk']
636 filenames = ['*.crmsh', '*.pcmk']
637 mimetypes = []
638
639 elem = words((
640 'node', 'primitive', 'group', 'clone', 'ms', 'location',
641 'colocation', 'order', 'fencing_topology', 'rsc_ticket',
642 'rsc_template', 'property', 'rsc_defaults',
643 'op_defaults', 'acl_target', 'acl_group', 'user', 'role',
644 'tag'), suffix=r'(?![\w#$-])')
645 sub = words((
646 'params', 'meta', 'operations', 'op', 'rule',
647 'attributes', 'utilization'), suffix=r'(?![\w#$-])')
648 acl = words(('read', 'write', 'deny'), suffix=r'(?![\w#$-])')
649 bin_rel = words(('and', 'or'), suffix=r'(?![\w#$-])')
650 un_ops = words(('defined', 'not_defined'), suffix=r'(?![\w#$-])')
651 date_exp = words(('in_range', 'date', 'spec', 'in'), suffix=r'(?![\w#$-])')
652 acl_mod = (r'(?:tag|ref|reference|attribute|type|xpath)')
653 bin_ops = (r'(?:lt|gt|lte|gte|eq|ne)')
654 val_qual = (r'(?:string|version|number)')
655 rsc_role_action = (r'(?:Master|Started|Slave|Stopped|'
656 r'start|promote|demote|stop)')
657
658 tokens = {
659 'root': [
660 (r'^#.*\n?', Comment),
661 # attr=value (nvpair)
662 (r'([\w#$-]+)(=)("(?:""|[^"])*"|\S+)',
663 bygroups(Name.Attribute, Punctuation, String)),
664 # need this construct, otherwise numeric node ids
665 # are matched as scores
666 # elem id:
667 (r'(node)(\s+)([\w#$-]+)(:)',
668 bygroups(Keyword, Whitespace, Name, Punctuation)),
669 # scores
670 (r'([+-]?([0-9]+|inf)):', Number),
671 # keywords (elements and other)
672 (elem, Keyword),
673 (sub, Keyword),
674 (acl, Keyword),
675 # binary operators
676 (r'(?:%s:)?(%s)(?![\w#$-])' % (val_qual, bin_ops), Operator.Word),
677 # other operators
678 (bin_rel, Operator.Word),
679 (un_ops, Operator.Word),
680 (date_exp, Operator.Word),
681 # builtin attributes (e.g. #uname)
682 (r'#[a-z]+(?![\w#$-])', Name.Builtin),
683 # acl_mod:blah
684 (r'(%s)(:)("(?:""|[^"])*"|\S+)' % acl_mod,
685 bygroups(Keyword, Punctuation, Name)),
686 # rsc_id[:(role|action)]
687 # NB: this matches all other identifiers
688 (r'([\w#$-]+)(?:(:)(%s))?(?![\w#$-])' % rsc_role_action,
689 bygroups(Name, Punctuation, Operator.Word)),
690 # punctuation
691 (r'(\\(?=\n)|[\[\](){}/:@])', Punctuation),
692 (r'\s+|\n', Whitespace),
693 ],
694 }
695
696
697 class FlatlineLexer(RegexLexer):
698 """
699 Lexer for `Flatline <https://github.com/bigmlcom/flatline>`_ expressions.
700
701 .. versionadded:: 2.2
702 """
703 name = 'Flatline'
704 aliases = ['flatline']
705 filenames = []
706 mimetypes = ['text/x-flatline']
707
708 special_forms = ('let',)
709
710 builtins = (
711 "!=", "*", "+", "-", "<", "<=", "=", ">", ">=", "abs", "acos", "all",
712 "all-but", "all-with-defaults", "all-with-numeric-default", "and",
713 "asin", "atan", "avg", "avg-window", "bin-center", "bin-count", "call",
714 "category-count", "ceil", "cond", "cond-window", "cons", "cos", "cosh",
715 "count", "diff-window", "div", "ensure-value", "ensure-weighted-value",
716 "epoch", "epoch-day", "epoch-fields", "epoch-hour", "epoch-millisecond",
717 "epoch-minute", "epoch-month", "epoch-second", "epoch-weekday",
718 "epoch-year", "exp", "f", "field", "field-prop", "fields", "filter",
719 "first", "floor", "head", "if", "in", "integer", "language", "length",
720 "levenshtein", "linear-regression", "list", "ln", "log", "log10", "map",
721 "matches", "matches?", "max", "maximum", "md5", "mean", "median", "min",
722 "minimum", "missing", "missing-count", "missing?", "missing_count",
723 "mod", "mode", "normalize", "not", "nth", "occurrences", "or",
724 "percentile", "percentile-label", "population", "population-fraction",
725 "pow", "preferred", "preferred?", "quantile-label", "rand", "rand-int",
726 "random-value", "re-quote", "real", "replace", "replace-first", "rest",
727 "round", "row-number", "segment-label", "sha1", "sha256", "sin", "sinh",
728 "sqrt", "square", "standard-deviation", "standard_deviation", "str",
729 "subs", "sum", "sum-squares", "sum-window", "sum_squares", "summary",
730 "summary-no", "summary-str", "tail", "tan", "tanh", "to-degrees",
731 "to-radians", "variance", "vectorize", "weighted-random-value", "window",
732 "winnow", "within-percentiles?", "z-score",
733 )
734
735 valid_name = r'(?!#)[\w!$%*+<=>?/.#-]+'
736
737 tokens = {
738 'root': [
739 # whitespaces - usually not relevant
740 (r'[,\s]+', Text),
741
742 # numbers
743 (r'-?\d+\.\d+', Number.Float),
744 (r'-?\d+', Number.Integer),
745 (r'0x-?[a-f\d]+', Number.Hex),
746
747 # strings, symbols and characters
748 (r'"(\\\\|\\"|[^"])*"', String),
749 (r"\\(.|[a-z]+)", String.Char),
750
751 # expression template placeholder
752 (r'_', String.Symbol),
753
754 # highlight the special forms
755 (words(special_forms, suffix=' '), Keyword),
756
757 # highlight the builtins
758 (words(builtins, suffix=' '), Name.Builtin),
759
760 # the remaining functions
761 (r'(?<=\()' + valid_name, Name.Function),
762
763 # find the remaining variables
764 (valid_name, Name.Variable),
765
766 # parentheses
767 (r'(\(|\))', Punctuation),
768 ],
769 }
770
771
772 class SnowballLexer(ExtendedRegexLexer):
773 """
774 Lexer for `Snowball <http://snowballstem.org/>`_ source code.
775
776 .. versionadded:: 2.2
777 """
778
779 name = 'Snowball'
780 aliases = ['snowball']
781 filenames = ['*.sbl']
782
783 _ws = r'\n\r\t '
784
785 def __init__(self, **options):
786 self._reset_stringescapes()
787 ExtendedRegexLexer.__init__(self, **options)
788
789 def _reset_stringescapes(self):
790 self._start = "'"
791 self._end = "'"
792
793 def _string(do_string_first):
794 def callback(lexer, match, ctx):
795 s = match.start()
796 text = match.group()
797 string = re.compile(r'([^%s]*)(.)' % re.escape(lexer._start)).match
798 escape = re.compile(r'([^%s]*)(.)' % re.escape(lexer._end)).match
799 pos = 0
800 do_string = do_string_first
801 while pos < len(text):
802 if do_string:
803 match = string(text, pos)
804 yield s + match.start(1), String.Single, match.group(1)
805 if match.group(2) == "'":
806 yield s + match.start(2), String.Single, match.group(2)
807 ctx.stack.pop()
808 break
809 yield s + match.start(2), String.Escape, match.group(2)
810 pos = match.end()
811 match = escape(text, pos)
812 yield s + match.start(), String.Escape, match.group()
813 if match.group(2) != lexer._end:
814 ctx.stack[-1] = 'escape'
815 break
816 pos = match.end()
817 do_string = True
818 ctx.pos = s + match.end()
819 return callback
820
821 def _stringescapes(lexer, match, ctx):
822 lexer._start = match.group(3)
823 lexer._end = match.group(5)
824 return bygroups(Keyword.Reserved, Text, String.Escape, Text,
825 String.Escape)(lexer, match, ctx)
826
827 tokens = {
828 'root': [
829 (words(('len', 'lenof'), suffix=r'\b'), Operator.Word),
830 include('root1'),
831 ],
832 'root1': [
833 (r'[%s]+' % _ws, Text),
834 (r'\d+', Number.Integer),
835 (r"'", String.Single, 'string'),
836 (r'[()]', Punctuation),
837 (r'/\*[\w\W]*?\*/', Comment.Multiline),
838 (r'//.*', Comment.Single),
839 (r'[!*+\-/<=>]=|[-=]>|<[+-]|[$*+\-/<=>?\[\]]', Operator),
840 (words(('as', 'get', 'hex', 'among', 'define', 'decimal',
841 'backwardmode'), suffix=r'\b'),
842 Keyword.Reserved),
843 (words(('strings', 'booleans', 'integers', 'routines', 'externals',
844 'groupings'), suffix=r'\b'),
845 Keyword.Reserved, 'declaration'),
846 (words(('do', 'or', 'and', 'for', 'hop', 'non', 'not', 'set', 'try',
847 'fail', 'goto', 'loop', 'next', 'test', 'true',
848 'false', 'unset', 'atmark', 'attach', 'delete', 'gopast',
849 'insert', 'repeat', 'sizeof', 'tomark', 'atleast',
850 'atlimit', 'reverse', 'setmark', 'tolimit', 'setlimit',
851 'backwards', 'substring'), suffix=r'\b'),
852 Operator.Word),
853 (words(('size', 'limit', 'cursor', 'maxint', 'minint'),
854 suffix=r'\b'),
855 Name.Builtin),
856 (r'(stringdef\b)([%s]*)([^%s]+)' % (_ws, _ws),
857 bygroups(Keyword.Reserved, Text, String.Escape)),
858 (r'(stringescapes\b)([%s]*)(.)([%s]*)(.)' % (_ws, _ws),
859 _stringescapes),
860 (r'[A-Za-z]\w*', Name),
861 ],
862 'declaration': [
863 (r'\)', Punctuation, '#pop'),
864 (words(('len', 'lenof'), suffix=r'\b'), Name,
865 ('root1', 'declaration')),
866 include('root1'),
867 ],
868 'string': [
869 (r"[^']*'", _string(True)),
870 ],
871 'escape': [
872 (r"[^']*'", _string(False)),
873 ],
874 }
875
876 def get_tokens_unprocessed(self, text=None, context=None):
877 self._reset_stringescapes()
878 return ExtendedRegexLexer.get_tokens_unprocessed(self, text, context)

eric ide

mercurial