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 })();