source: node_modules/highlight.js/lib/languages/cpp.js@ d24f17c

main
Last change on this file since d24f17c was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 10.0 KB
Line 
1/**
2 * @param {string} value
3 * @returns {RegExp}
4 * */
5
6/**
7 * @param {RegExp | string } re
8 * @returns {string}
9 */
10function source(re) {
11 if (!re) return null;
12 if (typeof re === "string") return re;
13
14 return re.source;
15}
16
17/**
18 * @param {RegExp | string } re
19 * @returns {string}
20 */
21function lookahead(re) {
22 return concat('(?=', re, ')');
23}
24
25/**
26 * @param {RegExp | string } re
27 * @returns {string}
28 */
29function optional(re) {
30 return concat('(', re, ')?');
31}
32
33/**
34 * @param {...(RegExp | string) } args
35 * @returns {string}
36 */
37function concat(...args) {
38 const joined = args.map((x) => source(x)).join("");
39 return joined;
40}
41
42/*
43Language: C++
44Category: common, system
45Website: https://isocpp.org
46*/
47
48/** @type LanguageFn */
49function cpp(hljs) {
50 // added for historic reasons because `hljs.C_LINE_COMMENT_MODE` does
51 // not include such support nor can we be sure all the grammars depending
52 // on it would desire this behavior
53 const C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$', {
54 contains: [
55 {
56 begin: /\\\n/
57 }
58 ]
59 });
60 const DECLTYPE_AUTO_RE = 'decltype\\(auto\\)';
61 const NAMESPACE_RE = '[a-zA-Z_]\\w*::';
62 const TEMPLATE_ARGUMENT_RE = '<[^<>]+>';
63 const FUNCTION_TYPE_RE = '(' +
64 DECLTYPE_AUTO_RE + '|' +
65 optional(NAMESPACE_RE) +
66 '[a-zA-Z_]\\w*' + optional(TEMPLATE_ARGUMENT_RE) +
67 ')';
68 const CPP_PRIMITIVE_TYPES = {
69 className: 'keyword',
70 begin: '\\b[a-z\\d_]*_t\\b'
71 };
72
73 // https://en.cppreference.com/w/cpp/language/escape
74 // \\ \x \xFF \u2837 \u00323747 \374
75 const CHARACTER_ESCAPES = '\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)';
76 const STRINGS = {
77 className: 'string',
78 variants: [
79 {
80 begin: '(u8?|U|L)?"',
81 end: '"',
82 illegal: '\\n',
83 contains: [ hljs.BACKSLASH_ESCAPE ]
84 },
85 {
86 begin: '(u8?|U|L)?\'(' + CHARACTER_ESCAPES + "|.)",
87 end: '\'',
88 illegal: '.'
89 },
90 hljs.END_SAME_AS_BEGIN({
91 begin: /(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,
92 end: /\)([^()\\ ]{0,16})"/
93 })
94 ]
95 };
96
97 const NUMBERS = {
98 className: 'number',
99 variants: [
100 {
101 begin: '\\b(0b[01\']+)'
102 },
103 {
104 begin: '(-?)\\b([\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)'
105 },
106 {
107 begin: '(-?)(\\b0[xX][a-fA-F0-9\']+|(\\b[\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)([eE][-+]?[\\d\']+)?)'
108 }
109 ],
110 relevance: 0
111 };
112
113 const PREPROCESSOR = {
114 className: 'meta',
115 begin: /#\s*[a-z]+\b/,
116 end: /$/,
117 keywords: {
118 'meta-keyword':
119 'if else elif endif define undef warning error line ' +
120 'pragma _Pragma ifdef ifndef include'
121 },
122 contains: [
123 {
124 begin: /\\\n/,
125 relevance: 0
126 },
127 hljs.inherit(STRINGS, {
128 className: 'meta-string'
129 }),
130 {
131 className: 'meta-string',
132 begin: /<.*?>/
133 },
134 C_LINE_COMMENT_MODE,
135 hljs.C_BLOCK_COMMENT_MODE
136 ]
137 };
138
139 const TITLE_MODE = {
140 className: 'title',
141 begin: optional(NAMESPACE_RE) + hljs.IDENT_RE,
142 relevance: 0
143 };
144
145 const FUNCTION_TITLE = optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\s*\\(';
146
147 const COMMON_CPP_HINTS = [
148 'asin',
149 'atan2',
150 'atan',
151 'calloc',
152 'ceil',
153 'cosh',
154 'cos',
155 'exit',
156 'exp',
157 'fabs',
158 'floor',
159 'fmod',
160 'fprintf',
161 'fputs',
162 'free',
163 'frexp',
164 'auto_ptr',
165 'deque',
166 'list',
167 'queue',
168 'stack',
169 'vector',
170 'map',
171 'set',
172 'pair',
173 'bitset',
174 'multiset',
175 'multimap',
176 'unordered_set',
177 'fscanf',
178 'future',
179 'isalnum',
180 'isalpha',
181 'iscntrl',
182 'isdigit',
183 'isgraph',
184 'islower',
185 'isprint',
186 'ispunct',
187 'isspace',
188 'isupper',
189 'isxdigit',
190 'tolower',
191 'toupper',
192 'labs',
193 'ldexp',
194 'log10',
195 'log',
196 'malloc',
197 'realloc',
198 'memchr',
199 'memcmp',
200 'memcpy',
201 'memset',
202 'modf',
203 'pow',
204 'printf',
205 'putchar',
206 'puts',
207 'scanf',
208 'sinh',
209 'sin',
210 'snprintf',
211 'sprintf',
212 'sqrt',
213 'sscanf',
214 'strcat',
215 'strchr',
216 'strcmp',
217 'strcpy',
218 'strcspn',
219 'strlen',
220 'strncat',
221 'strncmp',
222 'strncpy',
223 'strpbrk',
224 'strrchr',
225 'strspn',
226 'strstr',
227 'tanh',
228 'tan',
229 'unordered_map',
230 'unordered_multiset',
231 'unordered_multimap',
232 'priority_queue',
233 'make_pair',
234 'array',
235 'shared_ptr',
236 'abort',
237 'terminate',
238 'abs',
239 'acos',
240 'vfprintf',
241 'vprintf',
242 'vsprintf',
243 'endl',
244 'initializer_list',
245 'unique_ptr',
246 'complex',
247 'imaginary',
248 'std',
249 'string',
250 'wstring',
251 'cin',
252 'cout',
253 'cerr',
254 'clog',
255 'stdin',
256 'stdout',
257 'stderr',
258 'stringstream',
259 'istringstream',
260 'ostringstream'
261 ];
262
263 const CPP_KEYWORDS = {
264 keyword: 'int float while private char char8_t char16_t char32_t catch import module export virtual operator sizeof ' +
265 'dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace ' +
266 'unsigned long volatile static protected bool template mutable if public friend ' +
267 'do goto auto void enum else break extern using asm case typeid wchar_t ' +
268 'short reinterpret_cast|10 default double register explicit signed typename try this ' +
269 'switch continue inline delete alignas alignof constexpr consteval constinit decltype ' +
270 'concept co_await co_return co_yield requires ' +
271 'noexcept static_assert thread_local restrict final override ' +
272 'atomic_bool atomic_char atomic_schar ' +
273 'atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong ' +
274 'atomic_ullong new throw return ' +
275 'and and_eq bitand bitor compl not not_eq or or_eq xor xor_eq',
276 built_in: '_Bool _Complex _Imaginary',
277 _relevance_hints: COMMON_CPP_HINTS,
278 literal: 'true false nullptr NULL'
279 };
280
281 const FUNCTION_DISPATCH = {
282 className: "function.dispatch",
283 relevance: 0,
284 keywords: CPP_KEYWORDS,
285 begin: concat(
286 /\b/,
287 /(?!decltype)/,
288 /(?!if)/,
289 /(?!for)/,
290 /(?!while)/,
291 hljs.IDENT_RE,
292 lookahead(/\s*\(/))
293 };
294
295 const EXPRESSION_CONTAINS = [
296 FUNCTION_DISPATCH,
297 PREPROCESSOR,
298 CPP_PRIMITIVE_TYPES,
299 C_LINE_COMMENT_MODE,
300 hljs.C_BLOCK_COMMENT_MODE,
301 NUMBERS,
302 STRINGS
303 ];
304
305
306 const EXPRESSION_CONTEXT = {
307 // This mode covers expression context where we can't expect a function
308 // definition and shouldn't highlight anything that looks like one:
309 // `return some()`, `else if()`, `(x*sum(1, 2))`
310 variants: [
311 {
312 begin: /=/,
313 end: /;/
314 },
315 {
316 begin: /\(/,
317 end: /\)/
318 },
319 {
320 beginKeywords: 'new throw return else',
321 end: /;/
322 }
323 ],
324 keywords: CPP_KEYWORDS,
325 contains: EXPRESSION_CONTAINS.concat([
326 {
327 begin: /\(/,
328 end: /\)/,
329 keywords: CPP_KEYWORDS,
330 contains: EXPRESSION_CONTAINS.concat([ 'self' ]),
331 relevance: 0
332 }
333 ]),
334 relevance: 0
335 };
336
337 const FUNCTION_DECLARATION = {
338 className: 'function',
339 begin: '(' + FUNCTION_TYPE_RE + '[\\*&\\s]+)+' + FUNCTION_TITLE,
340 returnBegin: true,
341 end: /[{;=]/,
342 excludeEnd: true,
343 keywords: CPP_KEYWORDS,
344 illegal: /[^\w\s\*&:<>.]/,
345 contains: [
346 { // to prevent it from being confused as the function title
347 begin: DECLTYPE_AUTO_RE,
348 keywords: CPP_KEYWORDS,
349 relevance: 0
350 },
351 {
352 begin: FUNCTION_TITLE,
353 returnBegin: true,
354 contains: [ TITLE_MODE ],
355 relevance: 0
356 },
357 // needed because we do not have look-behind on the below rule
358 // to prevent it from grabbing the final : in a :: pair
359 {
360 begin: /::/,
361 relevance: 0
362 },
363 // initializers
364 {
365 begin: /:/,
366 endsWithParent: true,
367 contains: [
368 STRINGS,
369 NUMBERS
370 ]
371 },
372 {
373 className: 'params',
374 begin: /\(/,
375 end: /\)/,
376 keywords: CPP_KEYWORDS,
377 relevance: 0,
378 contains: [
379 C_LINE_COMMENT_MODE,
380 hljs.C_BLOCK_COMMENT_MODE,
381 STRINGS,
382 NUMBERS,
383 CPP_PRIMITIVE_TYPES,
384 // Count matching parentheses.
385 {
386 begin: /\(/,
387 end: /\)/,
388 keywords: CPP_KEYWORDS,
389 relevance: 0,
390 contains: [
391 'self',
392 C_LINE_COMMENT_MODE,
393 hljs.C_BLOCK_COMMENT_MODE,
394 STRINGS,
395 NUMBERS,
396 CPP_PRIMITIVE_TYPES
397 ]
398 }
399 ]
400 },
401 CPP_PRIMITIVE_TYPES,
402 C_LINE_COMMENT_MODE,
403 hljs.C_BLOCK_COMMENT_MODE,
404 PREPROCESSOR
405 ]
406 };
407
408 return {
409 name: 'C++',
410 aliases: [
411 'cc',
412 'c++',
413 'h++',
414 'hpp',
415 'hh',
416 'hxx',
417 'cxx'
418 ],
419 keywords: CPP_KEYWORDS,
420 illegal: '</',
421 classNameAliases: {
422 "function.dispatch": "built_in"
423 },
424 contains: [].concat(
425 EXPRESSION_CONTEXT,
426 FUNCTION_DECLARATION,
427 FUNCTION_DISPATCH,
428 EXPRESSION_CONTAINS,
429 [
430 PREPROCESSOR,
431 { // containers: ie, `vector <int> rooms (9);`
432 begin: '\\b(deque|list|queue|priority_queue|pair|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<',
433 end: '>',
434 keywords: CPP_KEYWORDS,
435 contains: [
436 'self',
437 CPP_PRIMITIVE_TYPES
438 ]
439 },
440 {
441 begin: hljs.IDENT_RE + '::',
442 keywords: CPP_KEYWORDS
443 },
444 {
445 className: 'class',
446 beginKeywords: 'enum class struct union',
447 end: /[{;:<>=]/,
448 contains: [
449 {
450 beginKeywords: "final class struct"
451 },
452 hljs.TITLE_MODE
453 ]
454 }
455 ]),
456 exports: {
457 preprocessor: PREPROCESSOR,
458 strings: STRINGS,
459 keywords: CPP_KEYWORDS
460 }
461 };
462}
463
464module.exports = cpp;
Note: See TracBrowser for help on using the repository browser.