/ src / theme / languages / cpp.js
cpp.js
  1  /*! `cpp` grammar compiled for Highlight.js 11.10.0 */
  2    (function(){
  3      var hljsGrammar = (function () {
  4    'use strict';
  5  
  6    /*
  7    Language: C++
  8    Category: common, system
  9    Website: https://isocpp.org
 10    */
 11  
 12    /** @type LanguageFn */
 13    function cpp(hljs) {
 14      const regex = hljs.regex;
 15      // added for historic reasons because `hljs.C_LINE_COMMENT_MODE` does
 16      // not include such support nor can we be sure all the grammars depending
 17      // on it would desire this behavior
 18      const C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$', { contains: [ { begin: /\\\n/ } ] });
 19      const DECLTYPE_AUTO_RE = 'decltype\\(auto\\)';
 20      const NAMESPACE_RE = '[a-zA-Z_]\\w*::';
 21      const TEMPLATE_ARGUMENT_RE = '<[^<>]+>';
 22      const FUNCTION_TYPE_RE = '(?!struct)('
 23        + DECLTYPE_AUTO_RE + '|'
 24        + regex.optional(NAMESPACE_RE)
 25        + '[a-zA-Z_]\\w*' + regex.optional(TEMPLATE_ARGUMENT_RE)
 26      + ')';
 27  
 28      const CPP_PRIMITIVE_TYPES = {
 29        className: 'type',
 30        begin: '\\b[a-z\\d_]*_t\\b'
 31      };
 32  
 33      // https://en.cppreference.com/w/cpp/language/escape
 34      // \\ \x \xFF \u2837 \u00323747 \374
 35      const CHARACTER_ESCAPES = '\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)';
 36      const STRINGS = {
 37        className: 'string',
 38        variants: [
 39          {
 40            begin: '(u8?|U|L)?"',
 41            end: '"',
 42            illegal: '\\n',
 43            contains: [ hljs.BACKSLASH_ESCAPE ]
 44          },
 45          {
 46            begin: '(u8?|U|L)?\'(' + CHARACTER_ESCAPES + '|.)',
 47            end: '\'',
 48            illegal: '.'
 49          },
 50          hljs.END_SAME_AS_BEGIN({
 51            begin: /(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,
 52            end: /\)([^()\\ ]{0,16})"/
 53          })
 54        ]
 55      };
 56  
 57      const NUMBERS = {
 58        className: 'number',
 59        variants: [
 60          // Floating-point literal.
 61          { begin:
 62            "[+-]?(?:" // Leading sign.
 63              // Decimal.
 64              + "(?:"
 65                +"[0-9](?:'?[0-9])*\\.(?:[0-9](?:'?[0-9])*)?"
 66                + "|\\.[0-9](?:'?[0-9])*"
 67              + ")(?:[Ee][+-]?[0-9](?:'?[0-9])*)?"
 68              + "|[0-9](?:'?[0-9])*[Ee][+-]?[0-9](?:'?[0-9])*"
 69              // Hexadecimal.
 70              + "|0[Xx](?:"
 71                +"[0-9A-Fa-f](?:'?[0-9A-Fa-f])*(?:\\.(?:[0-9A-Fa-f](?:'?[0-9A-Fa-f])*)?)?"
 72                + "|\\.[0-9A-Fa-f](?:'?[0-9A-Fa-f])*"
 73              + ")[Pp][+-]?[0-9](?:'?[0-9])*"
 74            + ")(?:" // Literal suffixes.
 75              + "[Ff](?:16|32|64|128)?"
 76              + "|(BF|bf)16"
 77              + "|[Ll]"
 78              + "|" // Literal suffix is optional.
 79            + ")"
 80          },
 81          // Integer literal.
 82          { begin:
 83            "[+-]?\\b(?:" // Leading sign.
 84              + "0[Bb][01](?:'?[01])*" // Binary.
 85              + "|0[Xx][0-9A-Fa-f](?:'?[0-9A-Fa-f])*" // Hexadecimal.
 86              + "|0(?:'?[0-7])*" // Octal or just a lone zero.
 87              + "|[1-9](?:'?[0-9])*" // Decimal.
 88            + ")(?:" // Literal suffixes.
 89              + "[Uu](?:LL?|ll?)"
 90              + "|[Uu][Zz]?"
 91              + "|(?:LL?|ll?)[Uu]?"
 92              + "|[Zz][Uu]"
 93              + "|" // Literal suffix is optional.
 94            + ")"
 95            // Note: there are user-defined literal suffixes too, but perhaps having the custom suffix not part of the
 96            // literal highlight actually makes it stand out more.
 97          }
 98        ],
 99        relevance: 0
100      };
101  
102      const PREPROCESSOR = {
103        className: 'meta',
104        begin: /#\s*[a-z]+\b/,
105        end: /$/,
106        keywords: { keyword:
107            'if else elif endif define undef warning error line '
108            + 'pragma _Pragma ifdef ifndef include' },
109        contains: [
110          {
111            begin: /\\\n/,
112            relevance: 0
113          },
114          hljs.inherit(STRINGS, { className: 'string' }),
115          {
116            className: 'string',
117            begin: /<.*?>/
118          },
119          C_LINE_COMMENT_MODE,
120          hljs.C_BLOCK_COMMENT_MODE
121        ]
122      };
123  
124      const TITLE_MODE = {
125        className: 'title',
126        begin: regex.optional(NAMESPACE_RE) + hljs.IDENT_RE,
127        relevance: 0
128      };
129  
130      const FUNCTION_TITLE = regex.optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\s*\\(';
131  
132      // https://en.cppreference.com/w/cpp/keyword
133      const RESERVED_KEYWORDS = [
134        'alignas',
135        'alignof',
136        'and',
137        'and_eq',
138        'asm',
139        'atomic_cancel',
140        'atomic_commit',
141        'atomic_noexcept',
142        'auto',
143        'bitand',
144        'bitor',
145        'break',
146        'case',
147        'catch',
148        'class',
149        'co_await',
150        'co_return',
151        'co_yield',
152        'compl',
153        'concept',
154        'const_cast|10',
155        'consteval',
156        'constexpr',
157        'constinit',
158        'continue',
159        'decltype',
160        'default',
161        'delete',
162        'do',
163        'dynamic_cast|10',
164        'else',
165        'enum',
166        'explicit',
167        'export',
168        'extern',
169        'false',
170        'final',
171        'for',
172        'friend',
173        'goto',
174        'if',
175        'import',
176        'inline',
177        'module',
178        'mutable',
179        'namespace',
180        'new',
181        'noexcept',
182        'not',
183        'not_eq',
184        'nullptr',
185        'operator',
186        'or',
187        'or_eq',
188        'override',
189        'private',
190        'protected',
191        'public',
192        'reflexpr',
193        'register',
194        'reinterpret_cast|10',
195        'requires',
196        'return',
197        'sizeof',
198        'static_assert',
199        'static_cast|10',
200        'struct',
201        'switch',
202        'synchronized',
203        'template',
204        'this',
205        'thread_local',
206        'throw',
207        'transaction_safe',
208        'transaction_safe_dynamic',
209        'true',
210        'try',
211        'typedef',
212        'typeid',
213        'typename',
214        'union',
215        'using',
216        'virtual',
217        'volatile',
218        'while',
219        'xor',
220        'xor_eq'
221      ];
222  
223      // https://en.cppreference.com/w/cpp/keyword
224      const RESERVED_TYPES = [
225        'bool',
226        'char',
227        'char16_t',
228        'char32_t',
229        'char8_t',
230        'double',
231        'float',
232        'int',
233        'long',
234        'short',
235        'void',
236        'wchar_t',
237        'unsigned',
238        'signed',
239        'const',
240        'static'
241      ];
242  
243      const TYPE_HINTS = [
244        'any',
245        'auto_ptr',
246        'barrier',
247        'binary_semaphore',
248        'bitset',
249        'complex',
250        'condition_variable',
251        'condition_variable_any',
252        'counting_semaphore',
253        'deque',
254        'false_type',
255        'future',
256        'imaginary',
257        'initializer_list',
258        'istringstream',
259        'jthread',
260        'latch',
261        'lock_guard',
262        'multimap',
263        'multiset',
264        'mutex',
265        'optional',
266        'ostringstream',
267        'packaged_task',
268        'pair',
269        'promise',
270        'priority_queue',
271        'queue',
272        'recursive_mutex',
273        'recursive_timed_mutex',
274        'scoped_lock',
275        'set',
276        'shared_future',
277        'shared_lock',
278        'shared_mutex',
279        'shared_timed_mutex',
280        'shared_ptr',
281        'stack',
282        'string_view',
283        'stringstream',
284        'timed_mutex',
285        'thread',
286        'true_type',
287        'tuple',
288        'unique_lock',
289        'unique_ptr',
290        'unordered_map',
291        'unordered_multimap',
292        'unordered_multiset',
293        'unordered_set',
294        'variant',
295        'vector',
296        'weak_ptr',
297        'wstring',
298        'wstring_view'
299      ];
300  
301      const FUNCTION_HINTS = [
302        'abort',
303        'abs',
304        'acos',
305        'apply',
306        'as_const',
307        'asin',
308        'atan',
309        'atan2',
310        'calloc',
311        'ceil',
312        'cerr',
313        'cin',
314        'clog',
315        'cos',
316        'cosh',
317        'cout',
318        'declval',
319        'endl',
320        'exchange',
321        'exit',
322        'exp',
323        'fabs',
324        'floor',
325        'fmod',
326        'forward',
327        'fprintf',
328        'fputs',
329        'free',
330        'frexp',
331        'fscanf',
332        'future',
333        'invoke',
334        'isalnum',
335        'isalpha',
336        'iscntrl',
337        'isdigit',
338        'isgraph',
339        'islower',
340        'isprint',
341        'ispunct',
342        'isspace',
343        'isupper',
344        'isxdigit',
345        'labs',
346        'launder',
347        'ldexp',
348        'log',
349        'log10',
350        'make_pair',
351        'make_shared',
352        'make_shared_for_overwrite',
353        'make_tuple',
354        'make_unique',
355        'malloc',
356        'memchr',
357        'memcmp',
358        'memcpy',
359        'memset',
360        'modf',
361        'move',
362        'pow',
363        'printf',
364        'putchar',
365        'puts',
366        'realloc',
367        'scanf',
368        'sin',
369        'sinh',
370        'snprintf',
371        'sprintf',
372        'sqrt',
373        'sscanf',
374        'std',
375        'stderr',
376        'stdin',
377        'stdout',
378        'strcat',
379        'strchr',
380        'strcmp',
381        'strcpy',
382        'strcspn',
383        'strlen',
384        'strncat',
385        'strncmp',
386        'strncpy',
387        'strpbrk',
388        'strrchr',
389        'strspn',
390        'strstr',
391        'swap',
392        'tan',
393        'tanh',
394        'terminate',
395        'to_underlying',
396        'tolower',
397        'toupper',
398        'vfprintf',
399        'visit',
400        'vprintf',
401        'vsprintf'
402      ];
403  
404      const LITERALS = [
405        'NULL',
406        'false',
407        'nullopt',
408        'nullptr',
409        'true'
410      ];
411  
412      // https://en.cppreference.com/w/cpp/keyword
413      const BUILT_IN = [ '_Pragma' ];
414  
415      const CPP_KEYWORDS = {
416        type: RESERVED_TYPES,
417        keyword: RESERVED_KEYWORDS,
418        literal: LITERALS,
419        built_in: BUILT_IN,
420        _type_hints: TYPE_HINTS
421      };
422  
423      const FUNCTION_DISPATCH = {
424        className: 'function.dispatch',
425        relevance: 0,
426        keywords: {
427          // Only for relevance, not highlighting.
428          _hint: FUNCTION_HINTS },
429        begin: regex.concat(
430          /\b/,
431          /(?!decltype)/,
432          /(?!if)/,
433          /(?!for)/,
434          /(?!switch)/,
435          /(?!while)/,
436          hljs.IDENT_RE,
437          regex.lookahead(/(<[^<>]+>|)\s*\(/))
438      };
439  
440      const EXPRESSION_CONTAINS = [
441        FUNCTION_DISPATCH,
442        PREPROCESSOR,
443        CPP_PRIMITIVE_TYPES,
444        C_LINE_COMMENT_MODE,
445        hljs.C_BLOCK_COMMENT_MODE,
446        NUMBERS,
447        STRINGS
448      ];
449  
450      const EXPRESSION_CONTEXT = {
451        // This mode covers expression context where we can't expect a function
452        // definition and shouldn't highlight anything that looks like one:
453        // `return some()`, `else if()`, `(x*sum(1, 2))`
454        variants: [
455          {
456            begin: /=/,
457            end: /;/
458          },
459          {
460            begin: /\(/,
461            end: /\)/
462          },
463          {
464            beginKeywords: 'new throw return else',
465            end: /;/
466          }
467        ],
468        keywords: CPP_KEYWORDS,
469        contains: EXPRESSION_CONTAINS.concat([
470          {
471            begin: /\(/,
472            end: /\)/,
473            keywords: CPP_KEYWORDS,
474            contains: EXPRESSION_CONTAINS.concat([ 'self' ]),
475            relevance: 0
476          }
477        ]),
478        relevance: 0
479      };
480  
481      const FUNCTION_DECLARATION = {
482        className: 'function',
483        begin: '(' + FUNCTION_TYPE_RE + '[\\*&\\s]+)+' + FUNCTION_TITLE,
484        returnBegin: true,
485        end: /[{;=]/,
486        excludeEnd: true,
487        keywords: CPP_KEYWORDS,
488        illegal: /[^\w\s\*&:<>.]/,
489        contains: [
490          { // to prevent it from being confused as the function title
491            begin: DECLTYPE_AUTO_RE,
492            keywords: CPP_KEYWORDS,
493            relevance: 0
494          },
495          {
496            begin: FUNCTION_TITLE,
497            returnBegin: true,
498            contains: [ TITLE_MODE ],
499            relevance: 0
500          },
501          // needed because we do not have look-behind on the below rule
502          // to prevent it from grabbing the final : in a :: pair
503          {
504            begin: /::/,
505            relevance: 0
506          },
507          // initializers
508          {
509            begin: /:/,
510            endsWithParent: true,
511            contains: [
512              STRINGS,
513              NUMBERS
514            ]
515          },
516          // allow for multiple declarations, e.g.:
517          // extern void f(int), g(char);
518          {
519            relevance: 0,
520            match: /,/
521          },
522          {
523            className: 'params',
524            begin: /\(/,
525            end: /\)/,
526            keywords: CPP_KEYWORDS,
527            relevance: 0,
528            contains: [
529              C_LINE_COMMENT_MODE,
530              hljs.C_BLOCK_COMMENT_MODE,
531              STRINGS,
532              NUMBERS,
533              CPP_PRIMITIVE_TYPES,
534              // Count matching parentheses.
535              {
536                begin: /\(/,
537                end: /\)/,
538                keywords: CPP_KEYWORDS,
539                relevance: 0,
540                contains: [
541                  'self',
542                  C_LINE_COMMENT_MODE,
543                  hljs.C_BLOCK_COMMENT_MODE,
544                  STRINGS,
545                  NUMBERS,
546                  CPP_PRIMITIVE_TYPES
547                ]
548              }
549            ]
550          },
551          CPP_PRIMITIVE_TYPES,
552          C_LINE_COMMENT_MODE,
553          hljs.C_BLOCK_COMMENT_MODE,
554          PREPROCESSOR
555        ]
556      };
557  
558      return {
559        name: 'C++',
560        aliases: [
561          'cc',
562          'c++',
563          'h++',
564          'hpp',
565          'hh',
566          'hxx',
567          'cxx'
568        ],
569        keywords: CPP_KEYWORDS,
570        illegal: '</',
571        classNameAliases: { 'function.dispatch': 'built_in' },
572        contains: [].concat(
573          EXPRESSION_CONTEXT,
574          FUNCTION_DECLARATION,
575          FUNCTION_DISPATCH,
576          EXPRESSION_CONTAINS,
577          [
578            PREPROCESSOR,
579            { // containers: ie, `vector <int> rooms (9);`
580              begin: '\\b(deque|list|queue|priority_queue|pair|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array|tuple|optional|variant|function)\\s*<(?!<)',
581              end: '>',
582              keywords: CPP_KEYWORDS,
583              contains: [
584                'self',
585                CPP_PRIMITIVE_TYPES
586              ]
587            },
588            {
589              begin: hljs.IDENT_RE + '::',
590              keywords: CPP_KEYWORDS
591            },
592            {
593              match: [
594                // extra complexity to deal with `enum class` and `enum struct`
595                /\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/,
596                /\s+/,
597                /\w+/
598              ],
599              className: {
600                1: 'keyword',
601                3: 'title.class'
602              }
603            }
604          ])
605      };
606    }
607  
608    return cpp;
609  
610  })();
611  
612      hljs.registerLanguage('cpp', hljsGrammar);
613    })();