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

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

eric ide

mercurial