1"""
2 pygments.lexers.scripting
3 ~~~~~~~~~~~~~~~~~~~~~~~~~
4
5 Lexer for scripting and embedded languages.
6
7 :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8 :license: BSD, see LICENSE for details.
9"""
10
11import re
12
13from pygments.lexer import RegexLexer, include, bygroups, default, combined, \
14 words
15from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
16 Number, Punctuation, Error, Whitespace, Other
17from pygments.util import get_bool_opt, get_list_opt
18
19__all__ = ['LuaLexer', 'LuauLexer', 'MoonScriptLexer', 'ChaiscriptLexer', 'LSLLexer',
20 'AppleScriptLexer', 'RexxLexer', 'MOOCodeLexer', 'HybrisLexer',
21 'EasytrieveLexer', 'JclLexer', 'MiniScriptLexer']
22
23
24def all_lua_builtins():
25 from pygments.lexers._lua_builtins import MODULES
26 return [w for values in MODULES.values() for w in values]
27
28class LuaLexer(RegexLexer):
29 """
30 For Lua source code.
31
32 Additional options accepted:
33
34 `func_name_highlighting`
35 If given and ``True``, highlight builtin function names
36 (default: ``True``).
37 `disabled_modules`
38 If given, must be a list of module names whose function names
39 should not be highlighted. By default all modules are highlighted.
40
41 To get a list of allowed modules have a look into the
42 `_lua_builtins` module:
43
44 .. sourcecode:: pycon
45
46 >>> from pygments.lexers._lua_builtins import MODULES
47 >>> MODULES.keys()
48 ['string', 'coroutine', 'modules', 'io', 'basic', ...]
49 """
50
51 name = 'Lua'
52 url = 'https://www.lua.org/'
53 aliases = ['lua']
54 filenames = ['*.lua', '*.wlua']
55 mimetypes = ['text/x-lua', 'application/x-lua']
56 version_added = ''
57
58 _comment_multiline = r'(?:--\[(?P<level>=*)\[[\w\W]*?\](?P=level)\])'
59 _comment_single = r'(?:--.*$)'
60 _space = r'(?:\s+(?!\s))'
61 _s = rf'(?:{_comment_multiline}|{_comment_single}|{_space})'
62 _name = r'(?:[^\W\d]\w*)'
63
64 tokens = {
65 'root': [
66 # Lua allows a file to start with a shebang.
67 (r'#!.*', Comment.Preproc),
68 default('base'),
69 ],
70 'ws': [
71 (_comment_multiline, Comment.Multiline),
72 (_comment_single, Comment.Single),
73 (_space, Whitespace),
74 ],
75 'base': [
76 include('ws'),
77
78 (r'(?i)0x[\da-f]*(\.[\da-f]*)?(p[+-]?\d+)?', Number.Hex),
79 (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number.Float),
80 (r'(?i)\d+e[+-]?\d+', Number.Float),
81 (r'\d+', Number.Integer),
82
83 # multiline strings
84 (r'(?s)\[(=*)\[.*?\]\1\]', String),
85
86 (r'::', Punctuation, 'label'),
87 (r'\.{3}', Punctuation),
88 (r'[=<>|~&+\-*/%#^]+|\.\.', Operator),
89 (r'[\[\]{}().,:;]+', Punctuation),
90 (r'(and|or|not)\b', Operator.Word),
91
92 (words([
93 'break', 'do', 'else', 'elseif', 'end', 'for', 'if', 'in',
94 'repeat', 'return', 'then', 'until', 'while'
95 ], suffix=r'\b'), Keyword.Reserved),
96 (r'goto\b', Keyword.Reserved, 'goto'),
97 (r'(local)\b', Keyword.Declaration),
98 (r'(true|false|nil)\b', Keyword.Constant),
99
100 (r'(function)\b', Keyword.Reserved, 'funcname'),
101
102 (words(all_lua_builtins(), suffix=r"\b"), Name.Builtin),
103 (fr'[A-Za-z_]\w*(?={_s}*[.:])', Name.Variable, 'varname'),
104 (fr'[A-Za-z_]\w*(?={_s}*\()', Name.Function),
105 (r'[A-Za-z_]\w*', Name.Variable),
106
107 ("'", String.Single, combined('stringescape', 'sqs')),
108 ('"', String.Double, combined('stringescape', 'dqs'))
109 ],
110
111 'varname': [
112 include('ws'),
113 (r'\.\.', Operator, '#pop'),
114 (r'[.:]', Punctuation),
115 (rf'{_name}(?={_s}*[.:])', Name.Property),
116 (rf'{_name}(?={_s}*\()', Name.Function, '#pop'),
117 (_name, Name.Property, '#pop'),
118 ],
119
120 'funcname': [
121 include('ws'),
122 (r'[.:]', Punctuation),
123 (rf'{_name}(?={_s}*[.:])', Name.Class),
124 (_name, Name.Function, '#pop'),
125 # inline function
126 (r'\(', Punctuation, '#pop'),
127 ],
128
129 'goto': [
130 include('ws'),
131 (_name, Name.Label, '#pop'),
132 ],
133
134 'label': [
135 include('ws'),
136 (r'::', Punctuation, '#pop'),
137 (_name, Name.Label),
138 ],
139
140 'stringescape': [
141 (r'\\([abfnrtv\\"\']|[\r\n]{1,2}|z\s*|x[0-9a-fA-F]{2}|\d{1,3}|'
142 r'u\{[0-9a-fA-F]+\})', String.Escape),
143 ],
144
145 'sqs': [
146 (r"'", String.Single, '#pop'),
147 (r"[^\\']+", String.Single),
148 ],
149
150 'dqs': [
151 (r'"', String.Double, '#pop'),
152 (r'[^\\"]+', String.Double),
153 ]
154 }
155
156 def __init__(self, **options):
157 self.func_name_highlighting = get_bool_opt(
158 options, 'func_name_highlighting', True)
159 self.disabled_modules = get_list_opt(options, 'disabled_modules', [])
160
161 self._functions = set()
162 if self.func_name_highlighting:
163 from pygments.lexers._lua_builtins import MODULES
164 for mod, func in MODULES.items():
165 if mod not in self.disabled_modules:
166 self._functions.update(func)
167 RegexLexer.__init__(self, **options)
168
169 def get_tokens_unprocessed(self, text):
170 for index, token, value in \
171 RegexLexer.get_tokens_unprocessed(self, text):
172 if token is Name.Builtin and value not in self._functions:
173 if '.' in value:
174 a, b = value.split('.')
175 yield index, Name, a
176 yield index + len(a), Punctuation, '.'
177 yield index + len(a) + 1, Name, b
178 else:
179 yield index, Name, value
180 continue
181 yield index, token, value
182
183def _luau_make_expression(should_pop, _s):
184 temp_list = [
185 (r'0[xX][\da-fA-F_]*', Number.Hex, '#pop'),
186 (r'0[bB][\d_]*', Number.Bin, '#pop'),
187 (r'\.?\d[\d_]*(?:\.[\d_]*)?(?:[eE][+-]?[\d_]+)?', Number.Float, '#pop'),
188
189 (words((
190 'true', 'false', 'nil'
191 ), suffix=r'\b'), Keyword.Constant, '#pop'),
192
193 (r'\[(=*)\[[.\n]*?\]\1\]', String, '#pop'),
194
195 (r'(\.)([a-zA-Z_]\w*)(?=%s*[({"\'])', bygroups(Punctuation, Name.Function), '#pop'),
196 (r'(\.)([a-zA-Z_]\w*)', bygroups(Punctuation, Name.Variable), '#pop'),
197
198 (rf'[a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*(?={_s}*[({{"\'])', Name.Other, '#pop'),
199 (r'[a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*', Name, '#pop'),
200 ]
201 if should_pop:
202 return temp_list
203 return [entry[:2] for entry in temp_list]
204
205def _luau_make_expression_special(should_pop):
206 temp_list = [
207 (r'\{', Punctuation, ('#pop', 'closing_brace_base', 'expression')),
208 (r'\(', Punctuation, ('#pop', 'closing_parenthesis_base', 'expression')),
209
210 (r'::?', Punctuation, ('#pop', 'type_end', 'type_start')),
211
212 (r"'", String.Single, ('#pop', 'string_single')),
213 (r'"', String.Double, ('#pop', 'string_double')),
214 (r'`', String.Backtick, ('#pop', 'string_interpolated')),
215 ]
216 if should_pop:
217 return temp_list
218 return [(entry[0], entry[1], entry[2][1:]) for entry in temp_list]
219
220class LuauLexer(RegexLexer):
221 """
222 For Luau source code.
223
224 Additional options accepted:
225
226 `include_luau_builtins`
227 If given and ``True``, automatically highlight Luau builtins
228 (default: ``True``).
229 `include_roblox_builtins`
230 If given and ``True``, automatically highlight Roblox-specific builtins
231 (default: ``False``).
232 `additional_builtins`
233 If given, must be a list of additional builtins to highlight.
234 `disabled_builtins`
235 If given, must be a list of builtins that will not be highlighted.
236 """
237
238 name = 'Luau'
239 url = 'https://luau-lang.org/'
240 aliases = ['luau']
241 filenames = ['*.luau']
242 version_added = '2.18'
243
244 _comment_multiline = r'(?:--\[(?P<level>=*)\[[\w\W]*?\](?P=level)\])'
245 _comment_single = r'(?:--.*$)'
246 _s = r'(?:{}|{}|{})'.format(_comment_multiline, _comment_single, r'\s+')
247
248 tokens = {
249 'root': [
250 (r'#!.*', Comment.Hashbang, 'base'),
251 default('base'),
252 ],
253
254 'ws': [
255 (_comment_multiline, Comment.Multiline),
256 (_comment_single, Comment.Single),
257 (r'\s+', Whitespace),
258 ],
259
260 'base': [
261 include('ws'),
262
263 *_luau_make_expression_special(False),
264 (r'\.\.\.', Punctuation),
265
266 (rf'type\b(?={_s}+[a-zA-Z_])', Keyword.Reserved, 'type_declaration'),
267 (rf'export\b(?={_s}+[a-zA-Z_])', Keyword.Reserved),
268
269 (r'(?:\.\.|//|[+\-*\/%^<>=])=?', Operator, 'expression'),
270 (r'~=', Operator, 'expression'),
271
272 (words((
273 'and', 'or', 'not'
274 ), suffix=r'\b'), Operator.Word, 'expression'),
275
276 (words((
277 'elseif', 'for', 'if', 'in', 'repeat', 'return', 'until',
278 'while'), suffix=r'\b'), Keyword.Reserved, 'expression'),
279 (r'local\b', Keyword.Declaration, 'expression'),
280
281 (r'function\b', Keyword.Reserved, ('expression', 'func_name')),
282
283 (r'[\])};]+', Punctuation),
284
285 include('expression_static'),
286 *_luau_make_expression(False, _s),
287
288 (r'[\[.,]', Punctuation, 'expression'),
289 ],
290 'expression_static': [
291 (words((
292 'break', 'continue', 'do', 'else', 'elseif', 'end', 'for',
293 'if', 'in', 'repeat', 'return', 'then', 'until', 'while'),
294 suffix=r'\b'), Keyword.Reserved),
295 ],
296 'expression': [
297 include('ws'),
298
299 (r'if\b', Keyword.Reserved, ('ternary', 'expression')),
300
301 (r'local\b', Keyword.Declaration),
302 *_luau_make_expression_special(True),
303 (r'\.\.\.', Punctuation, '#pop'),
304
305 (r'function\b', Keyword.Reserved, 'func_name'),
306
307 include('expression_static'),
308 *_luau_make_expression(True, _s),
309
310 default('#pop'),
311 ],
312 'ternary': [
313 include('ws'),
314
315 (r'else\b', Keyword.Reserved, '#pop'),
316 (words((
317 'then', 'elseif',
318 ), suffix=r'\b'), Operator.Reserved, 'expression'),
319
320 default('#pop'),
321 ],
322
323 'closing_brace_pop': [
324 (r'\}', Punctuation, '#pop'),
325 ],
326 'closing_parenthesis_pop': [
327 (r'\)', Punctuation, '#pop'),
328 ],
329 'closing_gt_pop': [
330 (r'>', Punctuation, '#pop'),
331 ],
332
333 'closing_parenthesis_base': [
334 include('closing_parenthesis_pop'),
335 include('base'),
336 ],
337 'closing_parenthesis_type': [
338 include('closing_parenthesis_pop'),
339 include('type'),
340 ],
341 'closing_brace_base': [
342 include('closing_brace_pop'),
343 include('base'),
344 ],
345 'closing_brace_type': [
346 include('closing_brace_pop'),
347 include('type'),
348 ],
349 'closing_gt_type': [
350 include('closing_gt_pop'),
351 include('type'),
352 ],
353
354 'string_escape': [
355 (r'\\z\s*', String.Escape),
356 (r'\\(?:[abfnrtvz\\"\'`\{\n])|[\r\n]{1,2}|x[\da-fA-F]{2}|\d{1,3}|'
357 r'u\{\}[\da-fA-F]*\}', String.Escape),
358 ],
359 'string_single': [
360 include('string_escape'),
361
362 (r"'", String.Single, "#pop"),
363 (r"[^\\']+", String.Single),
364 ],
365 'string_double': [
366 include('string_escape'),
367
368 (r'"', String.Double, "#pop"),
369 (r'[^\\"]+', String.Double),
370 ],
371 'string_interpolated': [
372 include('string_escape'),
373
374 (r'\{', Punctuation, ('closing_brace_base', 'expression')),
375
376 (r'`', String.Backtick, "#pop"),
377 (r'[^\\`\{]+', String.Backtick),
378 ],
379
380 'func_name': [
381 include('ws'),
382
383 (r'[.:]', Punctuation),
384 (rf'[a-zA-Z_]\w*(?={_s}*[.:])', Name.Class),
385 (r'[a-zA-Z_]\w*', Name.Function),
386
387 (r'<', Punctuation, 'closing_gt_type'),
388
389 (r'\(', Punctuation, '#pop'),
390 ],
391
392 'type': [
393 include('ws'),
394
395 (r'\(', Punctuation, 'closing_parenthesis_type'),
396 (r'\{', Punctuation, 'closing_brace_type'),
397 (r'<', Punctuation, 'closing_gt_type'),
398
399 (r"'", String.Single, 'string_single'),
400 (r'"', String.Double, 'string_double'),
401
402 (r'[|&\.,\[\]:=]+', Punctuation),
403 (r'->', Punctuation),
404
405 (r'typeof\(', Name.Builtin, ('closing_parenthesis_base',
406 'expression')),
407 (r'[a-zA-Z_]\w*', Name.Class),
408 ],
409 'type_start': [
410 include('ws'),
411
412 (r'\(', Punctuation, ('#pop', 'closing_parenthesis_type')),
413 (r'\{', Punctuation, ('#pop', 'closing_brace_type')),
414 (r'<', Punctuation, ('#pop', 'closing_gt_type')),
415
416 (r"'", String.Single, ('#pop', 'string_single')),
417 (r'"', String.Double, ('#pop', 'string_double')),
418
419 (r'typeof\(', Name.Builtin, ('#pop', 'closing_parenthesis_base',
420 'expression')),
421 (r'[a-zA-Z_]\w*', Name.Class, '#pop'),
422 ],
423 'type_end': [
424 include('ws'),
425
426 (r'[|&\.]', Punctuation, 'type_start'),
427 (r'->', Punctuation, 'type_start'),
428
429 (r'<', Punctuation, 'closing_gt_type'),
430
431 default('#pop'),
432 ],
433 'type_declaration': [
434 include('ws'),
435
436 (r'[a-zA-Z_]\w*', Name.Class),
437 (r'<', Punctuation, 'closing_gt_type'),
438
439 (r'=', Punctuation, ('#pop', 'type_end', 'type_start')),
440 ],
441 }
442
443 def __init__(self, **options):
444 self.include_luau_builtins = get_bool_opt(
445 options, 'include_luau_builtins', True)
446 self.include_roblox_builtins = get_bool_opt(
447 options, 'include_roblox_builtins', False)
448 self.additional_builtins = get_list_opt(options, 'additional_builtins', [])
449 self.disabled_builtins = get_list_opt(options, 'disabled_builtins', [])
450
451 self._builtins = set(self.additional_builtins)
452 if self.include_luau_builtins:
453 from pygments.lexers._luau_builtins import LUAU_BUILTINS
454 self._builtins.update(LUAU_BUILTINS)
455 if self.include_roblox_builtins:
456 from pygments.lexers._luau_builtins import ROBLOX_BUILTINS
457 self._builtins.update(ROBLOX_BUILTINS)
458 if self.additional_builtins:
459 self._builtins.update(self.additional_builtins)
460 self._builtins.difference_update(self.disabled_builtins)
461
462 RegexLexer.__init__(self, **options)
463
464 def get_tokens_unprocessed(self, text):
465 for index, token, value in \
466 RegexLexer.get_tokens_unprocessed(self, text):
467 if token is Name or token is Name.Other:
468 split_value = value.split('.')
469 complete_value = []
470 new_index = index
471 for position in range(len(split_value), 0, -1):
472 potential_string = '.'.join(split_value[:position])
473 if potential_string in self._builtins:
474 yield index, Name.Builtin, potential_string
475 new_index += len(potential_string)
476
477 if complete_value:
478 yield new_index, Punctuation, '.'
479 new_index += 1
480 break
481 complete_value.insert(0, split_value[position - 1])
482
483 for position, substring in enumerate(complete_value):
484 if position + 1 == len(complete_value):
485 if token is Name:
486 yield new_index, Name.Variable, substring
487 continue
488 yield new_index, Name.Function, substring
489 continue
490 yield new_index, Name.Variable, substring
491 new_index += len(substring)
492 yield new_index, Punctuation, '.'
493 new_index += 1
494
495 continue
496 yield index, token, value
497
498class MoonScriptLexer(LuaLexer):
499 """
500 For MoonScript source code.
501 """
502
503 name = 'MoonScript'
504 url = 'http://moonscript.org'
505 aliases = ['moonscript', 'moon']
506 filenames = ['*.moon']
507 mimetypes = ['text/x-moonscript', 'application/x-moonscript']
508 version_added = '1.5'
509
510 tokens = {
511 'root': [
512 (r'#!(.*?)$', Comment.Preproc),
513 default('base'),
514 ],
515 'base': [
516 ('--.*$', Comment.Single),
517 (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number.Float),
518 (r'(?i)\d+e[+-]?\d+', Number.Float),
519 (r'(?i)0x[0-9a-f]*', Number.Hex),
520 (r'\d+', Number.Integer),
521 (r'\n', Whitespace),
522 (r'[^\S\n]+', Text),
523 (r'(?s)\[(=*)\[.*?\]\1\]', String),
524 (r'(->|=>)', Name.Function),
525 (r':[a-zA-Z_]\w*', Name.Variable),
526 (r'(==|!=|~=|<=|>=|\.\.\.|\.\.|[=+\-*/%^<>#!.\\:])', Operator),
527 (r'[;,]', Punctuation),
528 (r'[\[\]{}()]', Keyword.Type),
529 (r'[a-zA-Z_]\w*:', Name.Variable),
530 (words((
531 'class', 'extends', 'if', 'then', 'super', 'do', 'with',
532 'import', 'export', 'while', 'elseif', 'return', 'for', 'in',
533 'from', 'when', 'using', 'else', 'and', 'or', 'not', 'switch',
534 'break'), suffix=r'\b'),
535 Keyword),
536 (r'(true|false|nil)\b', Keyword.Constant),
537 (r'(and|or|not)\b', Operator.Word),
538 (r'(self)\b', Name.Builtin.Pseudo),
539 (r'@@?([a-zA-Z_]\w*)?', Name.Variable.Class),
540 (r'[A-Z]\w*', Name.Class), # proper name
541 (words(all_lua_builtins(), suffix=r"\b"), Name.Builtin),
542 (r'[A-Za-z_]\w*', Name),
543 ("'", String.Single, combined('stringescape', 'sqs')),
544 ('"', String.Double, combined('stringescape', 'dqs'))
545 ],
546 'stringescape': [
547 (r'''\\([abfnrtv\\"']|\d{1,3})''', String.Escape)
548 ],
549 'strings': [
550 (r'[^#\\\'"]+', String),
551 # note that strings are multi-line.
552 # hashmarks, quotes and backslashes must be parsed one at a time
553 ],
554 'interpoling_string': [
555 (r'\}', String.Interpol, "#pop"),
556 include('base')
557 ],
558 'dqs': [
559 (r'"', String.Double, '#pop'),
560 (r'\\.|\'', String), # double-quoted string don't need ' escapes
561 (r'#\{', String.Interpol, "interpoling_string"),
562 (r'#', String),
563 include('strings')
564 ],
565 'sqs': [
566 (r"'", String.Single, '#pop'),
567 (r'#|\\.|"', String), # single quoted strings don't need " escapses
568 include('strings')
569 ]
570 }
571
572 def get_tokens_unprocessed(self, text):
573 # set . as Operator instead of Punctuation
574 for index, token, value in LuaLexer.get_tokens_unprocessed(self, text):
575 if token == Punctuation and value == ".":
576 token = Operator
577 yield index, token, value
578
579
580class ChaiscriptLexer(RegexLexer):
581 """
582 For ChaiScript source code.
583 """
584
585 name = 'ChaiScript'
586 url = 'http://chaiscript.com/'
587 aliases = ['chaiscript', 'chai']
588 filenames = ['*.chai']
589 mimetypes = ['text/x-chaiscript', 'application/x-chaiscript']
590 version_added = '2.0'
591
592 flags = re.DOTALL | re.MULTILINE
593
594 tokens = {
595 'commentsandwhitespace': [
596 (r'\s+', Text),
597 (r'//.*?\n', Comment.Single),
598 (r'/\*.*?\*/', Comment.Multiline),
599 (r'^\#.*?\n', Comment.Single)
600 ],
601 'slashstartsregex': [
602 include('commentsandwhitespace'),
603 (r'/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/'
604 r'([gim]+\b|\B)', String.Regex, '#pop'),
605 (r'(?=/)', Text, ('#pop', 'badregex')),
606 default('#pop')
607 ],
608 'badregex': [
609 (r'\n', Text, '#pop')
610 ],
611 'root': [
612 include('commentsandwhitespace'),
613 (r'\n', Text),
614 (r'[^\S\n]+', Text),
615 (r'\+\+|--|~|&&|\?|:|\|\||\\(?=\n)|\.\.'
616 r'(<<|>>>?|==?|!=?|[-<>+*%&|^/])=?', Operator, 'slashstartsregex'),
617 (r'[{(\[;,]', Punctuation, 'slashstartsregex'),
618 (r'[})\].]', Punctuation),
619 (r'[=+\-*/]', Operator),
620 (r'(for|in|while|do|break|return|continue|if|else|'
621 r'throw|try|catch'
622 r')\b', Keyword, 'slashstartsregex'),
623 (r'(var)\b', Keyword.Declaration, 'slashstartsregex'),
624 (r'(attr|def|fun)\b', Keyword.Reserved),
625 (r'(true|false)\b', Keyword.Constant),
626 (r'(eval|throw)\b', Name.Builtin),
627 (r'`\S+`', Name.Builtin),
628 (r'[$a-zA-Z_]\w*', Name.Other),
629 (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
630 (r'0x[0-9a-fA-F]+', Number.Hex),
631 (r'[0-9]+', Number.Integer),
632 (r'"', String.Double, 'dqstring'),
633 (r"'(\\\\|\\[^\\]|[^'\\])*'", String.Single),
634 ],
635 'dqstring': [
636 (r'\$\{[^"}]+?\}', String.Interpol),
637 (r'\$', String.Double),
638 (r'\\\\', String.Double),
639 (r'\\"', String.Double),
640 (r'[^\\"$]+', String.Double),
641 (r'"', String.Double, '#pop'),
642 ],
643 }
644
645
646class LSLLexer(RegexLexer):
647 """
648 For Second Life's Linden Scripting Language source code.
649 """
650
651 name = 'LSL'
652 aliases = ['lsl']
653 filenames = ['*.lsl']
654 mimetypes = ['text/x-lsl']
655 url = 'https://wiki.secondlife.com/wiki/Linden_Scripting_Language'
656 version_added = '2.0'
657
658 flags = re.MULTILINE
659
660 lsl_keywords = r'\b(?:do|else|for|if|jump|return|while)\b'
661 lsl_types = r'\b(?:float|integer|key|list|quaternion|rotation|string|vector)\b'
662 lsl_states = r'\b(?:(?:state)\s+\w+|default)\b'
663 lsl_events = r'\b(?:state_(?:entry|exit)|touch(?:_(?:start|end))?|(?:land_)?collision(?:_(?:start|end))?|timer|listen|(?:no_)?sensor|control|(?:not_)?at_(?:rot_)?target|money|email|run_time_permissions|changed|attach|dataserver|moving_(?:start|end)|link_message|(?:on|object)_rez|remote_data|http_re(?:sponse|quest)|path_update|transaction_result)\b'
664 lsl_functions_builtin = r'\b(?:ll(?:ReturnObjectsBy(?:ID|Owner)|Json(?:2List|[GS]etValue|ValueType)|Sin|Cos|Tan|Atan2|Sqrt|Pow|Abs|Fabs|Frand|Floor|Ceil|Round|Vec(?:Mag|Norm|Dist)|Rot(?:Between|2(?:Euler|Fwd|Left|Up))|(?:Euler|Axes)2Rot|Whisper|(?:Region|Owner)?Say|Shout|Listen(?:Control|Remove)?|Sensor(?:Repeat|Remove)?|Detected(?:Name|Key|Owner|Type|Pos|Vel|Grab|Rot|Group|LinkNumber)|Die|Ground|Wind|(?:[GS]et)(?:AnimationOverride|MemoryLimit|PrimMediaParams|ParcelMusicURL|Object(?:Desc|Name)|PhysicsMaterial|Status|Scale|Color|Alpha|Texture|Pos|Rot|Force|Torque)|ResetAnimationOverride|(?:Scale|Offset|Rotate)Texture|(?:Rot)?Target(?:Remove)?|(?:Stop)?MoveToTarget|Apply(?:Rotational)?Impulse|Set(?:KeyframedMotion|ContentType|RegionPos|(?:Angular)?Velocity|Buoyancy|HoverHeight|ForceAndTorque|TimerEvent|ScriptState|Damage|TextureAnim|Sound(?:Queueing|Radius)|Vehicle(?:Type|(?:Float|Vector|Rotation)Param)|(?:Touch|Sit)?Text|Camera(?:Eye|At)Offset|PrimitiveParams|ClickAction|Link(?:Alpha|Color|PrimitiveParams(?:Fast)?|Texture(?:Anim)?|Camera|Media)|RemoteScriptAccessPin|PayPrice|LocalRot)|ScaleByFactor|Get(?:(?:Max|Min)ScaleFactor|ClosestNavPoint|StaticPath|SimStats|Env|PrimitiveParams|Link(?:PrimitiveParams|Number(?:OfSides)?|Key|Name|Media)|HTTPHeader|FreeURLs|Object(?:Details|PermMask|PrimCount)|Parcel(?:MaxPrims|Details|Prim(?:Count|Owners))|Attached|(?:SPMax|Free|Used)Memory|Region(?:Name|TimeDilation|FPS|Corner|AgentCount)|Root(?:Position|Rotation)|UnixTime|(?:Parcel|Region)Flags|(?:Wall|GMT)clock|SimulatorHostname|BoundingBox|GeometricCenter|Creator|NumberOf(?:Prims|NotecardLines|Sides)|Animation(?:List)?|(?:Camera|Local)(?:Pos|Rot)|Vel|Accel|Omega|Time(?:stamp|OfDay)|(?:Object|CenterOf)?Mass|MassMKS|Energy|Owner|(?:Owner)?Key|SunDirection|Texture(?:Offset|Scale|Rot)|Inventory(?:Number|Name|Key|Type|Creator|PermMask)|Permissions(?:Key)?|StartParameter|List(?:Length|EntryType)|Date|Agent(?:Size|Info|Language|List)|LandOwnerAt|NotecardLine|Script(?:Name|State))|(?:Get|Reset|GetAndReset)Time|PlaySound(?:Slave)?|LoopSound(?:Master|Slave)?|(?:Trigger|Stop|Preload)Sound|(?:(?:Get|Delete)Sub|Insert)String|To(?:Upper|Lower)|Give(?:InventoryList|Money)|RezObject|(?:Stop)?LookAt|Sleep|CollisionFilter|(?:Take|Release)Controls|DetachFromAvatar|AttachToAvatar(?:Temp)?|InstantMessage|(?:GetNext)?Email|StopHover|MinEventDelay|RotLookAt|String(?:Length|Trim)|(?:Start|Stop)Animation|TargetOmega|RequestPermissions|(?:Create|Break)Link|BreakAllLinks|(?:Give|Remove)Inventory|Water|PassTouches|Request(?:Agent|Inventory)Data|TeleportAgent(?:Home|GlobalCoords)?|ModifyLand|CollisionSound|ResetScript|MessageLinked|PushObject|PassCollisions|AxisAngle2Rot|Rot2(?:Axis|Angle)|A(?:cos|sin)|AngleBetween|AllowInventoryDrop|SubStringIndex|List2(?:CSV|Integer|Json|Float|String|Key|Vector|Rot|List(?:Strided)?)|DeleteSubList|List(?:Statistics|Sort|Randomize|(?:Insert|Find|Replace)List)|EdgeOfWorld|AdjustSoundVolume|Key2Name|TriggerSoundLimited|EjectFromLand|(?:CSV|ParseString)2List|OverMyLand|SameGroup|UnSit|Ground(?:Slope|Normal|Contour)|GroundRepel|(?:Set|Remove)VehicleFlags|(?:AvatarOn)?(?:Link)?SitTarget|Script(?:Danger|Profiler)|Dialog|VolumeDetect|ResetOtherScript|RemoteLoadScriptPin|(?:Open|Close)RemoteDataChannel|SendRemoteData|RemoteDataReply|(?:Integer|String)ToBase64|XorBase64|Log(?:10)?|Base64To(?:String|Integer)|ParseStringKeepNulls|RezAtRoot|RequestSimulatorData|ForceMouselook|(?:Load|Release|(?:E|Une)scape)URL|ParcelMedia(?:CommandList|Query)|ModPow|MapDestination|(?:RemoveFrom|AddTo|Reset)Land(?:Pass|Ban)List|(?:Set|Clear)CameraParams|HTTP(?:Request|Response)|TextBox|DetectedTouch(?:UV|Face|Pos|(?:N|Bin)ormal|ST)|(?:MD5|SHA1|DumpList2)String|Request(?:Secure)?URL|Clear(?:Prim|Link)Media|(?:Link)?ParticleSystem|(?:Get|Request)(?:Username|DisplayName)|RegionSayTo|CastRay|GenerateKey|TransferLindenDollars|ManageEstateAccess|(?:Create|Delete)Character|ExecCharacterCmd|Evade|FleeFrom|NavigateTo|PatrolPoints|Pursue|UpdateCharacter|WanderWithin))\b'
665 lsl_constants_float = r'\b(?:DEG_TO_RAD|PI(?:_BY_TWO)?|RAD_TO_DEG|SQRT2|TWO_PI)\b'
666 lsl_constants_integer = r'\b(?:JSON_APPEND|STATUS_(?:PHYSICS|ROTATE_[XYZ]|PHANTOM|SANDBOX|BLOCK_GRAB(?:_OBJECT)?|(?:DIE|RETURN)_AT_EDGE|CAST_SHADOWS|OK|MALFORMED_PARAMS|TYPE_MISMATCH|BOUNDS_ERROR|NOT_(?:FOUND|SUPPORTED)|INTERNAL_ERROR|WHITELIST_FAILED)|AGENT(?:_(?:BY_(?:LEGACY_|USER)NAME|FLYING|ATTACHMENTS|SCRIPTED|MOUSELOOK|SITTING|ON_OBJECT|AWAY|WALKING|IN_AIR|TYPING|CROUCHING|BUSY|ALWAYS_RUN|AUTOPILOT|LIST_(?:PARCEL(?:_OWNER)?|REGION)))?|CAMERA_(?:PITCH|DISTANCE|BEHINDNESS_(?:ANGLE|LAG)|(?:FOCUS|POSITION)(?:_(?:THRESHOLD|LOCKED|LAG))?|FOCUS_OFFSET|ACTIVE)|ANIM_ON|LOOP|REVERSE|PING_PONG|SMOOTH|ROTATE|SCALE|ALL_SIDES|LINK_(?:ROOT|SET|ALL_(?:OTHERS|CHILDREN)|THIS)|ACTIVE|PASSIVE|SCRIPTED|CONTROL_(?:FWD|BACK|(?:ROT_)?(?:LEFT|RIGHT)|UP|DOWN|(?:ML_)?LBUTTON)|PERMISSION_(?:RETURN_OBJECTS|DEBIT|OVERRIDE_ANIMATIONS|SILENT_ESTATE_MANAGEMENT|TAKE_CONTROLS|TRIGGER_ANIMATION|ATTACH|CHANGE_LINKS|(?:CONTROL|TRACK)_CAMERA|TELEPORT)|INVENTORY_(?:TEXTURE|SOUND|OBJECT|SCRIPT|LANDMARK|CLOTHING|NOTECARD|BODYPART|ANIMATION|GESTURE|ALL|NONE)|CHANGED_(?:INVENTORY|COLOR|SHAPE|SCALE|TEXTURE|LINK|ALLOWED_DROP|OWNER|REGION(?:_START)?|TELEPORT|MEDIA)|OBJECT_(?:(?:PHYSICS|SERVER|STREAMING)_COST|UNKNOWN_DETAIL|CHARACTER_TIME|PHANTOM|PHYSICS|TEMP_ON_REZ|NAME|DESC|POS|PRIM_EQUIVALENCE|RETURN_(?:PARCEL(?:_OWNER)?|REGION)|ROO?T|VELOCITY|OWNER|GROUP|CREATOR|ATTACHED_POINT|RENDER_WEIGHT|PATHFINDING_TYPE|(?:RUNNING|TOTAL)_SCRIPT_COUNT|SCRIPT_(?:MEMORY|TIME))|TYPE_(?:INTEGER|FLOAT|STRING|KEY|VECTOR|ROTATION|INVALID)|(?:DEBUG|PUBLIC)_CHANNEL|ATTACH_(?:AVATAR_CENTER|CHEST|HEAD|BACK|PELVIS|MOUTH|CHIN|NECK|NOSE|BELLY|[LR](?:SHOULDER|HAND|FOOT|EAR|EYE|[UL](?:ARM|LEG)|HIP)|(?:LEFT|RIGHT)_PEC|HUD_(?:CENTER_[12]|TOP_(?:RIGHT|CENTER|LEFT)|BOTTOM(?:_(?:RIGHT|LEFT))?))|LAND_(?:LEVEL|RAISE|LOWER|SMOOTH|NOISE|REVERT)|DATA_(?:ONLINE|NAME|BORN|SIM_(?:POS|STATUS|RATING)|PAYINFO)|PAYMENT_INFO_(?:ON_FILE|USED)|REMOTE_DATA_(?:CHANNEL|REQUEST|REPLY)|PSYS_(?:PART_(?:BF_(?:ZERO|ONE(?:_MINUS_(?:DEST_COLOR|SOURCE_(ALPHA|COLOR)))?|DEST_COLOR|SOURCE_(ALPHA|COLOR))|BLEND_FUNC_(DEST|SOURCE)|FLAGS|(?:START|END)_(?:COLOR|ALPHA|SCALE|GLOW)|MAX_AGE|(?:RIBBON|WIND|INTERP_(?:COLOR|SCALE)|BOUNCE|FOLLOW_(?:SRC|VELOCITY)|TARGET_(?:POS|LINEAR)|EMISSIVE)_MASK)|SRC_(?:MAX_AGE|PATTERN|ANGLE_(?:BEGIN|END)|BURST_(?:RATE|PART_COUNT|RADIUS|SPEED_(?:MIN|MAX))|ACCEL|TEXTURE|TARGET_KEY|OMEGA|PATTERN_(?:DROP|EXPLODE|ANGLE(?:_CONE(?:_EMPTY)?)?)))|VEHICLE_(?:REFERENCE_FRAME|TYPE_(?:NONE|SLED|CAR|BOAT|AIRPLANE|BALLOON)|(?:LINEAR|ANGULAR)_(?:FRICTION_TIMESCALE|MOTOR_DIRECTION)|LINEAR_MOTOR_OFFSET|HOVER_(?:HEIGHT|EFFICIENCY|TIMESCALE)|BUOYANCY|(?:LINEAR|ANGULAR)_(?:DEFLECTION_(?:EFFICIENCY|TIMESCALE)|MOTOR_(?:DECAY_)?TIMESCALE)|VERTICAL_ATTRACTION_(?:EFFICIENCY|TIMESCALE)|BANKING_(?:EFFICIENCY|MIX|TIMESCALE)|FLAG_(?:NO_DEFLECTION_UP|LIMIT_(?:ROLL_ONLY|MOTOR_UP)|HOVER_(?:(?:WATER|TERRAIN|UP)_ONLY|GLOBAL_HEIGHT)|MOUSELOOK_(?:STEER|BANK)|CAMERA_DECOUPLED))|PRIM_(?:TYPE(?:_(?:BOX|CYLINDER|PRISM|SPHERE|TORUS|TUBE|RING|SCULPT))?|HOLE_(?:DEFAULT|CIRCLE|SQUARE|TRIANGLE)|MATERIAL(?:_(?:STONE|METAL|GLASS|WOOD|FLESH|PLASTIC|RUBBER))?|SHINY_(?:NONE|LOW|MEDIUM|HIGH)|BUMP_(?:NONE|BRIGHT|DARK|WOOD|BARK|BRICKS|CHECKER|CONCRETE|TILE|STONE|DISKS|GRAVEL|BLOBS|SIDING|LARGETILE|STUCCO|SUCTION|WEAVE)|TEXGEN_(?:DEFAULT|PLANAR)|SCULPT_(?:TYPE_(?:SPHERE|TORUS|PLANE|CYLINDER|MASK)|FLAG_(?:MIRROR|INVERT))|PHYSICS(?:_(?:SHAPE_(?:CONVEX|NONE|PRIM|TYPE)))?|(?:POS|ROT)_LOCAL|SLICE|TEXT|FLEXIBLE|POINT_LIGHT|TEMP_ON_REZ|PHANTOM|POSITION|SIZE|ROTATION|TEXTURE|NAME|OMEGA|DESC|LINK_TARGET|COLOR|BUMP_SHINY|FULLBRIGHT|TEXGEN|GLOW|MEDIA_(?:ALT_IMAGE_ENABLE|CONTROLS|(?:CURRENT|HOME)_URL|AUTO_(?:LOOP|PLAY|SCALE|ZOOM)|FIRST_CLICK_INTERACT|(?:WIDTH|HEIGHT)_PIXELS|WHITELIST(?:_ENABLE)?|PERMS_(?:INTERACT|CONTROL)|PARAM_MAX|CONTROLS_(?:STANDARD|MINI)|PERM_(?:NONE|OWNER|GROUP|ANYONE)|MAX_(?:URL_LENGTH|WHITELIST_(?:SIZE|COUNT)|(?:WIDTH|HEIGHT)_PIXELS)))|MASK_(?:BASE|OWNER|GROUP|EVERYONE|NEXT)|PERM_(?:TRANSFER|MODIFY|COPY|MOVE|ALL)|PARCEL_(?:MEDIA_COMMAND_(?:STOP|PAUSE|PLAY|LOOP|TEXTURE|URL|TIME|AGENT|UNLOAD|AUTO_ALIGN|TYPE|SIZE|DESC|LOOP_SET)|FLAG_(?:ALLOW_(?:FLY|(?:GROUP_)?SCRIPTS|LANDMARK|TERRAFORM|DAMAGE|CREATE_(?:GROUP_)?OBJECTS)|USE_(?:ACCESS_(?:GROUP|LIST)|BAN_LIST|LAND_PASS_LIST)|LOCAL_SOUND_ONLY|RESTRICT_PUSHOBJECT|ALLOW_(?:GROUP|ALL)_OBJECT_ENTRY)|COUNT_(?:TOTAL|OWNER|GROUP|OTHER|SELECTED|TEMP)|DETAILS_(?:NAME|DESC|OWNER|GROUP|AREA|ID|SEE_AVATARS))|LIST_STAT_(?:MAX|MIN|MEAN|MEDIAN|STD_DEV|SUM(?:_SQUARES)?|NUM_COUNT|GEOMETRIC_MEAN|RANGE)|PAY_(?:HIDE|DEFAULT)|REGION_FLAG_(?:ALLOW_DAMAGE|FIXED_SUN|BLOCK_TERRAFORM|SANDBOX|DISABLE_(?:COLLISIONS|PHYSICS)|BLOCK_FLY|ALLOW_DIRECT_TELEPORT|RESTRICT_PUSHOBJECT)|HTTP_(?:METHOD|MIMETYPE|BODY_(?:MAXLENGTH|TRUNCATED)|CUSTOM_HEADER|PRAGMA_NO_CACHE|VERBOSE_THROTTLE|VERIFY_CERT)|STRING_(?:TRIM(?:_(?:HEAD|TAIL))?)|CLICK_ACTION_(?:NONE|TOUCH|SIT|BUY|PAY|OPEN(?:_MEDIA)?|PLAY|ZOOM)|TOUCH_INVALID_FACE|PROFILE_(?:NONE|SCRIPT_MEMORY)|RC_(?:DATA_FLAGS|DETECT_PHANTOM|GET_(?:LINK_NUM|NORMAL|ROOT_KEY)|MAX_HITS|REJECT_(?:TYPES|AGENTS|(?:NON)?PHYSICAL|LAND))|RCERR_(?:CAST_TIME_EXCEEDED|SIM_PERF_LOW|UNKNOWN)|ESTATE_ACCESS_(?:ALLOWED_(?:AGENT|GROUP)_(?:ADD|REMOVE)|BANNED_AGENT_(?:ADD|REMOVE))|DENSITY|FRICTION|RESTITUTION|GRAVITY_MULTIPLIER|KFM_(?:COMMAND|CMD_(?:PLAY|STOP|PAUSE|SET_MODE)|MODE|FORWARD|LOOP|PING_PONG|REVERSE|DATA|ROTATION|TRANSLATION)|ERR_(?:GENERIC|PARCEL_PERMISSIONS|MALFORMED_PARAMS|RUNTIME_PERMISSIONS|THROTTLED)|CHARACTER_(?:CMD_(?:(?:SMOOTH_)?STOP|JUMP)|DESIRED_(?:TURN_)?SPEED|RADIUS|STAY_WITHIN_PARCEL|LENGTH|ORIENTATION|ACCOUNT_FOR_SKIPPED_FRAMES|AVOIDANCE_MODE|TYPE(?:_(?:[A-D]|NONE))?|MAX_(?:DECEL|TURN_RADIUS|(?:ACCEL|SPEED)))|PURSUIT_(?:OFFSET|FUZZ_FACTOR|GOAL_TOLERANCE|INTERCEPT)|REQUIRE_LINE_OF_SIGHT|FORCE_DIRECT_PATH|VERTICAL|HORIZONTAL|AVOID_(?:CHARACTERS|DYNAMIC_OBSTACLES|NONE)|PU_(?:EVADE_(?:HIDDEN|SPOTTED)|FAILURE_(?:DYNAMIC_PATHFINDING_DISABLED|INVALID_(?:GOAL|START)|NO_(?:NAVMESH|VALID_DESTINATION)|OTHER|TARGET_GONE|(?:PARCEL_)?UNREACHABLE)|(?:GOAL|SLOWDOWN_DISTANCE)_REACHED)|TRAVERSAL_TYPE(?:_(?:FAST|NONE|SLOW))?|CONTENT_TYPE_(?:ATOM|FORM|HTML|JSON|LLSD|RSS|TEXT|XHTML|XML)|GCNP_(?:RADIUS|STATIC)|(?:PATROL|WANDER)_PAUSE_AT_WAYPOINTS|OPT_(?:AVATAR|CHARACTER|EXCLUSION_VOLUME|LEGACY_LINKSET|MATERIAL_VOLUME|OTHER|STATIC_OBSTACLE|WALKABLE)|SIM_STAT_PCT_CHARS_STEPPED)\b'
667 lsl_constants_integer_boolean = r'\b(?:FALSE|TRUE)\b'
668 lsl_constants_rotation = r'\b(?:ZERO_ROTATION)\b'
669 lsl_constants_string = r'\b(?:EOF|JSON_(?:ARRAY|DELETE|FALSE|INVALID|NULL|NUMBER|OBJECT|STRING|TRUE)|NULL_KEY|TEXTURE_(?:BLANK|DEFAULT|MEDIA|PLYWOOD|TRANSPARENT)|URL_REQUEST_(?:GRANTED|DENIED))\b'
670 lsl_constants_vector = r'\b(?:TOUCH_INVALID_(?:TEXCOORD|VECTOR)|ZERO_VECTOR)\b'
671 lsl_invalid_broken = r'\b(?:LAND_(?:LARGE|MEDIUM|SMALL)_BRUSH)\b'
672 lsl_invalid_deprecated = r'\b(?:ATTACH_[LR]PEC|DATA_RATING|OBJECT_ATTACHMENT_(?:GEOMETRY_BYTES|SURFACE_AREA)|PRIM_(?:CAST_SHADOWS|MATERIAL_LIGHT|TYPE_LEGACY)|PSYS_SRC_(?:INNER|OUTER)ANGLE|VEHICLE_FLAG_NO_FLY_UP|ll(?:Cloud|Make(?:Explosion|Fountain|Smoke|Fire)|RemoteDataSetRegion|Sound(?:Preload)?|XorBase64Strings(?:Correct)?))\b'
673 lsl_invalid_illegal = r'\b(?:event)\b'
674 lsl_invalid_unimplemented = r'\b(?:CHARACTER_(?:MAX_ANGULAR_(?:ACCEL|SPEED)|TURN_SPEED_MULTIPLIER)|PERMISSION_(?:CHANGE_(?:JOINTS|PERMISSIONS)|RELEASE_OWNERSHIP|REMAP_CONTROLS)|PRIM_PHYSICS_MATERIAL|PSYS_SRC_OBJ_REL_MASK|ll(?:CollisionSprite|(?:Stop)?PointAt|(?:(?:Refresh|Set)Prim)URL|(?:Take|Release)Camera|RemoteLoadScript))\b'
675 lsl_reserved_godmode = r'\b(?:ll(?:GodLikeRezObject|Set(?:Inventory|Object)PermMask))\b'
676 lsl_reserved_log = r'\b(?:print)\b'
677 lsl_operators = r'\+\+|\-\-|<<|>>|&&?|\|\|?|\^|~|[!%<>=*+\-/]=?'
678
679 tokens = {
680 'root':
681 [
682 (r'//.*?\n', Comment.Single),
683 (r'/\*', Comment.Multiline, 'comment'),
684 (r'"', String.Double, 'string'),
685 (lsl_keywords, Keyword),
686 (lsl_types, Keyword.Type),
687 (lsl_states, Name.Class),
688 (lsl_events, Name.Builtin),
689 (lsl_functions_builtin, Name.Function),
690 (lsl_constants_float, Keyword.Constant),
691 (lsl_constants_integer, Keyword.Constant),
692 (lsl_constants_integer_boolean, Keyword.Constant),
693 (lsl_constants_rotation, Keyword.Constant),
694 (lsl_constants_string, Keyword.Constant),
695 (lsl_constants_vector, Keyword.Constant),
696 (lsl_invalid_broken, Error),
697 (lsl_invalid_deprecated, Error),
698 (lsl_invalid_illegal, Error),
699 (lsl_invalid_unimplemented, Error),
700 (lsl_reserved_godmode, Keyword.Reserved),
701 (lsl_reserved_log, Keyword.Reserved),
702 (r'\b([a-zA-Z_]\w*)\b', Name.Variable),
703 (r'(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d*', Number.Float),
704 (r'(\d+\.\d*|\.\d+)', Number.Float),
705 (r'0[xX][0-9a-fA-F]+', Number.Hex),
706 (r'\d+', Number.Integer),
707 (lsl_operators, Operator),
708 (r':=?', Error),
709 (r'[,;{}()\[\]]', Punctuation),
710 (r'\n+', Whitespace),
711 (r'\s+', Whitespace)
712 ],
713 'comment':
714 [
715 (r'[^*/]+', Comment.Multiline),
716 (r'/\*', Comment.Multiline, '#push'),
717 (r'\*/', Comment.Multiline, '#pop'),
718 (r'[*/]', Comment.Multiline)
719 ],
720 'string':
721 [
722 (r'\\([nt"\\])', String.Escape),
723 (r'"', String.Double, '#pop'),
724 (r'\\.', Error),
725 (r'[^"\\]+', String.Double),
726 ]
727 }
728
729
730class AppleScriptLexer(RegexLexer):
731 """
732 For AppleScript source code,
733 including `AppleScript Studio
734 <http://developer.apple.com/documentation/AppleScript/
735 Reference/StudioReference>`_.
736 Contributed by Andreas Amann <aamann@mac.com>.
737 """
738
739 name = 'AppleScript'
740 url = 'https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/introduction/ASLR_intro.html'
741 aliases = ['applescript']
742 filenames = ['*.applescript']
743 version_added = '1.0'
744
745 flags = re.MULTILINE | re.DOTALL
746
747 Identifiers = r'[a-zA-Z]\w*'
748
749 # XXX: use words() for all of these
750 Literals = ('AppleScript', 'current application', 'false', 'linefeed',
751 'missing value', 'pi', 'quote', 'result', 'return', 'space',
752 'tab', 'text item delimiters', 'true', 'version')
753 Classes = ('alias ', 'application ', 'boolean ', 'class ', 'constant ',
754 'date ', 'file ', 'integer ', 'list ', 'number ', 'POSIX file ',
755 'real ', 'record ', 'reference ', 'RGB color ', 'script ',
756 'text ', 'unit types', '(?:Unicode )?text', 'string')
757 BuiltIn = ('attachment', 'attribute run', 'character', 'day', 'month',
758 'paragraph', 'word', 'year')
759 HandlerParams = ('about', 'above', 'against', 'apart from', 'around',
760 'aside from', 'at', 'below', 'beneath', 'beside',
761 'between', 'for', 'given', 'instead of', 'on', 'onto',
762 'out of', 'over', 'since')
763 Commands = ('ASCII (character|number)', 'activate', 'beep', 'choose URL',
764 'choose application', 'choose color', 'choose file( name)?',
765 'choose folder', 'choose from list',
766 'choose remote application', 'clipboard info',
767 'close( access)?', 'copy', 'count', 'current date', 'delay',
768 'delete', 'display (alert|dialog)', 'do shell script',
769 'duplicate', 'exists', 'get eof', 'get volume settings',
770 'info for', 'launch', 'list (disks|folder)', 'load script',
771 'log', 'make', 'mount volume', 'new', 'offset',
772 'open( (for access|location))?', 'path to', 'print', 'quit',
773 'random number', 'read', 'round', 'run( script)?',
774 'say', 'scripting components',
775 'set (eof|the clipboard to|volume)', 'store script',
776 'summarize', 'system attribute', 'system info',
777 'the clipboard', 'time to GMT', 'write', 'quoted form')
778 References = ('(in )?back of', '(in )?front of', '[0-9]+(st|nd|rd|th)',
779 'first', 'second', 'third', 'fourth', 'fifth', 'sixth',
780 'seventh', 'eighth', 'ninth', 'tenth', 'after', 'back',
781 'before', 'behind', 'every', 'front', 'index', 'last',
782 'middle', 'some', 'that', 'through', 'thru', 'where', 'whose')
783 Operators = ("and", "or", "is equal", "equals", "(is )?equal to", "is not",
784 "isn't", "isn't equal( to)?", "is not equal( to)?",
785 "doesn't equal", "does not equal", "(is )?greater than",
786 "comes after", "is not less than or equal( to)?",
787 "isn't less than or equal( to)?", "(is )?less than",
788 "comes before", "is not greater than or equal( to)?",
789 "isn't greater than or equal( to)?",
790 "(is )?greater than or equal( to)?", "is not less than",
791 "isn't less than", "does not come before",
792 "doesn't come before", "(is )?less than or equal( to)?",
793 "is not greater than", "isn't greater than",
794 "does not come after", "doesn't come after", "starts? with",
795 "begins? with", "ends? with", "contains?", "does not contain",
796 "doesn't contain", "is in", "is contained by", "is not in",
797 "is not contained by", "isn't contained by", "div", "mod",
798 "not", "(a )?(ref( to)?|reference to)", "is", "does")
799 Control = ('considering', 'else', 'error', 'exit', 'from', 'if',
800 'ignoring', 'in', 'repeat', 'tell', 'then', 'times', 'to',
801 'try', 'until', 'using terms from', 'while', 'whith',
802 'with timeout( of)?', 'with transaction', 'by', 'continue',
803 'end', 'its?', 'me', 'my', 'return', 'of', 'as')
804 Declarations = ('global', 'local', 'prop(erty)?', 'set', 'get')
805 Reserved = ('but', 'put', 'returning', 'the')
806 StudioClasses = ('action cell', 'alert reply', 'application', 'box',
807 'browser( cell)?', 'bundle', 'button( cell)?', 'cell',
808 'clip view', 'color well', 'color-panel',
809 'combo box( item)?', 'control',
810 'data( (cell|column|item|row|source))?', 'default entry',
811 'dialog reply', 'document', 'drag info', 'drawer',
812 'event', 'font(-panel)?', 'formatter',
813 'image( (cell|view))?', 'matrix', 'menu( item)?', 'item',
814 'movie( view)?', 'open-panel', 'outline view', 'panel',
815 'pasteboard', 'plugin', 'popup button',
816 'progress indicator', 'responder', 'save-panel',
817 'scroll view', 'secure text field( cell)?', 'slider',
818 'sound', 'split view', 'stepper', 'tab view( item)?',
819 'table( (column|header cell|header view|view))',
820 'text( (field( cell)?|view))?', 'toolbar( item)?',
821 'user-defaults', 'view', 'window')
822 StudioEvents = ('accept outline drop', 'accept table drop', 'action',
823 'activated', 'alert ended', 'awake from nib', 'became key',
824 'became main', 'begin editing', 'bounds changed',
825 'cell value', 'cell value changed', 'change cell value',
826 'change item value', 'changed', 'child of item',
827 'choose menu item', 'clicked', 'clicked toolbar item',
828 'closed', 'column clicked', 'column moved',
829 'column resized', 'conclude drop', 'data representation',
830 'deminiaturized', 'dialog ended', 'document nib name',
831 'double clicked', 'drag( (entered|exited|updated))?',
832 'drop', 'end editing', 'exposed', 'idle', 'item expandable',
833 'item value', 'item value changed', 'items changed',
834 'keyboard down', 'keyboard up', 'launched',
835 'load data representation', 'miniaturized', 'mouse down',
836 'mouse dragged', 'mouse entered', 'mouse exited',
837 'mouse moved', 'mouse up', 'moved',
838 'number of browser rows', 'number of items',
839 'number of rows', 'open untitled', 'opened', 'panel ended',
840 'parameters updated', 'plugin loaded', 'prepare drop',
841 'prepare outline drag', 'prepare outline drop',
842 'prepare table drag', 'prepare table drop',
843 'read from file', 'resigned active', 'resigned key',
844 'resigned main', 'resized( sub views)?',
845 'right mouse down', 'right mouse dragged',
846 'right mouse up', 'rows changed', 'scroll wheel',
847 'selected tab view item', 'selection changed',
848 'selection changing', 'should begin editing',
849 'should close', 'should collapse item',
850 'should end editing', 'should expand item',
851 'should open( untitled)?',
852 'should quit( after last window closed)?',
853 'should select column', 'should select item',
854 'should select row', 'should select tab view item',
855 'should selection change', 'should zoom', 'shown',
856 'update menu item', 'update parameters',
857 'update toolbar item', 'was hidden', 'was miniaturized',
858 'will become active', 'will close', 'will dismiss',
859 'will display browser cell', 'will display cell',
860 'will display item cell', 'will display outline cell',
861 'will finish launching', 'will hide', 'will miniaturize',
862 'will move', 'will open', 'will pop up', 'will quit',
863 'will resign active', 'will resize( sub views)?',
864 'will select tab view item', 'will show', 'will zoom',
865 'write to file', 'zoomed')
866 StudioCommands = ('animate', 'append', 'call method', 'center',
867 'close drawer', 'close panel', 'display',
868 'display alert', 'display dialog', 'display panel', 'go',
869 'hide', 'highlight', 'increment', 'item for',
870 'load image', 'load movie', 'load nib', 'load panel',
871 'load sound', 'localized string', 'lock focus', 'log',
872 'open drawer', 'path for', 'pause', 'perform action',
873 'play', 'register', 'resume', 'scroll', 'select( all)?',
874 'show', 'size to fit', 'start', 'step back',
875 'step forward', 'stop', 'synchronize', 'unlock focus',
876 'update')
877 StudioProperties = ('accepts arrow key', 'action method', 'active',
878 'alignment', 'allowed identifiers',
879 'allows branch selection', 'allows column reordering',
880 'allows column resizing', 'allows column selection',
881 'allows customization',
882 'allows editing text attributes',
883 'allows empty selection', 'allows mixed state',
884 'allows multiple selection', 'allows reordering',
885 'allows undo', 'alpha( value)?', 'alternate image',
886 'alternate increment value', 'alternate title',
887 'animation delay', 'associated file name',
888 'associated object', 'auto completes', 'auto display',
889 'auto enables items', 'auto repeat',
890 'auto resizes( outline column)?',
891 'auto save expanded items', 'auto save name',
892 'auto save table columns', 'auto saves configuration',
893 'auto scroll', 'auto sizes all columns to fit',
894 'auto sizes cells', 'background color', 'bezel state',
895 'bezel style', 'bezeled', 'border rect', 'border type',
896 'bordered', 'bounds( rotation)?', 'box type',
897 'button returned', 'button type',
898 'can choose directories', 'can choose files',
899 'can draw', 'can hide',
900 'cell( (background color|size|type))?', 'characters',
901 'class', 'click count', 'clicked( data)? column',
902 'clicked data item', 'clicked( data)? row',
903 'closeable', 'collating', 'color( (mode|panel))',
904 'command key down', 'configuration',
905 'content(s| (size|view( margins)?))?', 'context',
906 'continuous', 'control key down', 'control size',
907 'control tint', 'control view',
908 'controller visible', 'coordinate system',
909 'copies( on scroll)?', 'corner view', 'current cell',
910 'current column', 'current( field)? editor',
911 'current( menu)? item', 'current row',
912 'current tab view item', 'data source',
913 'default identifiers', 'delta (x|y|z)',
914 'destination window', 'directory', 'display mode',
915 'displayed cell', 'document( (edited|rect|view))?',
916 'double value', 'dragged column', 'dragged distance',
917 'dragged items', 'draws( cell)? background',
918 'draws grid', 'dynamically scrolls', 'echos bullets',
919 'edge', 'editable', 'edited( data)? column',
920 'edited data item', 'edited( data)? row', 'enabled',
921 'enclosing scroll view', 'ending page',
922 'error handling', 'event number', 'event type',
923 'excluded from windows menu', 'executable path',
924 'expanded', 'fax number', 'field editor', 'file kind',
925 'file name', 'file type', 'first responder',
926 'first visible column', 'flipped', 'floating',
927 'font( panel)?', 'formatter', 'frameworks path',
928 'frontmost', 'gave up', 'grid color', 'has data items',
929 'has horizontal ruler', 'has horizontal scroller',
930 'has parent data item', 'has resize indicator',
931 'has shadow', 'has sub menu', 'has vertical ruler',
932 'has vertical scroller', 'header cell', 'header view',
933 'hidden', 'hides when deactivated', 'highlights by',
934 'horizontal line scroll', 'horizontal page scroll',
935 'horizontal ruler view', 'horizontally resizable',
936 'icon image', 'id', 'identifier',
937 'ignores multiple clicks',
938 'image( (alignment|dims when disabled|frame style|scaling))?',
939 'imports graphics', 'increment value',
940 'indentation per level', 'indeterminate', 'index',
941 'integer value', 'intercell spacing', 'item height',
942 'key( (code|equivalent( modifier)?|window))?',
943 'knob thickness', 'label', 'last( visible)? column',
944 'leading offset', 'leaf', 'level', 'line scroll',
945 'loaded', 'localized sort', 'location', 'loop mode',
946 'main( (bunde|menu|window))?', 'marker follows cell',
947 'matrix mode', 'maximum( content)? size',
948 'maximum visible columns',
949 'menu( form representation)?', 'miniaturizable',
950 'miniaturized', 'minimized image', 'minimized title',
951 'minimum column width', 'minimum( content)? size',
952 'modal', 'modified', 'mouse down state',
953 'movie( (controller|file|rect))?', 'muted', 'name',
954 'needs display', 'next state', 'next text',
955 'number of tick marks', 'only tick mark values',
956 'opaque', 'open panel', 'option key down',
957 'outline table column', 'page scroll', 'pages across',
958 'pages down', 'palette label', 'pane splitter',
959 'parent data item', 'parent window', 'pasteboard',
960 'path( (names|separator))?', 'playing',
961 'plays every frame', 'plays selection only', 'position',
962 'preferred edge', 'preferred type', 'pressure',
963 'previous text', 'prompt', 'properties',
964 'prototype cell', 'pulls down', 'rate',
965 'released when closed', 'repeated',
966 'requested print time', 'required file type',
967 'resizable', 'resized column', 'resource path',
968 'returns records', 'reuses columns', 'rich text',
969 'roll over', 'row height', 'rulers visible',
970 'save panel', 'scripts path', 'scrollable',
971 'selectable( identifiers)?', 'selected cell',
972 'selected( data)? columns?', 'selected data items?',
973 'selected( data)? rows?', 'selected item identifier',
974 'selection by rect', 'send action on arrow key',
975 'sends action when done editing', 'separates columns',
976 'separator item', 'sequence number', 'services menu',
977 'shared frameworks path', 'shared support path',
978 'sheet', 'shift key down', 'shows alpha',
979 'shows state by', 'size( mode)?',
980 'smart insert delete enabled', 'sort case sensitivity',
981 'sort column', 'sort order', 'sort type',
982 'sorted( data rows)?', 'sound', 'source( mask)?',
983 'spell checking enabled', 'starting page', 'state',
984 'string value', 'sub menu', 'super menu', 'super view',
985 'tab key traverses cells', 'tab state', 'tab type',
986 'tab view', 'table view', 'tag', 'target( printer)?',
987 'text color', 'text container insert',
988 'text container origin', 'text returned',
989 'tick mark position', 'time stamp',
990 'title(d| (cell|font|height|position|rect))?',
991 'tool tip', 'toolbar', 'trailing offset', 'transparent',
992 'treat packages as directories', 'truncated labels',
993 'types', 'unmodified characters', 'update views',
994 'use sort indicator', 'user defaults',
995 'uses data source', 'uses ruler',
996 'uses threaded animation',
997 'uses title from previous column', 'value wraps',
998 'version',
999 'vertical( (line scroll|page scroll|ruler view))?',
1000 'vertically resizable', 'view',
1001 'visible( document rect)?', 'volume', 'width', 'window',
1002 'windows menu', 'wraps', 'zoomable', 'zoomed')
1003
1004 tokens = {
1005 'root': [
1006 (r'\s+', Text),
1007 (r'¬\n', String.Escape),
1008 (r"'s\s+", Text), # This is a possessive, consider moving
1009 (r'(--|#).*?$', Comment),
1010 (r'\(\*', Comment.Multiline, 'comment'),
1011 (r'[(){}!,.:]', Punctuation),
1012 (r'(«)([^»]+)(»)',
1013 bygroups(Text, Name.Builtin, Text)),
1014 (r'\b((?:considering|ignoring)\s*)'
1015 r'(application responses|case|diacriticals|hyphens|'
1016 r'numeric strings|punctuation|white space)',
1017 bygroups(Keyword, Name.Builtin)),
1018 (r'(-|\*|\+|&|≠|>=?|<=?|=|≥|≤|/|÷|\^)', Operator),
1019 (r"\b({})\b".format('|'.join(Operators)), Operator.Word),
1020 (r'^(\s*(?:on|end)\s+)'
1021 r'({})'.format('|'.join(StudioEvents[::-1])),
1022 bygroups(Keyword, Name.Function)),
1023 (r'^(\s*)(in|on|script|to)(\s+)', bygroups(Text, Keyword, Text)),
1024 (r'\b(as )({})\b'.format('|'.join(Classes)),
1025 bygroups(Keyword, Name.Class)),
1026 (r'\b({})\b'.format('|'.join(Literals)), Name.Constant),
1027 (r'\b({})\b'.format('|'.join(Commands)), Name.Builtin),
1028 (r'\b({})\b'.format('|'.join(Control)), Keyword),
1029 (r'\b({})\b'.format('|'.join(Declarations)), Keyword),
1030 (r'\b({})\b'.format('|'.join(Reserved)), Name.Builtin),
1031 (r'\b({})s?\b'.format('|'.join(BuiltIn)), Name.Builtin),
1032 (r'\b({})\b'.format('|'.join(HandlerParams)), Name.Builtin),
1033 (r'\b({})\b'.format('|'.join(StudioProperties)), Name.Attribute),
1034 (r'\b({})s?\b'.format('|'.join(StudioClasses)), Name.Builtin),
1035 (r'\b({})\b'.format('|'.join(StudioCommands)), Name.Builtin),
1036 (r'\b({})\b'.format('|'.join(References)), Name.Builtin),
1037 (r'"(\\\\|\\[^\\]|[^"\\])*"', String.Double),
1038 (rf'\b({Identifiers})\b', Name.Variable),
1039 (r'[-+]?(\d+\.\d*|\d*\.\d+)(E[-+][0-9]+)?', Number.Float),
1040 (r'[-+]?\d+', Number.Integer),
1041 ],
1042 'comment': [
1043 (r'\(\*', Comment.Multiline, '#push'),
1044 (r'\*\)', Comment.Multiline, '#pop'),
1045 ('[^*(]+', Comment.Multiline),
1046 ('[*(]', Comment.Multiline),
1047 ],
1048 }
1049
1050
1051class RexxLexer(RegexLexer):
1052 """
1053 Rexx is a scripting language available for
1054 a wide range of different platforms with its roots found on mainframe
1055 systems. It is popular for I/O- and data based tasks and can act as glue
1056 language to bind different applications together.
1057 """
1058 name = 'Rexx'
1059 url = 'http://www.rexxinfo.org/'
1060 aliases = ['rexx', 'arexx']
1061 filenames = ['*.rexx', '*.rex', '*.rx', '*.arexx']
1062 mimetypes = ['text/x-rexx']
1063 version_added = '2.0'
1064 flags = re.IGNORECASE
1065
1066 tokens = {
1067 'root': [
1068 (r'\s+', Whitespace),
1069 (r'/\*', Comment.Multiline, 'comment'),
1070 (r'"', String, 'string_double'),
1071 (r"'", String, 'string_single'),
1072 (r'[0-9]+(\.[0-9]+)?(e[+-]?[0-9])?', Number),
1073 (r'([a-z_]\w*)(\s*)(:)(\s*)(procedure)\b',
1074 bygroups(Name.Function, Whitespace, Operator, Whitespace,
1075 Keyword.Declaration)),
1076 (r'([a-z_]\w*)(\s*)(:)',
1077 bygroups(Name.Label, Whitespace, Operator)),
1078 include('function'),
1079 include('keyword'),
1080 include('operator'),
1081 (r'[a-z_]\w*', Text),
1082 ],
1083 'function': [
1084 (words((
1085 'abbrev', 'abs', 'address', 'arg', 'b2x', 'bitand', 'bitor', 'bitxor',
1086 'c2d', 'c2x', 'center', 'charin', 'charout', 'chars', 'compare',
1087 'condition', 'copies', 'd2c', 'd2x', 'datatype', 'date', 'delstr',
1088 'delword', 'digits', 'errortext', 'form', 'format', 'fuzz', 'insert',
1089 'lastpos', 'left', 'length', 'linein', 'lineout', 'lines', 'max',
1090 'min', 'overlay', 'pos', 'queued', 'random', 'reverse', 'right', 'sign',
1091 'sourceline', 'space', 'stream', 'strip', 'substr', 'subword', 'symbol',
1092 'time', 'trace', 'translate', 'trunc', 'value', 'verify', 'word',
1093 'wordindex', 'wordlength', 'wordpos', 'words', 'x2b', 'x2c', 'x2d',
1094 'xrange'), suffix=r'(\s*)(\()'),
1095 bygroups(Name.Builtin, Whitespace, Operator)),
1096 ],
1097 'keyword': [
1098 (r'(address|arg|by|call|do|drop|else|end|exit|for|forever|if|'
1099 r'interpret|iterate|leave|nop|numeric|off|on|options|parse|'
1100 r'pull|push|queue|return|say|select|signal|to|then|trace|until|'
1101 r'while)\b', Keyword.Reserved),
1102 ],
1103 'operator': [
1104 (r'(-|//|/|\(|\)|\*\*|\*|\\<<|\\<|\\==|\\=|\\>>|\\>|\\|\|\||\||'
1105 r'&&|&|%|\+|<<=|<<|<=|<>|<|==|=|><|>=|>>=|>>|>|¬<<|¬<|¬==|¬=|'
1106 r'¬>>|¬>|¬|\.|,)', Operator),
1107 ],
1108 'string_double': [
1109 (r'[^"\n]+', String),
1110 (r'""', String),
1111 (r'"', String, '#pop'),
1112 (r'\n', Text, '#pop'), # Stray linefeed also terminates strings.
1113 ],
1114 'string_single': [
1115 (r'[^\'\n]+', String),
1116 (r'\'\'', String),
1117 (r'\'', String, '#pop'),
1118 (r'\n', Text, '#pop'), # Stray linefeed also terminates strings.
1119 ],
1120 'comment': [
1121 (r'[^*]+', Comment.Multiline),
1122 (r'\*/', Comment.Multiline, '#pop'),
1123 (r'\*', Comment.Multiline),
1124 ]
1125 }
1126
1127 def _c(s):
1128 return re.compile(s, re.MULTILINE)
1129 _ADDRESS_COMMAND_PATTERN = _c(r'^\s*address\s+command\b')
1130 _ADDRESS_PATTERN = _c(r'^\s*address\s+')
1131 _DO_WHILE_PATTERN = _c(r'^\s*do\s+while\b')
1132 _IF_THEN_DO_PATTERN = _c(r'^\s*if\b.+\bthen\s+do\s*$')
1133 _PROCEDURE_PATTERN = _c(r'^\s*([a-z_]\w*)(\s*)(:)(\s*)(procedure)\b')
1134 _ELSE_DO_PATTERN = _c(r'\belse\s+do\s*$')
1135 _PARSE_ARG_PATTERN = _c(r'^\s*parse\s+(upper\s+)?(arg|value)\b')
1136 PATTERNS_AND_WEIGHTS = (
1137 (_ADDRESS_COMMAND_PATTERN, 0.2),
1138 (_ADDRESS_PATTERN, 0.05),
1139 (_DO_WHILE_PATTERN, 0.1),
1140 (_ELSE_DO_PATTERN, 0.1),
1141 (_IF_THEN_DO_PATTERN, 0.1),
1142 (_PROCEDURE_PATTERN, 0.5),
1143 (_PARSE_ARG_PATTERN, 0.2),
1144 )
1145
1146 def analyse_text(text):
1147 """
1148 Check for initial comment and patterns that distinguish Rexx from other
1149 C-like languages.
1150 """
1151 if re.search(r'/\*\**\s*rexx', text, re.IGNORECASE):
1152 # Header matches MVS Rexx requirements, this is certainly a Rexx
1153 # script.
1154 return 1.0
1155 elif text.startswith('/*'):
1156 # Header matches general Rexx requirements; the source code might
1157 # still be any language using C comments such as C++, C# or Java.
1158 lowerText = text.lower()
1159 result = sum(weight
1160 for (pattern, weight) in RexxLexer.PATTERNS_AND_WEIGHTS
1161 if pattern.search(lowerText)) + 0.01
1162 return min(result, 1.0)
1163
1164
1165class MOOCodeLexer(RegexLexer):
1166 """
1167 For MOOCode (the MOO scripting language).
1168 """
1169 name = 'MOOCode'
1170 url = 'http://www.moo.mud.org/'
1171 filenames = ['*.moo']
1172 aliases = ['moocode', 'moo']
1173 mimetypes = ['text/x-moocode']
1174 version_added = '0.9'
1175
1176 tokens = {
1177 'root': [
1178 # Numbers
1179 (r'(0|[1-9][0-9_]*)', Number.Integer),
1180 # Strings
1181 (r'"(\\\\|\\[^\\]|[^"\\])*"', String),
1182 # exceptions
1183 (r'(E_PERM|E_DIV)', Name.Exception),
1184 # db-refs
1185 (r'((#[-0-9]+)|(\$\w+))', Name.Entity),
1186 # Keywords
1187 (r'\b(if|else|elseif|endif|for|endfor|fork|endfork|while'
1188 r'|endwhile|break|continue|return|try'
1189 r'|except|endtry|finally|in)\b', Keyword),
1190 # builtins
1191 (r'(random|length)', Name.Builtin),
1192 # special variables
1193 (r'(player|caller|this|args)', Name.Variable.Instance),
1194 # skip whitespace
1195 (r'\s+', Text),
1196 (r'\n', Text),
1197 # other operators
1198 (r'([!;=,{}&|:.\[\]@()<>?]+)', Operator),
1199 # function call
1200 (r'(\w+)(\()', bygroups(Name.Function, Operator)),
1201 # variables
1202 (r'(\w+)', Text),
1203 ]
1204 }
1205
1206
1207class HybrisLexer(RegexLexer):
1208 """
1209 For Hybris source code.
1210 """
1211
1212 name = 'Hybris'
1213 aliases = ['hybris']
1214 filenames = ['*.hyb']
1215 mimetypes = ['text/x-hybris', 'application/x-hybris']
1216 url = 'https://github.com/evilsocket/hybris'
1217 version_added = '1.4'
1218
1219 flags = re.MULTILINE | re.DOTALL
1220
1221 tokens = {
1222 'root': [
1223 # method names
1224 (r'^(\s*(?:function|method|operator\s+)+?)'
1225 r'([a-zA-Z_]\w*)'
1226 r'(\s*)(\()', bygroups(Keyword, Name.Function, Text, Operator)),
1227 (r'[^\S\n]+', Text),
1228 (r'//.*?\n', Comment.Single),
1229 (r'/\*.*?\*/', Comment.Multiline),
1230 (r'@[a-zA-Z_][\w.]*', Name.Decorator),
1231 (r'(break|case|catch|next|default|do|else|finally|for|foreach|of|'
1232 r'unless|if|new|return|switch|me|throw|try|while)\b', Keyword),
1233 (r'(extends|private|protected|public|static|throws|function|method|'
1234 r'operator)\b', Keyword.Declaration),
1235 (r'(true|false|null|__FILE__|__LINE__|__VERSION__|__LIB_PATH__|'
1236 r'__INC_PATH__)\b', Keyword.Constant),
1237 (r'(class|struct)(\s+)',
1238 bygroups(Keyword.Declaration, Text), 'class'),
1239 (r'(import|include)(\s+)',
1240 bygroups(Keyword.Namespace, Text), 'import'),
1241 (words((
1242 'gc_collect', 'gc_mm_items', 'gc_mm_usage', 'gc_collect_threshold',
1243 'urlencode', 'urldecode', 'base64encode', 'base64decode', 'sha1', 'crc32',
1244 'sha2', 'md5', 'md5_file', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos',
1245 'cosh', 'exp', 'fabs', 'floor', 'fmod', 'log', 'log10', 'pow', 'sin',
1246 'sinh', 'sqrt', 'tan', 'tanh', 'isint', 'isfloat', 'ischar', 'isstring',
1247 'isarray', 'ismap', 'isalias', 'typeof', 'sizeof', 'toint', 'tostring',
1248 'fromxml', 'toxml', 'binary', 'pack', 'load', 'eval', 'var_names',
1249 'var_values', 'user_functions', 'dyn_functions', 'methods', 'call',
1250 'call_method', 'mknod', 'mkfifo', 'mount', 'umount2', 'umount', 'ticks',
1251 'usleep', 'sleep', 'time', 'strtime', 'strdate', 'dllopen', 'dlllink',
1252 'dllcall', 'dllcall_argv', 'dllclose', 'env', 'exec', 'fork', 'getpid',
1253 'wait', 'popen', 'pclose', 'exit', 'kill', 'pthread_create',
1254 'pthread_create_argv', 'pthread_exit', 'pthread_join', 'pthread_kill',
1255 'smtp_send', 'http_get', 'http_post', 'http_download', 'socket', 'bind',
1256 'listen', 'accept', 'getsockname', 'getpeername', 'settimeout', 'connect',
1257 'server', 'recv', 'send', 'close', 'print', 'println', 'printf', 'input',
1258 'readline', 'serial_open', 'serial_fcntl', 'serial_get_attr',
1259 'serial_get_ispeed', 'serial_get_ospeed', 'serial_set_attr',
1260 'serial_set_ispeed', 'serial_set_ospeed', 'serial_write', 'serial_read',
1261 'serial_close', 'xml_load', 'xml_parse', 'fopen', 'fseek', 'ftell',
1262 'fsize', 'fread', 'fwrite', 'fgets', 'fclose', 'file', 'readdir',
1263 'pcre_replace', 'size', 'pop', 'unmap', 'has', 'keys', 'values',
1264 'length', 'find', 'substr', 'replace', 'split', 'trim', 'remove',
1265 'contains', 'join'), suffix=r'\b'),
1266 Name.Builtin),
1267 (words((
1268 'MethodReference', 'Runner', 'Dll', 'Thread', 'Pipe', 'Process',
1269 'Runnable', 'CGI', 'ClientSocket', 'Socket', 'ServerSocket',
1270 'File', 'Console', 'Directory', 'Exception'), suffix=r'\b'),
1271 Keyword.Type),
1272 (r'"(\\\\|\\[^\\]|[^"\\])*"', String),
1273 (r"'\\.'|'[^\\]'|'\\u[0-9a-f]{4}'", String.Char),
1274 (r'(\.)([a-zA-Z_]\w*)',
1275 bygroups(Operator, Name.Attribute)),
1276 (r'[a-zA-Z_]\w*:', Name.Label),
1277 (r'[a-zA-Z_$]\w*', Name),
1278 (r'[~^*!%&\[\](){}<>|+=:;,./?\-@]+', Operator),
1279 (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
1280 (r'0x[0-9a-f]+', Number.Hex),
1281 (r'[0-9]+L?', Number.Integer),
1282 (r'\n', Text),
1283 ],
1284 'class': [
1285 (r'[a-zA-Z_]\w*', Name.Class, '#pop')
1286 ],
1287 'import': [
1288 (r'[\w.]+\*?', Name.Namespace, '#pop')
1289 ],
1290 }
1291
1292 def analyse_text(text):
1293 """public method and private method don't seem to be quite common
1294 elsewhere."""
1295 result = 0
1296 if re.search(r'\b(?:public|private)\s+method\b', text):
1297 result += 0.01
1298 return result
1299
1300
1301
1302class EasytrieveLexer(RegexLexer):
1303 """
1304 Easytrieve Plus is a programming language for extracting, filtering and
1305 converting sequential data. Furthermore it can layout data for reports.
1306 It is mainly used on mainframe platforms and can access several of the
1307 mainframe's native file formats. It is somewhat comparable to awk.
1308 """
1309 name = 'Easytrieve'
1310 aliases = ['easytrieve']
1311 filenames = ['*.ezt', '*.mac']
1312 mimetypes = ['text/x-easytrieve']
1313 url = 'https://www.broadcom.com/products/mainframe/application-development/easytrieve-report-generator'
1314 version_added = '2.1'
1315 flags = 0
1316
1317 # Note: We cannot use r'\b' at the start and end of keywords because
1318 # Easytrieve Plus delimiter characters are:
1319 #
1320 # * space ( )
1321 # * apostrophe (')
1322 # * period (.)
1323 # * comma (,)
1324 # * parenthesis ( and )
1325 # * colon (:)
1326 #
1327 # Additionally words end once a '*' appears, indicatins a comment.
1328 _DELIMITERS = r' \'.,():\n'
1329 _DELIMITERS_OR_COMENT = _DELIMITERS + '*'
1330 _DELIMITER_PATTERN = '[' + _DELIMITERS + ']'
1331 _DELIMITER_PATTERN_CAPTURE = '(' + _DELIMITER_PATTERN + ')'
1332 _NON_DELIMITER_OR_COMMENT_PATTERN = '[^' + _DELIMITERS_OR_COMENT + ']'
1333 _OPERATORS_PATTERN = '[.+\\-/=\\[\\](){}<>;,&%¬]'
1334 _KEYWORDS = [
1335 'AFTER-BREAK', 'AFTER-LINE', 'AFTER-SCREEN', 'AIM', 'AND', 'ATTR',
1336 'BEFORE', 'BEFORE-BREAK', 'BEFORE-LINE', 'BEFORE-SCREEN', 'BUSHU',
1337 'BY', 'CALL', 'CASE', 'CHECKPOINT', 'CHKP', 'CHKP-STATUS', 'CLEAR',
1338 'CLOSE', 'COL', 'COLOR', 'COMMIT', 'CONTROL', 'COPY', 'CURSOR', 'D',
1339 'DECLARE', 'DEFAULT', 'DEFINE', 'DELETE', 'DENWA', 'DISPLAY', 'DLI',
1340 'DO', 'DUPLICATE', 'E', 'ELSE', 'ELSE-IF', 'END', 'END-CASE',
1341 'END-DO', 'END-IF', 'END-PROC', 'ENDPAGE', 'ENDTABLE', 'ENTER', 'EOF',
1342 'EQ', 'ERROR', 'EXIT', 'EXTERNAL', 'EZLIB', 'F1', 'F10', 'F11', 'F12',
1343 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F2', 'F20', 'F21',
1344 'F22', 'F23', 'F24', 'F25', 'F26', 'F27', 'F28', 'F29', 'F3', 'F30',
1345 'F31', 'F32', 'F33', 'F34', 'F35', 'F36', 'F4', 'F5', 'F6', 'F7',
1346 'F8', 'F9', 'FETCH', 'FILE-STATUS', 'FILL', 'FINAL', 'FIRST',
1347 'FIRST-DUP', 'FOR', 'GE', 'GET', 'GO', 'GOTO', 'GQ', 'GR', 'GT',
1348 'HEADING', 'HEX', 'HIGH-VALUES', 'IDD', 'IDMS', 'IF', 'IN', 'INSERT',
1349 'JUSTIFY', 'KANJI-DATE', 'KANJI-DATE-LONG', 'KANJI-TIME', 'KEY',
1350 'KEY-PRESSED', 'KOKUGO', 'KUN', 'LAST-DUP', 'LE', 'LEVEL', 'LIKE',
1351 'LINE', 'LINE-COUNT', 'LINE-NUMBER', 'LINK', 'LIST', 'LOW-VALUES',
1352 'LQ', 'LS', 'LT', 'MACRO', 'MASK', 'MATCHED', 'MEND', 'MESSAGE',
1353 'MOVE', 'MSTART', 'NE', 'NEWPAGE', 'NOMASK', 'NOPRINT', 'NOT',
1354 'NOTE', 'NOVERIFY', 'NQ', 'NULL', 'OF', 'OR', 'OTHERWISE', 'PA1',
1355 'PA2', 'PA3', 'PAGE-COUNT', 'PAGE-NUMBER', 'PARM-REGISTER',
1356 'PATH-ID', 'PATTERN', 'PERFORM', 'POINT', 'POS', 'PRIMARY', 'PRINT',
1357 'PROCEDURE', 'PROGRAM', 'PUT', 'READ', 'RECORD', 'RECORD-COUNT',
1358 'RECORD-LENGTH', 'REFRESH', 'RELEASE', 'RENUM', 'REPEAT', 'REPORT',
1359 'REPORT-INPUT', 'RESHOW', 'RESTART', 'RETRIEVE', 'RETURN-CODE',
1360 'ROLLBACK', 'ROW', 'S', 'SCREEN', 'SEARCH', 'SECONDARY', 'SELECT',
1361 'SEQUENCE', 'SIZE', 'SKIP', 'SOKAKU', 'SORT', 'SQL', 'STOP', 'SUM',
1362 'SYSDATE', 'SYSDATE-LONG', 'SYSIN', 'SYSIPT', 'SYSLST', 'SYSPRINT',
1363 'SYSSNAP', 'SYSTIME', 'TALLY', 'TERM-COLUMNS', 'TERM-NAME',
1364 'TERM-ROWS', 'TERMINATION', 'TITLE', 'TO', 'TRANSFER', 'TRC',
1365 'UNIQUE', 'UNTIL', 'UPDATE', 'UPPERCASE', 'USER', 'USERID', 'VALUE',
1366 'VERIFY', 'W', 'WHEN', 'WHILE', 'WORK', 'WRITE', 'X', 'XDM', 'XRST'
1367 ]
1368
1369 tokens = {
1370 'root': [
1371 (r'\*.*\n', Comment.Single),
1372 (r'\n+', Whitespace),
1373 # Macro argument
1374 (r'&' + _NON_DELIMITER_OR_COMMENT_PATTERN + r'+\.', Name.Variable,
1375 'after_macro_argument'),
1376 # Macro call
1377 (r'%' + _NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name.Variable),
1378 (r'(FILE|MACRO|REPORT)(\s+)',
1379 bygroups(Keyword.Declaration, Whitespace), 'after_declaration'),
1380 (r'(JOB|PARM)' + r'(' + _DELIMITER_PATTERN + r')',
1381 bygroups(Keyword.Declaration, Operator)),
1382 (words(_KEYWORDS, suffix=_DELIMITER_PATTERN_CAPTURE),
1383 bygroups(Keyword.Reserved, Operator)),
1384 (_OPERATORS_PATTERN, Operator),
1385 # Procedure declaration
1386 (r'(' + _NON_DELIMITER_OR_COMMENT_PATTERN + r'+)(\s*)(\.?)(\s*)(PROC)(\s*\n)',
1387 bygroups(Name.Function, Whitespace, Operator, Whitespace,
1388 Keyword.Declaration, Whitespace)),
1389 (r'[0-9]+\.[0-9]*', Number.Float),
1390 (r'[0-9]+', Number.Integer),
1391 (r"'(''|[^'])*'", String),
1392 (r'\s+', Whitespace),
1393 # Everything else just belongs to a name
1394 (_NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name),
1395 ],
1396 'after_declaration': [
1397 (_NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name.Function),
1398 default('#pop'),
1399 ],
1400 'after_macro_argument': [
1401 (r'\*.*\n', Comment.Single, '#pop'),
1402 (r'\s+', Whitespace, '#pop'),
1403 (_OPERATORS_PATTERN, Operator, '#pop'),
1404 (r"'(''|[^'])*'", String, '#pop'),
1405 # Everything else just belongs to a name
1406 (_NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name),
1407 ],
1408 }
1409 _COMMENT_LINE_REGEX = re.compile(r'^\s*\*')
1410 _MACRO_HEADER_REGEX = re.compile(r'^\s*MACRO')
1411
1412 def analyse_text(text):
1413 """
1414 Perform a structural analysis for basic Easytrieve constructs.
1415 """
1416 result = 0.0
1417 lines = text.split('\n')
1418 hasEndProc = False
1419 hasHeaderComment = False
1420 hasFile = False
1421 hasJob = False
1422 hasProc = False
1423 hasParm = False
1424 hasReport = False
1425
1426 def isCommentLine(line):
1427 return EasytrieveLexer._COMMENT_LINE_REGEX.match(lines[0]) is not None
1428
1429 def isEmptyLine(line):
1430 return not bool(line.strip())
1431
1432 # Remove possible empty lines and header comments.
1433 while lines and (isEmptyLine(lines[0]) or isCommentLine(lines[0])):
1434 if not isEmptyLine(lines[0]):
1435 hasHeaderComment = True
1436 del lines[0]
1437
1438 if EasytrieveLexer._MACRO_HEADER_REGEX.match(lines[0]):
1439 # Looks like an Easytrieve macro.
1440 result = 0.4
1441 if hasHeaderComment:
1442 result += 0.4
1443 else:
1444 # Scan the source for lines starting with indicators.
1445 for line in lines:
1446 words = line.split()
1447 if (len(words) >= 2):
1448 firstWord = words[0]
1449 if not hasReport:
1450 if not hasJob:
1451 if not hasFile:
1452 if not hasParm:
1453 if firstWord == 'PARM':
1454 hasParm = True
1455 if firstWord == 'FILE':
1456 hasFile = True
1457 if firstWord == 'JOB':
1458 hasJob = True
1459 elif firstWord == 'PROC':
1460 hasProc = True
1461 elif firstWord == 'END-PROC':
1462 hasEndProc = True
1463 elif firstWord == 'REPORT':
1464 hasReport = True
1465
1466 # Weight the findings.
1467 if hasJob and (hasProc == hasEndProc):
1468 if hasHeaderComment:
1469 result += 0.1
1470 if hasParm:
1471 if hasProc:
1472 # Found PARM, JOB and PROC/END-PROC:
1473 # pretty sure this is Easytrieve.
1474 result += 0.8
1475 else:
1476 # Found PARAM and JOB: probably this is Easytrieve
1477 result += 0.5
1478 else:
1479 # Found JOB and possibly other keywords: might be Easytrieve
1480 result += 0.11
1481 if hasParm:
1482 # Note: PARAM is not a proper English word, so this is
1483 # regarded a much better indicator for Easytrieve than
1484 # the other words.
1485 result += 0.2
1486 if hasFile:
1487 result += 0.01
1488 if hasReport:
1489 result += 0.01
1490 assert 0.0 <= result <= 1.0
1491 return result
1492
1493
1494class JclLexer(RegexLexer):
1495 """
1496 Job Control Language (JCL)
1497 is a scripting language used on mainframe platforms to instruct the system
1498 on how to run a batch job or start a subsystem. It is somewhat
1499 comparable to MS DOS batch and Unix shell scripts.
1500 """
1501 name = 'JCL'
1502 aliases = ['jcl']
1503 filenames = ['*.jcl']
1504 mimetypes = ['text/x-jcl']
1505 url = 'https://en.wikipedia.org/wiki/Job_Control_Language'
1506 version_added = '2.1'
1507
1508 flags = re.IGNORECASE
1509
1510 tokens = {
1511 'root': [
1512 (r'//\*.*\n', Comment.Single),
1513 (r'//', Keyword.Pseudo, 'statement'),
1514 (r'/\*', Keyword.Pseudo, 'jes2_statement'),
1515 # TODO: JES3 statement
1516 (r'.*\n', Other) # Input text or inline code in any language.
1517 ],
1518 'statement': [
1519 (r'\s*\n', Whitespace, '#pop'),
1520 (r'([a-z]\w*)(\s+)(exec|job)(\s*)',
1521 bygroups(Name.Label, Whitespace, Keyword.Reserved, Whitespace),
1522 'option'),
1523 (r'[a-z]\w*', Name.Variable, 'statement_command'),
1524 (r'\s+', Whitespace, 'statement_command'),
1525 ],
1526 'statement_command': [
1527 (r'\s+(command|cntl|dd|endctl|endif|else|include|jcllib|'
1528 r'output|pend|proc|set|then|xmit)\s+', Keyword.Reserved, 'option'),
1529 include('option')
1530 ],
1531 'jes2_statement': [
1532 (r'\s*\n', Whitespace, '#pop'),
1533 (r'\$', Keyword, 'option'),
1534 (r'\b(jobparam|message|netacct|notify|output|priority|route|'
1535 r'setup|signoff|xeq|xmit)\b', Keyword, 'option'),
1536 ],
1537 'option': [
1538 # (r'\n', Text, 'root'),
1539 (r'\*', Name.Builtin),
1540 (r'[\[\](){}<>;,]', Punctuation),
1541 (r'[-+*/=&%]', Operator),
1542 (r'[a-z_]\w*', Name),
1543 (r'\d+\.\d*', Number.Float),
1544 (r'\.\d+', Number.Float),
1545 (r'\d+', Number.Integer),
1546 (r"'", String, 'option_string'),
1547 (r'[ \t]+', Whitespace, 'option_comment'),
1548 (r'\.', Punctuation),
1549 ],
1550 'option_string': [
1551 (r"(\n)(//)", bygroups(Text, Keyword.Pseudo)),
1552 (r"''", String),
1553 (r"[^']", String),
1554 (r"'", String, '#pop'),
1555 ],
1556 'option_comment': [
1557 # (r'\n', Text, 'root'),
1558 (r'.+', Comment.Single),
1559 ]
1560 }
1561
1562 _JOB_HEADER_PATTERN = re.compile(r'^//[a-z#$@][a-z0-9#$@]{0,7}\s+job(\s+.*)?$',
1563 re.IGNORECASE)
1564
1565 def analyse_text(text):
1566 """
1567 Recognize JCL job by header.
1568 """
1569 result = 0.0
1570 lines = text.split('\n')
1571 if len(lines) > 0:
1572 if JclLexer._JOB_HEADER_PATTERN.match(lines[0]):
1573 result = 1.0
1574 assert 0.0 <= result <= 1.0
1575 return result
1576
1577
1578class MiniScriptLexer(RegexLexer):
1579 """
1580 For MiniScript source code.
1581 """
1582
1583 name = 'MiniScript'
1584 url = 'https://miniscript.org'
1585 aliases = ['miniscript', 'ms']
1586 filenames = ['*.ms']
1587 mimetypes = ['text/x-minicript', 'application/x-miniscript']
1588 version_added = '2.6'
1589
1590 tokens = {
1591 'root': [
1592 (r'#!(.*?)$', Comment.Preproc),
1593 default('base'),
1594 ],
1595 'base': [
1596 ('//.*$', Comment.Single),
1597 (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number),
1598 (r'(?i)\d+e[+-]?\d+', Number),
1599 (r'\d+', Number),
1600 (r'\n', Text),
1601 (r'[^\S\n]+', Text),
1602 (r'"', String, 'string_double'),
1603 (r'(==|!=|<=|>=|[=+\-*/%^<>.:])', Operator),
1604 (r'[;,\[\]{}()]', Punctuation),
1605 (words((
1606 'break', 'continue', 'else', 'end', 'for', 'function', 'if',
1607 'in', 'isa', 'then', 'repeat', 'return', 'while'), suffix=r'\b'),
1608 Keyword),
1609 (words((
1610 'abs', 'acos', 'asin', 'atan', 'ceil', 'char', 'cos', 'floor',
1611 'log', 'round', 'rnd', 'pi', 'sign', 'sin', 'sqrt', 'str', 'tan',
1612 'hasIndex', 'indexOf', 'len', 'val', 'code', 'remove', 'lower',
1613 'upper', 'replace', 'split', 'indexes', 'values', 'join', 'sum',
1614 'sort', 'shuffle', 'push', 'pop', 'pull', 'range',
1615 'print', 'input', 'time', 'wait', 'locals', 'globals', 'outer',
1616 'yield'), suffix=r'\b'),
1617 Name.Builtin),
1618 (r'(true|false|null)\b', Keyword.Constant),
1619 (r'(and|or|not|new)\b', Operator.Word),
1620 (r'(self|super|__isa)\b', Name.Builtin.Pseudo),
1621 (r'[a-zA-Z_]\w*', Name.Variable)
1622 ],
1623 'string_double': [
1624 (r'[^"\n]+', String),
1625 (r'""', String),
1626 (r'"', String, '#pop'),
1627 (r'\n', Text, '#pop'), # Stray linefeed also terminates strings.
1628 ]
1629 }