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