Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pygments/lexers/int_fiction.py: 78%
145 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-01 06:54 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-01 06:54 +0000
1"""
2 pygments.lexers.int_fiction
3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 Lexers for interactive fiction languages.
7 :copyright: Copyright 2006-2023 by the Pygments team, see AUTHORS.
8 :license: BSD, see LICENSE for details.
9"""
11import re
13from pygments.lexer import RegexLexer, include, bygroups, using, \
14 this, default, words
15from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
16 Number, Punctuation, Error, Generic
18__all__ = ['Inform6Lexer', 'Inform6TemplateLexer', 'Inform7Lexer',
19 'Tads3Lexer']
22class Inform6Lexer(RegexLexer):
23 """
24 For Inform 6 source code.
26 .. versionadded:: 2.0
27 """
29 name = 'Inform 6'
30 url = 'http://inform-fiction.org/'
31 aliases = ['inform6', 'i6']
32 filenames = ['*.inf']
34 flags = re.MULTILINE | re.DOTALL
36 _name = r'[a-zA-Z_]\w*'
38 # Inform 7 maps these four character classes to their ASCII
39 # equivalents. To support Inform 6 inclusions within Inform 7,
40 # Inform6Lexer maps them too.
41 _dash = '\\-\u2010-\u2014'
42 _dquote = '"\u201c\u201d'
43 _squote = "'\u2018\u2019"
44 _newline = '\\n\u0085\u2028\u2029'
46 tokens = {
47 'root': [
48 (r'\A(!%%[^%s]*[%s])+' % (_newline, _newline), Comment.Preproc,
49 'directive'),
50 default('directive')
51 ],
52 '_whitespace': [
53 (r'\s+', Text),
54 (r'![^%s]*' % _newline, Comment.Single)
55 ],
56 'default': [
57 include('_whitespace'),
58 (r'\[', Punctuation, 'many-values'), # Array initialization
59 (r':|(?=;)', Punctuation, '#pop'),
60 (r'<', Punctuation), # Second angle bracket in an action statement
61 default(('expression', '_expression'))
62 ],
64 # Expressions
65 '_expression': [
66 include('_whitespace'),
67 (r'(?=sp\b)', Text, '#pop'),
68 (r'(?=[%s%s$0-9#a-zA-Z_])' % (_dquote, _squote), Text,
69 ('#pop', 'value')),
70 (r'\+\+|[%s]{1,2}(?!>)|~~?' % _dash, Operator),
71 (r'(?=[()\[%s,?@{:;])' % _dash, Text, '#pop')
72 ],
73 'expression': [
74 include('_whitespace'),
75 (r'\(', Punctuation, ('expression', '_expression')),
76 (r'\)', Punctuation, '#pop'),
77 (r'\[', Punctuation, ('#pop', 'statements', 'locals')),
78 (r'>(?=(\s+|(![^%s]*))*[>;])' % _newline, Punctuation),
79 (r'\+\+|[%s]{2}(?!>)' % _dash, Operator),
80 (r',', Punctuation, '_expression'),
81 (r'&&?|\|\|?|[=~><]?=|[%s]{1,2}>?|\.\.?[&#]?|::|[<>+*/%%]' % _dash,
82 Operator, '_expression'),
83 (r'(has|hasnt|in|notin|ofclass|or|provides)\b', Operator.Word,
84 '_expression'),
85 (r'sp\b', Name),
86 (r'\?~?', Name.Label, 'label?'),
87 (r'[@{]', Error),
88 default('#pop')
89 ],
90 '_assembly-expression': [
91 (r'\(', Punctuation, ('#push', '_expression')),
92 (r'[\[\]]', Punctuation),
93 (r'[%s]>' % _dash, Punctuation, '_expression'),
94 (r'sp\b', Keyword.Pseudo),
95 (r';', Punctuation, '#pop:3'),
96 include('expression')
97 ],
98 '_for-expression': [
99 (r'\)', Punctuation, '#pop:2'),
100 (r':', Punctuation, '#pop'),
101 include('expression')
102 ],
103 '_keyword-expression': [
104 (r'(from|near|to)\b', Keyword, '_expression'),
105 include('expression')
106 ],
107 '_list-expression': [
108 (r',', Punctuation, '#pop'),
109 include('expression')
110 ],
111 '_object-expression': [
112 (r'has\b', Keyword.Declaration, '#pop'),
113 include('_list-expression')
114 ],
116 # Values
117 'value': [
118 include('_whitespace'),
119 # Strings
120 (r'[%s][^@][%s]' % (_squote, _squote), String.Char, '#pop'),
121 (r'([%s])(@\{[0-9a-fA-F]*\})([%s])' % (_squote, _squote),
122 bygroups(String.Char, String.Escape, String.Char), '#pop'),
123 (r'([%s])(@.{2})([%s])' % (_squote, _squote),
124 bygroups(String.Char, String.Escape, String.Char), '#pop'),
125 (r'[%s]' % _squote, String.Single, ('#pop', 'dictionary-word')),
126 (r'[%s]' % _dquote, String.Double, ('#pop', 'string')),
127 # Numbers
128 (r'\$[<>]?[+%s][0-9]*\.?[0-9]*([eE][+%s]?[0-9]+)?' % (_dash, _dash),
129 Number.Float, '#pop'),
130 (r'\$[0-9a-fA-F]+', Number.Hex, '#pop'),
131 (r'\$\$[01]+', Number.Bin, '#pop'),
132 (r'[0-9]+', Number.Integer, '#pop'),
133 # Values prefixed by hashes
134 (r'(##|#a\$)(%s)' % _name, bygroups(Operator, Name), '#pop'),
135 (r'(#g\$)(%s)' % _name,
136 bygroups(Operator, Name.Variable.Global), '#pop'),
137 (r'#[nw]\$', Operator, ('#pop', 'obsolete-dictionary-word')),
138 (r'(#r\$)(%s)' % _name, bygroups(Operator, Name.Function), '#pop'),
139 (r'#', Name.Builtin, ('#pop', 'system-constant')),
140 # System functions
141 (words((
142 'child', 'children', 'elder', 'eldest', 'glk', 'indirect', 'metaclass',
143 'parent', 'random', 'sibling', 'younger', 'youngest'), suffix=r'\b'),
144 Name.Builtin, '#pop'),
145 # Metaclasses
146 (r'(?i)(Class|Object|Routine|String)\b', Name.Builtin, '#pop'),
147 # Veneer routines
148 (words((
149 'Box__Routine', 'CA__Pr', 'CDefArt', 'CInDefArt', 'Cl__Ms',
150 'Copy__Primitive', 'CP__Tab', 'DA__Pr', 'DB__Pr', 'DefArt', 'Dynam__String',
151 'EnglishNumber', 'Glk__Wrap', 'IA__Pr', 'IB__Pr', 'InDefArt', 'Main__',
152 'Meta__class', 'OB__Move', 'OB__Remove', 'OC__Cl', 'OP__Pr', 'Print__Addr',
153 'Print__PName', 'PrintShortName', 'RA__Pr', 'RA__Sc', 'RL__Pr', 'R_Process',
154 'RT__ChG', 'RT__ChGt', 'RT__ChLDB', 'RT__ChLDW', 'RT__ChPR', 'RT__ChPrintA',
155 'RT__ChPrintC', 'RT__ChPrintO', 'RT__ChPrintS', 'RT__ChPS', 'RT__ChR',
156 'RT__ChSTB', 'RT__ChSTW', 'RT__ChT', 'RT__Err', 'RT__TrPS', 'RV__Pr',
157 'Symb__Tab', 'Unsigned__Compare', 'WV__Pr', 'Z__Region'),
158 prefix='(?i)', suffix=r'\b'),
159 Name.Builtin, '#pop'),
160 # Other built-in symbols
161 (words((
162 'call', 'copy', 'create', 'DEBUG', 'destroy', 'DICT_CHAR_SIZE',
163 'DICT_ENTRY_BYTES', 'DICT_IS_UNICODE', 'DICT_WORD_SIZE', 'DOUBLE_HI_INFINITY',
164 'DOUBLE_HI_NAN', 'DOUBLE_HI_NINFINITY', 'DOUBLE_LO_INFINITY', 'DOUBLE_LO_NAN',
165 'DOUBLE_LO_NINFINITY', 'false', 'FLOAT_INFINITY', 'FLOAT_NAN', 'FLOAT_NINFINITY',
166 'GOBJFIELD_CHAIN', 'GOBJFIELD_CHILD', 'GOBJFIELD_NAME', 'GOBJFIELD_PARENT',
167 'GOBJFIELD_PROPTAB', 'GOBJFIELD_SIBLING', 'GOBJ_EXT_START',
168 'GOBJ_TOTAL_LENGTH', 'Grammar__Version', 'INDIV_PROP_START', 'INFIX',
169 'infix__watching', 'MODULE_MODE', 'name', 'nothing', 'NUM_ATTR_BYTES', 'print',
170 'print_to_array', 'recreate', 'remaining', 'self', 'sender', 'STRICT_MODE',
171 'sw__var', 'sys__glob0', 'sys__glob1', 'sys__glob2', 'sys_statusline_flag',
172 'TARGET_GLULX', 'TARGET_ZCODE', 'temp__global2', 'temp__global3',
173 'temp__global4', 'temp_global', 'true', 'USE_MODULES', 'WORDSIZE'),
174 prefix='(?i)', suffix=r'\b'),
175 Name.Builtin, '#pop'),
176 # Other values
177 (_name, Name, '#pop')
178 ],
179 'value?': [
180 include('value'),
181 default('#pop')
182 ],
183 # Strings
184 'dictionary-word': [
185 (r'[~^]+', String.Escape),
186 (r'[^~^\\@({%s]+' % _squote, String.Single),
187 (r'[({]', String.Single),
188 (r'@\{[0-9a-fA-F]*\}', String.Escape),
189 (r'@.{2}', String.Escape),
190 (r'[%s]' % _squote, String.Single, '#pop')
191 ],
192 'string': [
193 (r'[~^]+', String.Escape),
194 (r'[^~^\\@({%s]+' % _dquote, String.Double),
195 (r'[({]', String.Double),
196 (r'\\', String.Escape),
197 (r'@(\\\s*[%s]\s*)*@((\\\s*[%s]\s*)*[0-9])*' %
198 (_newline, _newline), String.Escape),
199 (r'@(\\\s*[%s]\s*)*[({]((\\\s*[%s]\s*)*[0-9a-zA-Z_])*'
200 r'(\\\s*[%s]\s*)*[)}]' % (_newline, _newline, _newline),
201 String.Escape),
202 (r'@(\\\s*[%s]\s*)*.(\\\s*[%s]\s*)*.' % (_newline, _newline),
203 String.Escape),
204 (r'[%s]' % _dquote, String.Double, '#pop')
205 ],
206 'plain-string': [
207 (r'[^~^\\({\[\]%s]+' % _dquote, String.Double),
208 (r'[~^({\[\]]', String.Double),
209 (r'\\', String.Escape),
210 (r'[%s]' % _dquote, String.Double, '#pop')
211 ],
212 # Names
213 '_constant': [
214 include('_whitespace'),
215 (_name, Name.Constant, '#pop'),
216 include('value')
217 ],
218 'constant*': [
219 include('_whitespace'),
220 (r',', Punctuation),
221 (r'=', Punctuation, 'value?'),
222 (_name, Name.Constant, 'value?'),
223 default('#pop')
224 ],
225 '_global': [
226 include('_whitespace'),
227 (_name, Name.Variable.Global, '#pop'),
228 include('value')
229 ],
230 'label?': [
231 include('_whitespace'),
232 (_name, Name.Label, '#pop'),
233 default('#pop')
234 ],
235 'variable?': [
236 include('_whitespace'),
237 (_name, Name.Variable, '#pop'),
238 default('#pop')
239 ],
240 # Values after hashes
241 'obsolete-dictionary-word': [
242 (r'\S\w*', String.Other, '#pop')
243 ],
244 'system-constant': [
245 include('_whitespace'),
246 (_name, Name.Builtin, '#pop')
247 ],
249 # Directives
250 'directive': [
251 include('_whitespace'),
252 (r'#', Punctuation),
253 (r';', Punctuation, '#pop'),
254 (r'\[', Punctuation,
255 ('default', 'statements', 'locals', 'routine-name?')),
256 (words((
257 'abbreviate', 'endif', 'dictionary', 'ifdef', 'iffalse', 'ifndef', 'ifnot',
258 'iftrue', 'ifv3', 'ifv5', 'release', 'serial', 'switches', 'system_file',
259 'version'), prefix='(?i)', suffix=r'\b'),
260 Keyword, 'default'),
261 (r'(?i)(array|global)\b', Keyword,
262 ('default', 'directive-keyword?', '_global')),
263 (r'(?i)attribute\b', Keyword, ('default', 'alias?', '_constant')),
264 (r'(?i)class\b', Keyword,
265 ('object-body', 'duplicates', 'class-name')),
266 (r'(?i)(constant|default)\b', Keyword,
267 ('default', 'constant*')),
268 (r'(?i)(end\b)(.*)', bygroups(Keyword, Text)),
269 (r'(?i)(extend|verb)\b', Keyword, 'grammar'),
270 (r'(?i)fake_action\b', Keyword, ('default', '_constant')),
271 (r'(?i)import\b', Keyword, 'manifest'),
272 (r'(?i)(include|link|origsource)\b', Keyword,
273 ('default', 'before-plain-string?')),
274 (r'(?i)(lowstring|undef)\b', Keyword, ('default', '_constant')),
275 (r'(?i)message\b', Keyword, ('default', 'diagnostic')),
276 (r'(?i)(nearby|object)\b', Keyword,
277 ('object-body', '_object-head')),
278 (r'(?i)property\b', Keyword,
279 ('default', 'alias?', '_constant', 'property-keyword*')),
280 (r'(?i)replace\b', Keyword,
281 ('default', 'routine-name?', 'routine-name?')),
282 (r'(?i)statusline\b', Keyword, ('default', 'directive-keyword?')),
283 (r'(?i)stub\b', Keyword, ('default', 'routine-name?')),
284 (r'(?i)trace\b', Keyword,
285 ('default', 'trace-keyword?', 'trace-keyword?')),
286 (r'(?i)zcharacter\b', Keyword,
287 ('default', 'directive-keyword?', 'directive-keyword?')),
288 (_name, Name.Class, ('object-body', '_object-head'))
289 ],
290 # [, Replace, Stub
291 'routine-name?': [
292 include('_whitespace'),
293 (_name, Name.Function, '#pop'),
294 default('#pop')
295 ],
296 'locals': [
297 include('_whitespace'),
298 (r';', Punctuation, '#pop'),
299 (r'\*', Punctuation),
300 (r'"', String.Double, 'plain-string'),
301 (_name, Name.Variable)
302 ],
303 # Array
304 'many-values': [
305 include('_whitespace'),
306 (r';', Punctuation),
307 (r'\]', Punctuation, '#pop'),
308 (r':', Error),
309 default(('expression', '_expression'))
310 ],
311 # Attribute, Property
312 'alias?': [
313 include('_whitespace'),
314 (r'alias\b', Keyword, ('#pop', '_constant')),
315 default('#pop')
316 ],
317 # Class, Object, Nearby
318 'class-name': [
319 include('_whitespace'),
320 (r'(?=[,;]|(class|has|private|with)\b)', Text, '#pop'),
321 (_name, Name.Class, '#pop')
322 ],
323 'duplicates': [
324 include('_whitespace'),
325 (r'\(', Punctuation, ('#pop', 'expression', '_expression')),
326 default('#pop')
327 ],
328 '_object-head': [
329 (r'[%s]>' % _dash, Punctuation),
330 (r'(class|has|private|with)\b', Keyword.Declaration, '#pop'),
331 include('_global')
332 ],
333 'object-body': [
334 include('_whitespace'),
335 (r';', Punctuation, '#pop:2'),
336 (r',', Punctuation),
337 (r'class\b', Keyword.Declaration, 'class-segment'),
338 (r'(has|private|with)\b', Keyword.Declaration),
339 (r':', Error),
340 default(('_object-expression', '_expression'))
341 ],
342 'class-segment': [
343 include('_whitespace'),
344 (r'(?=[,;]|(class|has|private|with)\b)', Text, '#pop'),
345 (_name, Name.Class),
346 default('value')
347 ],
348 # Extend, Verb
349 'grammar': [
350 include('_whitespace'),
351 (r'=', Punctuation, ('#pop', 'default')),
352 (r'\*', Punctuation, ('#pop', 'grammar-line')),
353 default('_directive-keyword')
354 ],
355 'grammar-line': [
356 include('_whitespace'),
357 (r';', Punctuation, '#pop'),
358 (r'[/*]', Punctuation),
359 (r'[%s]>' % _dash, Punctuation, 'value'),
360 (r'(noun|scope)\b', Keyword, '=routine'),
361 default('_directive-keyword')
362 ],
363 '=routine': [
364 include('_whitespace'),
365 (r'=', Punctuation, 'routine-name?'),
366 default('#pop')
367 ],
368 # Import
369 'manifest': [
370 include('_whitespace'),
371 (r';', Punctuation, '#pop'),
372 (r',', Punctuation),
373 (r'(?i)global\b', Keyword, '_global'),
374 default('_global')
375 ],
376 # Include, Link, Message
377 'diagnostic': [
378 include('_whitespace'),
379 (r'[%s]' % _dquote, String.Double, ('#pop', 'message-string')),
380 default(('#pop', 'before-plain-string?', 'directive-keyword?'))
381 ],
382 'before-plain-string?': [
383 include('_whitespace'),
384 (r'[%s]' % _dquote, String.Double, ('#pop', 'plain-string')),
385 default('#pop')
386 ],
387 'message-string': [
388 (r'[~^]+', String.Escape),
389 include('plain-string')
390 ],
392 # Keywords used in directives
393 '_directive-keyword!': [
394 include('_whitespace'),
395 (words((
396 'additive', 'alias', 'buffer', 'class', 'creature', 'data', 'error', 'fatalerror',
397 'first', 'has', 'held', 'individual', 'initial', 'initstr', 'last', 'long', 'meta',
398 'multi', 'multiexcept', 'multiheld', 'multiinside', 'noun', 'number', 'only',
399 'private', 'replace', 'reverse', 'scope', 'score', 'special', 'string', 'table',
400 'terminating', 'time', 'topic', 'warning', 'with'), suffix=r'\b'),
401 Keyword, '#pop'),
402 (r'static\b', Keyword),
403 (r'[%s]{1,2}>|[+=]' % _dash, Punctuation, '#pop')
404 ],
405 '_directive-keyword': [
406 include('_directive-keyword!'),
407 include('value')
408 ],
409 'directive-keyword?': [
410 include('_directive-keyword!'),
411 default('#pop')
412 ],
413 'property-keyword*': [
414 include('_whitespace'),
415 (words(('additive', 'individual', 'long'),
416 suffix=r'\b(?=(\s*|(![^%s]*[%s]))*[_a-zA-Z])' % (_newline, _newline)),
417 Keyword),
418 default('#pop')
419 ],
420 'trace-keyword?': [
421 include('_whitespace'),
422 (words((
423 'assembly', 'dictionary', 'expressions', 'lines', 'linker',
424 'objects', 'off', 'on', 'symbols', 'tokens', 'verbs'), suffix=r'\b'),
425 Keyword, '#pop'),
426 default('#pop')
427 ],
429 # Statements
430 'statements': [
431 include('_whitespace'),
432 (r'\]', Punctuation, '#pop'),
433 (r'[;{}]', Punctuation),
434 (words((
435 'box', 'break', 'continue', 'default', 'give', 'inversion',
436 'new_line', 'quit', 'read', 'remove', 'return', 'rfalse', 'rtrue',
437 'spaces', 'string', 'until'), suffix=r'\b'),
438 Keyword, 'default'),
439 (r'(do|else)\b', Keyword),
440 (r'(font|style)\b', Keyword,
441 ('default', 'miscellaneous-keyword?')),
442 (r'for\b', Keyword, ('for', '(?')),
443 (r'(if|switch|while)', Keyword,
444 ('expression', '_expression', '(?')),
445 (r'(jump|save|restore)\b', Keyword, ('default', 'label?')),
446 (r'objectloop\b', Keyword,
447 ('_keyword-expression', 'variable?', '(?')),
448 (r'print(_ret)?\b|(?=[%s])' % _dquote, Keyword, 'print-list'),
449 (r'\.', Name.Label, 'label?'),
450 (r'@', Keyword, 'opcode'),
451 (r'#(?![agrnw]\$|#)', Punctuation, 'directive'),
452 (r'<', Punctuation, 'default'),
453 (r'move\b', Keyword,
454 ('default', '_keyword-expression', '_expression')),
455 default(('default', '_keyword-expression', '_expression'))
456 ],
457 'miscellaneous-keyword?': [
458 include('_whitespace'),
459 (r'(bold|fixed|from|near|off|on|reverse|roman|to|underline)\b',
460 Keyword, '#pop'),
461 (r'(a|A|an|address|char|name|number|object|property|string|the|'
462 r'The)\b(?=(\s+|(![^%s]*))*\))' % _newline, Keyword.Pseudo,
463 '#pop'),
464 (r'%s(?=(\s+|(![^%s]*))*\))' % (_name, _newline), Name.Function,
465 '#pop'),
466 default('#pop')
467 ],
468 '(?': [
469 include('_whitespace'),
470 (r'\(', Punctuation, '#pop'),
471 default('#pop')
472 ],
473 'for': [
474 include('_whitespace'),
475 (r';', Punctuation, ('_for-expression', '_expression')),
476 default(('_for-expression', '_expression'))
477 ],
478 'print-list': [
479 include('_whitespace'),
480 (r';', Punctuation, '#pop'),
481 (r':', Error),
482 default(('_list-expression', '_expression', '_list-expression', 'form'))
483 ],
484 'form': [
485 include('_whitespace'),
486 (r'\(', Punctuation, ('#pop', 'miscellaneous-keyword?')),
487 default('#pop')
488 ],
490 # Assembly
491 'opcode': [
492 include('_whitespace'),
493 (r'[%s]' % _dquote, String.Double, ('operands', 'plain-string')),
494 (_name, Keyword, 'operands')
495 ],
496 'operands': [
497 (r':', Error),
498 default(('_assembly-expression', '_expression'))
499 ]
500 }
502 def get_tokens_unprocessed(self, text):
503 # 'in' is either a keyword or an operator.
504 # If the token two tokens after 'in' is ')', 'in' is a keyword:
505 # objectloop(a in b)
506 # Otherwise, it is an operator:
507 # objectloop(a in b && true)
508 objectloop_queue = []
509 objectloop_token_count = -1
510 previous_token = None
511 for index, token, value in RegexLexer.get_tokens_unprocessed(self,
512 text):
513 if previous_token is Name.Variable and value == 'in':
514 objectloop_queue = [[index, token, value]]
515 objectloop_token_count = 2
516 elif objectloop_token_count > 0:
517 if token not in Comment and token not in Text:
518 objectloop_token_count -= 1
519 objectloop_queue.append((index, token, value))
520 else:
521 if objectloop_token_count == 0:
522 if objectloop_queue[-1][2] == ')':
523 objectloop_queue[0][1] = Keyword
524 while objectloop_queue:
525 yield objectloop_queue.pop(0)
526 objectloop_token_count = -1
527 yield index, token, value
528 if token not in Comment and token not in Text:
529 previous_token = token
530 while objectloop_queue:
531 yield objectloop_queue.pop(0)
533 def analyse_text(text):
534 """We try to find a keyword which seem relatively common, unfortunately
535 there is a decent overlap with Smalltalk keywords otherwise here.."""
536 result = 0
537 if re.search('\borigsource\b', text, re.IGNORECASE):
538 result += 0.05
540 return result
543class Inform7Lexer(RegexLexer):
544 """
545 For Inform 7 source code.
547 .. versionadded:: 2.0
548 """
550 name = 'Inform 7'
551 url = 'http://inform7.com/'
552 aliases = ['inform7', 'i7']
553 filenames = ['*.ni', '*.i7x']
555 flags = re.MULTILINE | re.DOTALL
557 _dash = Inform6Lexer._dash
558 _dquote = Inform6Lexer._dquote
559 _newline = Inform6Lexer._newline
560 _start = r'\A|(?<=[%s])' % _newline
562 # There are three variants of Inform 7, differing in how to
563 # interpret at signs and braces in I6T. In top-level inclusions, at
564 # signs in the first column are inweb syntax. In phrase definitions
565 # and use options, tokens in braces are treated as I7. Use options
566 # also interpret "{N}".
567 tokens = {}
568 token_variants = ['+i6t-not-inline', '+i6t-inline', '+i6t-use-option']
570 for level in token_variants:
571 tokens[level] = {
572 '+i6-root': list(Inform6Lexer.tokens['root']),
573 '+i6t-root': [ # For Inform6TemplateLexer
574 (r'[^%s]*' % Inform6Lexer._newline, Comment.Preproc,
575 ('directive', '+p'))
576 ],
577 'root': [
578 (r'(\|?\s)+', Text),
579 (r'\[', Comment.Multiline, '+comment'),
580 (r'[%s]' % _dquote, Generic.Heading,
581 ('+main', '+titling', '+titling-string')),
582 default(('+main', '+heading?'))
583 ],
584 '+titling-string': [
585 (r'[^%s]+' % _dquote, Generic.Heading),
586 (r'[%s]' % _dquote, Generic.Heading, '#pop')
587 ],
588 '+titling': [
589 (r'\[', Comment.Multiline, '+comment'),
590 (r'[^%s.;:|%s]+' % (_dquote, _newline), Generic.Heading),
591 (r'[%s]' % _dquote, Generic.Heading, '+titling-string'),
592 (r'[%s]{2}|(?<=[\s%s])\|[\s%s]' % (_newline, _dquote, _dquote),
593 Text, ('#pop', '+heading?')),
594 (r'[.;:]|(?<=[\s%s])\|' % _dquote, Text, '#pop'),
595 (r'[|%s]' % _newline, Generic.Heading)
596 ],
597 '+main': [
598 (r'(?i)[^%s:a\[(|%s]+' % (_dquote, _newline), Text),
599 (r'[%s]' % _dquote, String.Double, '+text'),
600 (r':', Text, '+phrase-definition'),
601 (r'(?i)\bas\b', Text, '+use-option'),
602 (r'\[', Comment.Multiline, '+comment'),
603 (r'(\([%s])(.*?)([%s]\))' % (_dash, _dash),
604 bygroups(Punctuation,
605 using(this, state=('+i6-root', 'directive'),
606 i6t='+i6t-not-inline'), Punctuation)),
607 (r'(%s|(?<=[\s;:.%s]))\|\s|[%s]{2,}' %
608 (_start, _dquote, _newline), Text, '+heading?'),
609 (r'(?i)[a(|%s]' % _newline, Text)
610 ],
611 '+phrase-definition': [
612 (r'\s+', Text),
613 (r'\[', Comment.Multiline, '+comment'),
614 (r'(\([%s])(.*?)([%s]\))' % (_dash, _dash),
615 bygroups(Punctuation,
616 using(this, state=('+i6-root', 'directive',
617 'default', 'statements'),
618 i6t='+i6t-inline'), Punctuation), '#pop'),
619 default('#pop')
620 ],
621 '+use-option': [
622 (r'\s+', Text),
623 (r'\[', Comment.Multiline, '+comment'),
624 (r'(\([%s])(.*?)([%s]\))' % (_dash, _dash),
625 bygroups(Punctuation,
626 using(this, state=('+i6-root', 'directive'),
627 i6t='+i6t-use-option'), Punctuation), '#pop'),
628 default('#pop')
629 ],
630 '+comment': [
631 (r'[^\[\]]+', Comment.Multiline),
632 (r'\[', Comment.Multiline, '#push'),
633 (r'\]', Comment.Multiline, '#pop')
634 ],
635 '+text': [
636 (r'[^\[%s]+' % _dquote, String.Double),
637 (r'\[.*?\]', String.Interpol),
638 (r'[%s]' % _dquote, String.Double, '#pop')
639 ],
640 '+heading?': [
641 (r'(\|?\s)+', Text),
642 (r'\[', Comment.Multiline, '+comment'),
643 (r'[%s]{4}\s+' % _dash, Text, '+documentation-heading'),
644 (r'[%s]{1,3}' % _dash, Text),
645 (r'(?i)(volume|book|part|chapter|section)\b[^%s]*' % _newline,
646 Generic.Heading, '#pop'),
647 default('#pop')
648 ],
649 '+documentation-heading': [
650 (r'\s+', Text),
651 (r'\[', Comment.Multiline, '+comment'),
652 (r'(?i)documentation\s+', Text, '+documentation-heading2'),
653 default('#pop')
654 ],
655 '+documentation-heading2': [
656 (r'\s+', Text),
657 (r'\[', Comment.Multiline, '+comment'),
658 (r'[%s]{4}\s' % _dash, Text, '+documentation'),
659 default('#pop:2')
660 ],
661 '+documentation': [
662 (r'(?i)(%s)\s*(chapter|example)\s*:[^%s]*' %
663 (_start, _newline), Generic.Heading),
664 (r'(?i)(%s)\s*section\s*:[^%s]*' % (_start, _newline),
665 Generic.Subheading),
666 (r'((%s)\t.*?[%s])+' % (_start, _newline),
667 using(this, state='+main')),
668 (r'[^%s\[]+|[%s\[]' % (_newline, _newline), Text),
669 (r'\[', Comment.Multiline, '+comment'),
670 ],
671 '+i6t-not-inline': [
672 (r'(%s)@c( .*?)?([%s]|\Z)' % (_start, _newline),
673 Comment.Preproc),
674 (r'(%s)@([%s]+|Purpose:)[^%s]*' % (_start, _dash, _newline),
675 Comment.Preproc),
676 (r'(%s)@p( .*?)?([%s]|\Z)' % (_start, _newline),
677 Generic.Heading, '+p')
678 ],
679 '+i6t-use-option': [
680 include('+i6t-not-inline'),
681 (r'(\{)(N)(\})', bygroups(Punctuation, Text, Punctuation))
682 ],
683 '+i6t-inline': [
684 (r'(\{)(\S[^}]*)?(\})',
685 bygroups(Punctuation, using(this, state='+main'),
686 Punctuation))
687 ],
688 '+i6t': [
689 (r'(\{[%s])(![^}]*)(\}?)' % _dash,
690 bygroups(Punctuation, Comment.Single, Punctuation)),
691 (r'(\{[%s])(lines)(:)([^}]*)(\}?)' % _dash,
692 bygroups(Punctuation, Keyword, Punctuation, Text,
693 Punctuation), '+lines'),
694 (r'(\{[%s])([^:}]*)(:?)([^}]*)(\}?)' % _dash,
695 bygroups(Punctuation, Keyword, Punctuation, Text,
696 Punctuation)),
697 (r'(\(\+)(.*?)(\+\)|\Z)',
698 bygroups(Punctuation, using(this, state='+main'),
699 Punctuation))
700 ],
701 '+p': [
702 (r'[^@]+', Comment.Preproc),
703 (r'(%s)@c( .*?)?([%s]|\Z)' % (_start, _newline),
704 Comment.Preproc, '#pop'),
705 (r'(%s)@([%s]|Purpose:)' % (_start, _dash), Comment.Preproc),
706 (r'(%s)@p( .*?)?([%s]|\Z)' % (_start, _newline),
707 Generic.Heading),
708 (r'@', Comment.Preproc)
709 ],
710 '+lines': [
711 (r'(%s)@c( .*?)?([%s]|\Z)' % (_start, _newline),
712 Comment.Preproc),
713 (r'(%s)@([%s]|Purpose:)[^%s]*' % (_start, _dash, _newline),
714 Comment.Preproc),
715 (r'(%s)@p( .*?)?([%s]|\Z)' % (_start, _newline),
716 Generic.Heading, '+p'),
717 (r'(%s)@\w*[ %s]' % (_start, _newline), Keyword),
718 (r'![^%s]*' % _newline, Comment.Single),
719 (r'(\{)([%s]endlines)(\})' % _dash,
720 bygroups(Punctuation, Keyword, Punctuation), '#pop'),
721 (r'[^@!{]+?([%s]|\Z)|.' % _newline, Text)
722 ]
723 }
724 # Inform 7 can include snippets of Inform 6 template language,
725 # so all of Inform6Lexer's states are copied here, with
726 # modifications to account for template syntax. Inform7Lexer's
727 # own states begin with '+' to avoid name conflicts. Some of
728 # Inform6Lexer's states begin with '_': these are not modified.
729 # They deal with template syntax either by including modified
730 # states, or by matching r'' then pushing to modified states.
731 for token in Inform6Lexer.tokens:
732 if token == 'root':
733 continue
734 tokens[level][token] = list(Inform6Lexer.tokens[token])
735 if not token.startswith('_'):
736 tokens[level][token][:0] = [include('+i6t'), include(level)]
738 def __init__(self, **options):
739 level = options.get('i6t', '+i6t-not-inline')
740 if level not in self._all_tokens:
741 self._tokens = self.__class__.process_tokendef(level)
742 else:
743 self._tokens = self._all_tokens[level]
744 RegexLexer.__init__(self, **options)
747class Inform6TemplateLexer(Inform7Lexer):
748 """
749 For Inform 6 template code.
751 .. versionadded:: 2.0
752 """
754 name = 'Inform 6 template'
755 aliases = ['i6t']
756 filenames = ['*.i6t']
758 def get_tokens_unprocessed(self, text, stack=('+i6t-root',)):
759 return Inform7Lexer.get_tokens_unprocessed(self, text, stack)
762class Tads3Lexer(RegexLexer):
763 """
764 For TADS 3 source code.
765 """
767 name = 'TADS 3'
768 aliases = ['tads3']
769 filenames = ['*.t']
771 flags = re.DOTALL | re.MULTILINE
773 _comment_single = r'(?://(?:[^\\\n]|\\+[\w\W])*$)'
774 _comment_multiline = r'(?:/\*(?:[^*]|\*(?!/))*\*/)'
775 _escape = (r'(?:\\(?:[\n\\<>"\'^v bnrt]|u[\da-fA-F]{,4}|x[\da-fA-F]{,2}|'
776 r'[0-3]?[0-7]{1,2}))')
777 _name = r'(?:[_a-zA-Z]\w*)'
778 _no_quote = r'(?=\s|\\?>)'
779 _operator = (r'(?:&&|\|\||\+\+|--|\?\?|::|[.,@\[\]~]|'
780 r'(?:[=+\-*/%!&|^]|<<?|>>?>?)=?)')
781 _ws = r'(?:\\|\s|%s|%s)' % (_comment_single, _comment_multiline)
782 _ws_pp = r'(?:\\\n|[^\S\n]|%s|%s)' % (_comment_single, _comment_multiline)
784 def _make_string_state(triple, double, verbatim=None, _escape=_escape):
785 if verbatim:
786 verbatim = ''.join(['(?:%s|%s)' % (re.escape(c.lower()),
787 re.escape(c.upper()))
788 for c in verbatim])
789 char = r'"' if double else r"'"
790 token = String.Double if double else String.Single
791 escaped_quotes = r'+|%s(?!%s{2})' % (char, char) if triple else r''
792 prefix = '%s%s' % ('t' if triple else '', 'd' if double else 's')
793 tag_state_name = '%sqt' % prefix
794 state = []
795 if triple:
796 state += [
797 (r'%s{3,}' % char, token, '#pop'),
798 (r'\\%s+' % char, String.Escape),
799 (char, token)
800 ]
801 else:
802 state.append((char, token, '#pop'))
803 state += [
804 include('s/verbatim'),
805 (r'[^\\<&{}%s]+' % char, token)
806 ]
807 if verbatim:
808 # This regex can't use `(?i)` because escape sequences are
809 # case-sensitive. `<\XMP>` works; `<\xmp>` doesn't.
810 state.append((r'\\?<(/|\\\\|(?!%s)\\)%s(?=[\s=>])' %
811 (_escape, verbatim),
812 Name.Tag, ('#pop', '%sqs' % prefix, tag_state_name)))
813 else:
814 state += [
815 (r'\\?<!([^><\\%s]|<(?!<)|\\%s%s|%s|\\.)*>?' %
816 (char, char, escaped_quotes, _escape), Comment.Multiline),
817 (r'(?i)\\?<listing(?=[\s=>]|\\>)', Name.Tag,
818 ('#pop', '%sqs/listing' % prefix, tag_state_name)),
819 (r'(?i)\\?<xmp(?=[\s=>]|\\>)', Name.Tag,
820 ('#pop', '%sqs/xmp' % prefix, tag_state_name)),
821 (r'\\?<([^\s=><\\%s]|<(?!<)|\\%s%s|%s|\\.)*' %
822 (char, char, escaped_quotes, _escape), Name.Tag,
823 tag_state_name),
824 include('s/entity')
825 ]
826 state += [
827 include('s/escape'),
828 (r'\{([^}<\\%s]|<(?!<)|\\%s%s|%s|\\.)*\}' %
829 (char, char, escaped_quotes, _escape), String.Interpol),
830 (r'[\\&{}<]', token)
831 ]
832 return state
834 def _make_tag_state(triple, double, _escape=_escape):
835 char = r'"' if double else r"'"
836 quantifier = r'{3,}' if triple else r''
837 state_name = '%s%sqt' % ('t' if triple else '', 'd' if double else 's')
838 token = String.Double if double else String.Single
839 escaped_quotes = r'+|%s(?!%s{2})' % (char, char) if triple else r''
840 return [
841 (r'%s%s' % (char, quantifier), token, '#pop:2'),
842 (r'(\s|\\\n)+', Text),
843 (r'(=)(\\?")', bygroups(Punctuation, String.Double),
844 'dqs/%s' % state_name),
845 (r"(=)(\\?')", bygroups(Punctuation, String.Single),
846 'sqs/%s' % state_name),
847 (r'=', Punctuation, 'uqs/%s' % state_name),
848 (r'\\?>', Name.Tag, '#pop'),
849 (r'\{([^}<\\%s]|<(?!<)|\\%s%s|%s|\\.)*\}' %
850 (char, char, escaped_quotes, _escape), String.Interpol),
851 (r'([^\s=><\\%s]|<(?!<)|\\%s%s|%s|\\.)+' %
852 (char, char, escaped_quotes, _escape), Name.Attribute),
853 include('s/escape'),
854 include('s/verbatim'),
855 include('s/entity'),
856 (r'[\\{}&]', Name.Attribute)
857 ]
859 def _make_attribute_value_state(terminator, host_triple, host_double,
860 _escape=_escape):
861 token = (String.Double if terminator == r'"' else
862 String.Single if terminator == r"'" else String.Other)
863 host_char = r'"' if host_double else r"'"
864 host_quantifier = r'{3,}' if host_triple else r''
865 host_token = String.Double if host_double else String.Single
866 escaped_quotes = (r'+|%s(?!%s{2})' % (host_char, host_char)
867 if host_triple else r'')
868 return [
869 (r'%s%s' % (host_char, host_quantifier), host_token, '#pop:3'),
870 (r'%s%s' % (r'' if token is String.Other else r'\\?', terminator),
871 token, '#pop'),
872 include('s/verbatim'),
873 include('s/entity'),
874 (r'\{([^}<\\%s]|<(?!<)|\\%s%s|%s|\\.)*\}' %
875 (host_char, host_char, escaped_quotes, _escape), String.Interpol),
876 (r'([^\s"\'<%s{}\\&])+' % (r'>' if token is String.Other else r''),
877 token),
878 include('s/escape'),
879 (r'["\'\s&{<}\\]', token)
880 ]
882 tokens = {
883 'root': [
884 ('\ufeff', Text),
885 (r'\{', Punctuation, 'object-body'),
886 (r';+', Punctuation),
887 (r'(?=(argcount|break|case|catch|continue|default|definingobj|'
888 r'delegated|do|else|for|foreach|finally|goto|if|inherited|'
889 r'invokee|local|nil|new|operator|replaced|return|self|switch|'
890 r'targetobj|targetprop|throw|true|try|while)\b)', Text, 'block'),
891 (r'(%s)(%s*)(\()' % (_name, _ws),
892 bygroups(Name.Function, using(this, state='whitespace'),
893 Punctuation),
894 ('block?/root', 'more/parameters', 'main/parameters')),
895 include('whitespace'),
896 (r'\++', Punctuation),
897 (r'[^\s!"%-(*->@-_a-z{-~]+', Error), # Averts an infinite loop
898 (r'(?!\Z)', Text, 'main/root')
899 ],
900 'main/root': [
901 include('main/basic'),
902 default(('#pop', 'object-body/no-braces', 'classes', 'class'))
903 ],
904 'object-body/no-braces': [
905 (r';', Punctuation, '#pop'),
906 (r'\{', Punctuation, ('#pop', 'object-body')),
907 include('object-body')
908 ],
909 'object-body': [
910 (r';', Punctuation),
911 (r'\{', Punctuation, '#push'),
912 (r'\}', Punctuation, '#pop'),
913 (r':', Punctuation, ('classes', 'class')),
914 (r'(%s?)(%s*)(\()' % (_name, _ws),
915 bygroups(Name.Function, using(this, state='whitespace'),
916 Punctuation),
917 ('block?', 'more/parameters', 'main/parameters')),
918 (r'(%s)(%s*)(\{)' % (_name, _ws),
919 bygroups(Name.Function, using(this, state='whitespace'),
920 Punctuation), 'block'),
921 (r'(%s)(%s*)(:)' % (_name, _ws),
922 bygroups(Name.Variable, using(this, state='whitespace'),
923 Punctuation),
924 ('object-body/no-braces', 'classes', 'class')),
925 include('whitespace'),
926 (r'->|%s' % _operator, Punctuation, 'main'),
927 default('main/object-body')
928 ],
929 'main/object-body': [
930 include('main/basic'),
931 (r'(%s)(%s*)(=?)' % (_name, _ws),
932 bygroups(Name.Variable, using(this, state='whitespace'),
933 Punctuation), ('#pop', 'more', 'main')),
934 default('#pop:2')
935 ],
936 'block?/root': [
937 (r'\{', Punctuation, ('#pop', 'block')),
938 include('whitespace'),
939 (r'(?=[\[\'"<(:])', Text, # It might be a VerbRule macro.
940 ('#pop', 'object-body/no-braces', 'grammar', 'grammar-rules')),
941 # It might be a macro like DefineAction.
942 default(('#pop', 'object-body/no-braces'))
943 ],
944 'block?': [
945 (r'\{', Punctuation, ('#pop', 'block')),
946 include('whitespace'),
947 default('#pop')
948 ],
949 'block/basic': [
950 (r'[;:]+', Punctuation),
951 (r'\{', Punctuation, '#push'),
952 (r'\}', Punctuation, '#pop'),
953 (r'default\b', Keyword.Reserved),
954 (r'(%s)(%s*)(:)' % (_name, _ws),
955 bygroups(Name.Label, using(this, state='whitespace'),
956 Punctuation)),
957 include('whitespace')
958 ],
959 'block': [
960 include('block/basic'),
961 (r'(?!\Z)', Text, ('more', 'main'))
962 ],
963 'block/embed': [
964 (r'>>', String.Interpol, '#pop'),
965 include('block/basic'),
966 (r'(?!\Z)', Text, ('more/embed', 'main'))
967 ],
968 'main/basic': [
969 include('whitespace'),
970 (r'\(', Punctuation, ('#pop', 'more', 'main')),
971 (r'\[', Punctuation, ('#pop', 'more/list', 'main')),
972 (r'\{', Punctuation, ('#pop', 'more/inner', 'main/inner',
973 'more/parameters', 'main/parameters')),
974 (r'\*|\.{3}', Punctuation, '#pop'),
975 (r'(?i)0x[\da-f]+', Number.Hex, '#pop'),
976 (r'(\d+\.(?!\.)\d*|\.\d+)([eE][-+]?\d+)?|\d+[eE][-+]?\d+',
977 Number.Float, '#pop'),
978 (r'0[0-7]+', Number.Oct, '#pop'),
979 (r'\d+', Number.Integer, '#pop'),
980 (r'"""', String.Double, ('#pop', 'tdqs')),
981 (r"'''", String.Single, ('#pop', 'tsqs')),
982 (r'"', String.Double, ('#pop', 'dqs')),
983 (r"'", String.Single, ('#pop', 'sqs')),
984 (r'R"""', String.Regex, ('#pop', 'tdqr')),
985 (r"R'''", String.Regex, ('#pop', 'tsqr')),
986 (r'R"', String.Regex, ('#pop', 'dqr')),
987 (r"R'", String.Regex, ('#pop', 'sqr')),
988 # Two-token keywords
989 (r'(extern)(%s+)(object\b)' % _ws,
990 bygroups(Keyword.Reserved, using(this, state='whitespace'),
991 Keyword.Reserved)),
992 (r'(function|method)(%s*)(\()' % _ws,
993 bygroups(Keyword.Reserved, using(this, state='whitespace'),
994 Punctuation),
995 ('#pop', 'block?', 'more/parameters', 'main/parameters')),
996 (r'(modify)(%s+)(grammar\b)' % _ws,
997 bygroups(Keyword.Reserved, using(this, state='whitespace'),
998 Keyword.Reserved),
999 ('#pop', 'object-body/no-braces', ':', 'grammar')),
1000 (r'(new)(%s+(?=(?:function|method)\b))' % _ws,
1001 bygroups(Keyword.Reserved, using(this, state='whitespace'))),
1002 (r'(object)(%s+)(template\b)' % _ws,
1003 bygroups(Keyword.Reserved, using(this, state='whitespace'),
1004 Keyword.Reserved), ('#pop', 'template')),
1005 (r'(string)(%s+)(template\b)' % _ws,
1006 bygroups(Keyword, using(this, state='whitespace'),
1007 Keyword.Reserved), ('#pop', 'function-name')),
1008 # Keywords
1009 (r'(argcount|definingobj|invokee|replaced|targetobj|targetprop)\b',
1010 Name.Builtin, '#pop'),
1011 (r'(break|continue|goto)\b', Keyword.Reserved, ('#pop', 'label')),
1012 (r'(case|extern|if|intrinsic|return|static|while)\b',
1013 Keyword.Reserved),
1014 (r'catch\b', Keyword.Reserved, ('#pop', 'catch')),
1015 (r'class\b', Keyword.Reserved,
1016 ('#pop', 'object-body/no-braces', 'class')),
1017 (r'(default|do|else|finally|try)\b', Keyword.Reserved, '#pop'),
1018 (r'(dictionary|property)\b', Keyword.Reserved,
1019 ('#pop', 'constants')),
1020 (r'enum\b', Keyword.Reserved, ('#pop', 'enum')),
1021 (r'export\b', Keyword.Reserved, ('#pop', 'main')),
1022 (r'(for|foreach)\b', Keyword.Reserved,
1023 ('#pop', 'more/inner', 'main/inner')),
1024 (r'(function|method)\b', Keyword.Reserved,
1025 ('#pop', 'block?', 'function-name')),
1026 (r'grammar\b', Keyword.Reserved,
1027 ('#pop', 'object-body/no-braces', 'grammar')),
1028 (r'inherited\b', Keyword.Reserved, ('#pop', 'inherited')),
1029 (r'local\b', Keyword.Reserved,
1030 ('#pop', 'more/local', 'main/local')),
1031 (r'(modify|replace|switch|throw|transient)\b', Keyword.Reserved,
1032 '#pop'),
1033 (r'new\b', Keyword.Reserved, ('#pop', 'class')),
1034 (r'(nil|true)\b', Keyword.Constant, '#pop'),
1035 (r'object\b', Keyword.Reserved, ('#pop', 'object-body/no-braces')),
1036 (r'operator\b', Keyword.Reserved, ('#pop', 'operator')),
1037 (r'propertyset\b', Keyword.Reserved,
1038 ('#pop', 'propertyset', 'main')),
1039 (r'self\b', Name.Builtin.Pseudo, '#pop'),
1040 (r'template\b', Keyword.Reserved, ('#pop', 'template')),
1041 # Operators
1042 (r'(__objref|defined)(%s*)(\()' % _ws,
1043 bygroups(Operator.Word, using(this, state='whitespace'),
1044 Operator), ('#pop', 'more/__objref', 'main')),
1045 (r'delegated\b', Operator.Word),
1046 # Compiler-defined macros and built-in properties
1047 (r'(__DATE__|__DEBUG|__LINE__|__FILE__|'
1048 r'__TADS_MACRO_FORMAT_VERSION|__TADS_SYS_\w*|__TADS_SYSTEM_NAME|'
1049 r'__TADS_VERSION_MAJOR|__TADS_VERSION_MINOR|__TADS3|__TIME__|'
1050 r'construct|finalize|grammarInfo|grammarTag|lexicalParent|'
1051 r'miscVocab|sourceTextGroup|sourceTextGroupName|'
1052 r'sourceTextGroupOrder|sourceTextOrder)\b', Name.Builtin, '#pop')
1053 ],
1054 'main': [
1055 include('main/basic'),
1056 (_name, Name, '#pop'),
1057 default('#pop')
1058 ],
1059 'more/basic': [
1060 (r'\(', Punctuation, ('more/list', 'main')),
1061 (r'\[', Punctuation, ('more', 'main')),
1062 (r'\.{3}', Punctuation),
1063 (r'->|\.\.', Punctuation, 'main'),
1064 (r'(?=;)|[:)\]]', Punctuation, '#pop'),
1065 include('whitespace'),
1066 (_operator, Operator, 'main'),
1067 (r'\?', Operator, ('main', 'more/conditional', 'main')),
1068 (r'(is|not)(%s+)(in\b)' % _ws,
1069 bygroups(Operator.Word, using(this, state='whitespace'),
1070 Operator.Word)),
1071 (r'[^\s!"%-_a-z{-~]+', Error) # Averts an infinite loop
1072 ],
1073 'more': [
1074 include('more/basic'),
1075 default('#pop')
1076 ],
1077 # Then expression (conditional operator)
1078 'more/conditional': [
1079 (r':(?!:)', Operator, '#pop'),
1080 include('more')
1081 ],
1082 # Embedded expressions
1083 'more/embed': [
1084 (r'>>', String.Interpol, '#pop:2'),
1085 include('more')
1086 ],
1087 # For/foreach loop initializer or short-form anonymous function
1088 'main/inner': [
1089 (r'\(', Punctuation, ('#pop', 'more/inner', 'main/inner')),
1090 (r'local\b', Keyword.Reserved, ('#pop', 'main/local')),
1091 include('main')
1092 ],
1093 'more/inner': [
1094 (r'\}', Punctuation, '#pop'),
1095 (r',', Punctuation, 'main/inner'),
1096 (r'(in|step)\b', Keyword, 'main/inner'),
1097 include('more')
1098 ],
1099 # Local
1100 'main/local': [
1101 (_name, Name.Variable, '#pop'),
1102 include('whitespace')
1103 ],
1104 'more/local': [
1105 (r',', Punctuation, 'main/local'),
1106 include('more')
1107 ],
1108 # List
1109 'more/list': [
1110 (r'[,:]', Punctuation, 'main'),
1111 include('more')
1112 ],
1113 # Parameter list
1114 'main/parameters': [
1115 (r'(%s)(%s*)(?=:)' % (_name, _ws),
1116 bygroups(Name.Variable, using(this, state='whitespace')), '#pop'),
1117 (r'(%s)(%s+)(%s)' % (_name, _ws, _name),
1118 bygroups(Name.Class, using(this, state='whitespace'),
1119 Name.Variable), '#pop'),
1120 (r'\[+', Punctuation),
1121 include('main/basic'),
1122 (_name, Name.Variable, '#pop'),
1123 default('#pop')
1124 ],
1125 'more/parameters': [
1126 (r'(:)(%s*(?=[?=,:)]))' % _ws,
1127 bygroups(Punctuation, using(this, state='whitespace'))),
1128 (r'[?\]]+', Punctuation),
1129 (r'[:)]', Punctuation, ('#pop', 'multimethod?')),
1130 (r',', Punctuation, 'main/parameters'),
1131 (r'=', Punctuation, ('more/parameter', 'main')),
1132 include('more')
1133 ],
1134 'more/parameter': [
1135 (r'(?=[,)])', Text, '#pop'),
1136 include('more')
1137 ],
1138 'multimethod?': [
1139 (r'multimethod\b', Keyword, '#pop'),
1140 include('whitespace'),
1141 default('#pop')
1142 ],
1144 # Statements and expressions
1145 'more/__objref': [
1146 (r',', Punctuation, 'mode'),
1147 (r'\)', Operator, '#pop'),
1148 include('more')
1149 ],
1150 'mode': [
1151 (r'(error|warn)\b', Keyword, '#pop'),
1152 include('whitespace')
1153 ],
1154 'catch': [
1155 (r'\(+', Punctuation),
1156 (_name, Name.Exception, ('#pop', 'variables')),
1157 include('whitespace')
1158 ],
1159 'enum': [
1160 include('whitespace'),
1161 (r'token\b', Keyword, ('#pop', 'constants')),
1162 default(('#pop', 'constants'))
1163 ],
1164 'grammar': [
1165 (r'\)+', Punctuation),
1166 (r'\(', Punctuation, 'grammar-tag'),
1167 (r':', Punctuation, 'grammar-rules'),
1168 (_name, Name.Class),
1169 include('whitespace')
1170 ],
1171 'grammar-tag': [
1172 include('whitespace'),
1173 (r'"""([^\\"<]|""?(?!")|\\"+|\\.|<(?!<))+("{3,}|<<)|'
1174 r'R"""([^\\"]|""?(?!")|\\"+|\\.)+"{3,}|'
1175 r"'''([^\\'<]|''?(?!')|\\'+|\\.|<(?!<))+('{3,}|<<)|"
1176 r"R'''([^\\']|''?(?!')|\\'+|\\.)+'{3,}|"
1177 r'"([^\\"<]|\\.|<(?!<))+("|<<)|R"([^\\"]|\\.)+"|'
1178 r"'([^\\'<]|\\.|<(?!<))+('|<<)|R'([^\\']|\\.)+'|"
1179 r"([^)\s\\/]|/(?![/*]))+|\)", String.Other, '#pop')
1180 ],
1181 'grammar-rules': [
1182 include('string'),
1183 include('whitespace'),
1184 (r'(\[)(%s*)(badness)' % _ws,
1185 bygroups(Punctuation, using(this, state='whitespace'), Keyword),
1186 'main'),
1187 (r'->|%s|[()]' % _operator, Punctuation),
1188 (_name, Name.Constant),
1189 default('#pop:2')
1190 ],
1191 ':': [
1192 (r':', Punctuation, '#pop')
1193 ],
1194 'function-name': [
1195 (r'(<<([^>]|>>>|>(?!>))*>>)+', String.Interpol),
1196 (r'(?=%s?%s*[({])' % (_name, _ws), Text, '#pop'),
1197 (_name, Name.Function, '#pop'),
1198 include('whitespace')
1199 ],
1200 'inherited': [
1201 (r'<', Punctuation, ('#pop', 'classes', 'class')),
1202 include('whitespace'),
1203 (_name, Name.Class, '#pop'),
1204 default('#pop')
1205 ],
1206 'operator': [
1207 (r'negate\b', Operator.Word, '#pop'),
1208 include('whitespace'),
1209 (_operator, Operator),
1210 default('#pop')
1211 ],
1212 'propertyset': [
1213 (r'\(', Punctuation, ('more/parameters', 'main/parameters')),
1214 (r'\{', Punctuation, ('#pop', 'object-body')),
1215 include('whitespace')
1216 ],
1217 'template': [
1218 (r'(?=;)', Text, '#pop'),
1219 include('string'),
1220 (r'inherited\b', Keyword.Reserved),
1221 include('whitespace'),
1222 (r'->|\?|%s' % _operator, Punctuation),
1223 (_name, Name.Variable)
1224 ],
1226 # Identifiers
1227 'class': [
1228 (r'\*|\.{3}', Punctuation, '#pop'),
1229 (r'object\b', Keyword.Reserved, '#pop'),
1230 (r'transient\b', Keyword.Reserved),
1231 (_name, Name.Class, '#pop'),
1232 include('whitespace'),
1233 default('#pop')
1234 ],
1235 'classes': [
1236 (r'[:,]', Punctuation, 'class'),
1237 include('whitespace'),
1238 (r'>', Punctuation, '#pop'),
1239 default('#pop')
1240 ],
1241 'constants': [
1242 (r',+', Punctuation),
1243 (r';', Punctuation, '#pop'),
1244 (r'property\b', Keyword.Reserved),
1245 (_name, Name.Constant),
1246 include('whitespace')
1247 ],
1248 'label': [
1249 (_name, Name.Label, '#pop'),
1250 include('whitespace'),
1251 default('#pop')
1252 ],
1253 'variables': [
1254 (r',+', Punctuation),
1255 (r'\)', Punctuation, '#pop'),
1256 include('whitespace'),
1257 (_name, Name.Variable)
1258 ],
1260 # Whitespace and comments
1261 'whitespace': [
1262 (r'^%s*#(%s|[^\n]|(?<=\\)\n)*\n?' % (_ws_pp, _comment_multiline),
1263 Comment.Preproc),
1264 (_comment_single, Comment.Single),
1265 (_comment_multiline, Comment.Multiline),
1266 (r'\\+\n+%s*#?|\n+|([^\S\n]|\\)+' % _ws_pp, Text)
1267 ],
1269 # Strings
1270 'string': [
1271 (r'"""', String.Double, 'tdqs'),
1272 (r"'''", String.Single, 'tsqs'),
1273 (r'"', String.Double, 'dqs'),
1274 (r"'", String.Single, 'sqs')
1275 ],
1276 's/escape': [
1277 (r'\{\{|\}\}|%s' % _escape, String.Escape)
1278 ],
1279 's/verbatim': [
1280 (r'<<\s*(as\s+decreasingly\s+likely\s+outcomes|cycling|else|end|'
1281 r'first\s+time|one\s+of|only|or|otherwise|'
1282 r'(sticky|(then\s+)?(purely\s+)?at)\s+random|stopping|'
1283 r'(then\s+)?(half\s+)?shuffled|\|\|)\s*>>', String.Interpol),
1284 (r'<<(%%(_(%s|\\?.)|[\-+ ,#]|\[\d*\]?)*\d*\.?\d*(%s|\\?.)|'
1285 r'\s*((else|otherwise)\s+)?(if|unless)\b)?' % (_escape, _escape),
1286 String.Interpol, ('block/embed', 'more/embed', 'main'))
1287 ],
1288 's/entity': [
1289 (r'(?i)&(#(x[\da-f]+|\d+)|[a-z][\da-z]*);?', Name.Entity)
1290 ],
1291 'tdqs': _make_string_state(True, True),
1292 'tsqs': _make_string_state(True, False),
1293 'dqs': _make_string_state(False, True),
1294 'sqs': _make_string_state(False, False),
1295 'tdqs/listing': _make_string_state(True, True, 'listing'),
1296 'tsqs/listing': _make_string_state(True, False, 'listing'),
1297 'dqs/listing': _make_string_state(False, True, 'listing'),
1298 'sqs/listing': _make_string_state(False, False, 'listing'),
1299 'tdqs/xmp': _make_string_state(True, True, 'xmp'),
1300 'tsqs/xmp': _make_string_state(True, False, 'xmp'),
1301 'dqs/xmp': _make_string_state(False, True, 'xmp'),
1302 'sqs/xmp': _make_string_state(False, False, 'xmp'),
1304 # Tags
1305 'tdqt': _make_tag_state(True, True),
1306 'tsqt': _make_tag_state(True, False),
1307 'dqt': _make_tag_state(False, True),
1308 'sqt': _make_tag_state(False, False),
1309 'dqs/tdqt': _make_attribute_value_state(r'"', True, True),
1310 'dqs/tsqt': _make_attribute_value_state(r'"', True, False),
1311 'dqs/dqt': _make_attribute_value_state(r'"', False, True),
1312 'dqs/sqt': _make_attribute_value_state(r'"', False, False),
1313 'sqs/tdqt': _make_attribute_value_state(r"'", True, True),
1314 'sqs/tsqt': _make_attribute_value_state(r"'", True, False),
1315 'sqs/dqt': _make_attribute_value_state(r"'", False, True),
1316 'sqs/sqt': _make_attribute_value_state(r"'", False, False),
1317 'uqs/tdqt': _make_attribute_value_state(_no_quote, True, True),
1318 'uqs/tsqt': _make_attribute_value_state(_no_quote, True, False),
1319 'uqs/dqt': _make_attribute_value_state(_no_quote, False, True),
1320 'uqs/sqt': _make_attribute_value_state(_no_quote, False, False),
1322 # Regular expressions
1323 'tdqr': [
1324 (r'[^\\"]+', String.Regex),
1325 (r'\\"*', String.Regex),
1326 (r'"{3,}', String.Regex, '#pop'),
1327 (r'"', String.Regex)
1328 ],
1329 'tsqr': [
1330 (r"[^\\']+", String.Regex),
1331 (r"\\'*", String.Regex),
1332 (r"'{3,}", String.Regex, '#pop'),
1333 (r"'", String.Regex)
1334 ],
1335 'dqr': [
1336 (r'[^\\"]+', String.Regex),
1337 (r'\\"?', String.Regex),
1338 (r'"', String.Regex, '#pop')
1339 ],
1340 'sqr': [
1341 (r"[^\\']+", String.Regex),
1342 (r"\\'?", String.Regex),
1343 (r"'", String.Regex, '#pop')
1344 ]
1345 }
1347 def get_tokens_unprocessed(self, text, **kwargs):
1348 pp = r'^%s*#%s*' % (self._ws_pp, self._ws_pp)
1349 if_false_level = 0
1350 for index, token, value in (
1351 RegexLexer.get_tokens_unprocessed(self, text, **kwargs)):
1352 if if_false_level == 0: # Not in a false #if
1353 if (token is Comment.Preproc and
1354 re.match(r'%sif%s+(0|nil)%s*$\n?' %
1355 (pp, self._ws_pp, self._ws_pp), value)):
1356 if_false_level = 1
1357 else: # In a false #if
1358 if token is Comment.Preproc:
1359 if (if_false_level == 1 and
1360 re.match(r'%sel(if|se)\b' % pp, value)):
1361 if_false_level = 0
1362 elif re.match(r'%sif' % pp, value):
1363 if_false_level += 1
1364 elif re.match(r'%sendif\b' % pp, value):
1365 if_false_level -= 1
1366 else:
1367 token = Comment
1368 yield index, token, value
1370 def analyse_text(text):
1371 """This is a rather generic descriptive language without strong
1372 identifiers. It looks like a 'GameMainDef' has to be present,
1373 and/or a 'versionInfo' with an 'IFID' field."""
1374 result = 0
1375 if '__TADS' in text or 'GameMainDef' in text:
1376 result += 0.2
1378 # This is a fairly unique keyword which is likely used in source as well
1379 if 'versionInfo' in text and 'IFID' in text:
1380 result += 0.1
1382 return result