cpp.js 12 KB

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