Mercurial
comparison third_party/highlight/languages/cpp.js @ 157:2db6253f355d
[ThirdParty] Added highlight library for better readability on blog.
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Tue, 13 Jan 2026 19:18:47 -0800 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 156:cd35e600ae34 | 157:2db6253f355d |
|---|---|
| 1 /*! `cpp` grammar compiled for Highlight.js 11.11.1 */ | |
| 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 'flat_map', | |
| 256 'flat_set', | |
| 257 'future', | |
| 258 'imaginary', | |
| 259 'initializer_list', | |
| 260 'istringstream', | |
| 261 'jthread', | |
| 262 'latch', | |
| 263 'lock_guard', | |
| 264 'multimap', | |
| 265 'multiset', | |
| 266 'mutex', | |
| 267 'optional', | |
| 268 'ostringstream', | |
| 269 'packaged_task', | |
| 270 'pair', | |
| 271 'promise', | |
| 272 'priority_queue', | |
| 273 'queue', | |
| 274 'recursive_mutex', | |
| 275 'recursive_timed_mutex', | |
| 276 'scoped_lock', | |
| 277 'set', | |
| 278 'shared_future', | |
| 279 'shared_lock', | |
| 280 'shared_mutex', | |
| 281 'shared_timed_mutex', | |
| 282 'shared_ptr', | |
| 283 'stack', | |
| 284 'string_view', | |
| 285 'stringstream', | |
| 286 'timed_mutex', | |
| 287 'thread', | |
| 288 'true_type', | |
| 289 'tuple', | |
| 290 'unique_lock', | |
| 291 'unique_ptr', | |
| 292 'unordered_map', | |
| 293 'unordered_multimap', | |
| 294 'unordered_multiset', | |
| 295 'unordered_set', | |
| 296 'variant', | |
| 297 'vector', | |
| 298 'weak_ptr', | |
| 299 'wstring', | |
| 300 'wstring_view' | |
| 301 ]; | |
| 302 | |
| 303 const FUNCTION_HINTS = [ | |
| 304 'abort', | |
| 305 'abs', | |
| 306 'acos', | |
| 307 'apply', | |
| 308 'as_const', | |
| 309 'asin', | |
| 310 'atan', | |
| 311 'atan2', | |
| 312 'calloc', | |
| 313 'ceil', | |
| 314 'cerr', | |
| 315 'cin', | |
| 316 'clog', | |
| 317 'cos', | |
| 318 'cosh', | |
| 319 'cout', | |
| 320 'declval', | |
| 321 'endl', | |
| 322 'exchange', | |
| 323 'exit', | |
| 324 'exp', | |
| 325 'fabs', | |
| 326 'floor', | |
| 327 'fmod', | |
| 328 'forward', | |
| 329 'fprintf', | |
| 330 'fputs', | |
| 331 'free', | |
| 332 'frexp', | |
| 333 'fscanf', | |
| 334 'future', | |
| 335 'invoke', | |
| 336 'isalnum', | |
| 337 'isalpha', | |
| 338 'iscntrl', | |
| 339 'isdigit', | |
| 340 'isgraph', | |
| 341 'islower', | |
| 342 'isprint', | |
| 343 'ispunct', | |
| 344 'isspace', | |
| 345 'isupper', | |
| 346 'isxdigit', | |
| 347 'labs', | |
| 348 'launder', | |
| 349 'ldexp', | |
| 350 'log', | |
| 351 'log10', | |
| 352 'make_pair', | |
| 353 'make_shared', | |
| 354 'make_shared_for_overwrite', | |
| 355 'make_tuple', | |
| 356 'make_unique', | |
| 357 'malloc', | |
| 358 'memchr', | |
| 359 'memcmp', | |
| 360 'memcpy', | |
| 361 'memset', | |
| 362 'modf', | |
| 363 'move', | |
| 364 'pow', | |
| 365 'printf', | |
| 366 'putchar', | |
| 367 'puts', | |
| 368 'realloc', | |
| 369 'scanf', | |
| 370 'sin', | |
| 371 'sinh', | |
| 372 'snprintf', | |
| 373 'sprintf', | |
| 374 'sqrt', | |
| 375 'sscanf', | |
| 376 'std', | |
| 377 'stderr', | |
| 378 'stdin', | |
| 379 'stdout', | |
| 380 'strcat', | |
| 381 'strchr', | |
| 382 'strcmp', | |
| 383 'strcpy', | |
| 384 'strcspn', | |
| 385 'strlen', | |
| 386 'strncat', | |
| 387 'strncmp', | |
| 388 'strncpy', | |
| 389 'strpbrk', | |
| 390 'strrchr', | |
| 391 'strspn', | |
| 392 'strstr', | |
| 393 'swap', | |
| 394 'tan', | |
| 395 'tanh', | |
| 396 'terminate', | |
| 397 'to_underlying', | |
| 398 'tolower', | |
| 399 'toupper', | |
| 400 'vfprintf', | |
| 401 'visit', | |
| 402 'vprintf', | |
| 403 'vsprintf' | |
| 404 ]; | |
| 405 | |
| 406 const LITERALS = [ | |
| 407 'NULL', | |
| 408 'false', | |
| 409 'nullopt', | |
| 410 'nullptr', | |
| 411 'true' | |
| 412 ]; | |
| 413 | |
| 414 // https://en.cppreference.com/w/cpp/keyword | |
| 415 const BUILT_IN = [ '_Pragma' ]; | |
| 416 | |
| 417 const CPP_KEYWORDS = { | |
| 418 type: RESERVED_TYPES, | |
| 419 keyword: RESERVED_KEYWORDS, | |
| 420 literal: LITERALS, | |
| 421 built_in: BUILT_IN, | |
| 422 _type_hints: TYPE_HINTS | |
| 423 }; | |
| 424 | |
| 425 const FUNCTION_DISPATCH = { | |
| 426 className: 'function.dispatch', | |
| 427 relevance: 0, | |
| 428 keywords: { | |
| 429 // Only for relevance, not highlighting. | |
| 430 _hint: FUNCTION_HINTS }, | |
| 431 begin: regex.concat( | |
| 432 /\b/, | |
| 433 /(?!decltype)/, | |
| 434 /(?!if)/, | |
| 435 /(?!for)/, | |
| 436 /(?!switch)/, | |
| 437 /(?!while)/, | |
| 438 hljs.IDENT_RE, | |
| 439 regex.lookahead(/(<[^<>]+>|)\s*\(/)) | |
| 440 }; | |
| 441 | |
| 442 const EXPRESSION_CONTAINS = [ | |
| 443 FUNCTION_DISPATCH, | |
| 444 PREPROCESSOR, | |
| 445 CPP_PRIMITIVE_TYPES, | |
| 446 C_LINE_COMMENT_MODE, | |
| 447 hljs.C_BLOCK_COMMENT_MODE, | |
| 448 NUMBERS, | |
| 449 STRINGS | |
| 450 ]; | |
| 451 | |
| 452 const EXPRESSION_CONTEXT = { | |
| 453 // This mode covers expression context where we can't expect a function | |
| 454 // definition and shouldn't highlight anything that looks like one: | |
| 455 // `return some()`, `else if()`, `(x*sum(1, 2))` | |
| 456 variants: [ | |
| 457 { | |
| 458 begin: /=/, | |
| 459 end: /;/ | |
| 460 }, | |
| 461 { | |
| 462 begin: /\(/, | |
| 463 end: /\)/ | |
| 464 }, | |
| 465 { | |
| 466 beginKeywords: 'new throw return else', | |
| 467 end: /;/ | |
| 468 } | |
| 469 ], | |
| 470 keywords: CPP_KEYWORDS, | |
| 471 contains: EXPRESSION_CONTAINS.concat([ | |
| 472 { | |
| 473 begin: /\(/, | |
| 474 end: /\)/, | |
| 475 keywords: CPP_KEYWORDS, | |
| 476 contains: EXPRESSION_CONTAINS.concat([ 'self' ]), | |
| 477 relevance: 0 | |
| 478 } | |
| 479 ]), | |
| 480 relevance: 0 | |
| 481 }; | |
| 482 | |
| 483 const FUNCTION_DECLARATION = { | |
| 484 className: 'function', | |
| 485 begin: '(' + FUNCTION_TYPE_RE + '[\\*&\\s]+)+' + FUNCTION_TITLE, | |
| 486 returnBegin: true, | |
| 487 end: /[{;=]/, | |
| 488 excludeEnd: true, | |
| 489 keywords: CPP_KEYWORDS, | |
| 490 illegal: /[^\w\s\*&:<>.]/, | |
| 491 contains: [ | |
| 492 { // to prevent it from being confused as the function title | |
| 493 begin: DECLTYPE_AUTO_RE, | |
| 494 keywords: CPP_KEYWORDS, | |
| 495 relevance: 0 | |
| 496 }, | |
| 497 { | |
| 498 begin: FUNCTION_TITLE, | |
| 499 returnBegin: true, | |
| 500 contains: [ TITLE_MODE ], | |
| 501 relevance: 0 | |
| 502 }, | |
| 503 // needed because we do not have look-behind on the below rule | |
| 504 // to prevent it from grabbing the final : in a :: pair | |
| 505 { | |
| 506 begin: /::/, | |
| 507 relevance: 0 | |
| 508 }, | |
| 509 // initializers | |
| 510 { | |
| 511 begin: /:/, | |
| 512 endsWithParent: true, | |
| 513 contains: [ | |
| 514 STRINGS, | |
| 515 NUMBERS | |
| 516 ] | |
| 517 }, | |
| 518 // allow for multiple declarations, e.g.: | |
| 519 // extern void f(int), g(char); | |
| 520 { | |
| 521 relevance: 0, | |
| 522 match: /,/ | |
| 523 }, | |
| 524 { | |
| 525 className: 'params', | |
| 526 begin: /\(/, | |
| 527 end: /\)/, | |
| 528 keywords: CPP_KEYWORDS, | |
| 529 relevance: 0, | |
| 530 contains: [ | |
| 531 C_LINE_COMMENT_MODE, | |
| 532 hljs.C_BLOCK_COMMENT_MODE, | |
| 533 STRINGS, | |
| 534 NUMBERS, | |
| 535 CPP_PRIMITIVE_TYPES, | |
| 536 // Count matching parentheses. | |
| 537 { | |
| 538 begin: /\(/, | |
| 539 end: /\)/, | |
| 540 keywords: CPP_KEYWORDS, | |
| 541 relevance: 0, | |
| 542 contains: [ | |
| 543 'self', | |
| 544 C_LINE_COMMENT_MODE, | |
| 545 hljs.C_BLOCK_COMMENT_MODE, | |
| 546 STRINGS, | |
| 547 NUMBERS, | |
| 548 CPP_PRIMITIVE_TYPES | |
| 549 ] | |
| 550 } | |
| 551 ] | |
| 552 }, | |
| 553 CPP_PRIMITIVE_TYPES, | |
| 554 C_LINE_COMMENT_MODE, | |
| 555 hljs.C_BLOCK_COMMENT_MODE, | |
| 556 PREPROCESSOR | |
| 557 ] | |
| 558 }; | |
| 559 | |
| 560 return { | |
| 561 name: 'C++', | |
| 562 aliases: [ | |
| 563 'cc', | |
| 564 'c++', | |
| 565 'h++', | |
| 566 'hpp', | |
| 567 'hh', | |
| 568 'hxx', | |
| 569 'cxx' | |
| 570 ], | |
| 571 keywords: CPP_KEYWORDS, | |
| 572 illegal: '</', | |
| 573 classNameAliases: { 'function.dispatch': 'built_in' }, | |
| 574 contains: [].concat( | |
| 575 EXPRESSION_CONTEXT, | |
| 576 FUNCTION_DECLARATION, | |
| 577 FUNCTION_DISPATCH, | |
| 578 EXPRESSION_CONTAINS, | |
| 579 [ | |
| 580 PREPROCESSOR, | |
| 581 { // containers: ie, `vector <int> rooms (9);` | |
| 582 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|flat_map|flat_set)\\s*<(?!<)', | |
| 583 end: '>', | |
| 584 keywords: CPP_KEYWORDS, | |
| 585 contains: [ | |
| 586 'self', | |
| 587 CPP_PRIMITIVE_TYPES | |
| 588 ] | |
| 589 }, | |
| 590 { | |
| 591 begin: hljs.IDENT_RE + '::', | |
| 592 keywords: CPP_KEYWORDS | |
| 593 }, | |
| 594 { | |
| 595 match: [ | |
| 596 // extra complexity to deal with `enum class` and `enum struct` | |
| 597 /\b(?:enum(?:\s+(?:class|struct))?|class|struct|union)/, | |
| 598 /\s+/, | |
| 599 /\w+/ | |
| 600 ], | |
| 601 className: { | |
| 602 1: 'keyword', | |
| 603 3: 'title.class' | |
| 604 } | |
| 605 } | |
| 606 ]) | |
| 607 }; | |
| 608 } | |
| 609 | |
| 610 return cpp; | |
| 611 | |
| 612 })(); | |
| 613 | |
| 614 hljs.registerLanguage('cpp', hljsGrammar); | |
| 615 })(); |