]> luflow.net public git repositories - flow-web.git/blob - static/highlight/languages/perl.js
Initial commit.
[flow-web.git] / static / highlight / languages / perl.js
1 /*! `perl` grammar compiled for Highlight.js 11.11.1 */
2 (function(){
3 var hljsGrammar = (function () {
4 'use strict';
5
6 /*
7 Language: Perl
8 Author: Peter Leonov <gojpeg@yandex.ru>
9 Website: https://www.perl.org
10 Category: common
11 */
12
13 /** @type LanguageFn */
14 function perl(hljs) {
15 const regex = hljs.regex;
16 const KEYWORDS = [
17 'abs',
18 'accept',
19 'alarm',
20 'and',
21 'atan2',
22 'bind',
23 'binmode',
24 'bless',
25 'break',
26 'caller',
27 'chdir',
28 'chmod',
29 'chomp',
30 'chop',
31 'chown',
32 'chr',
33 'chroot',
34 'class',
35 'close',
36 'closedir',
37 'connect',
38 'continue',
39 'cos',
40 'crypt',
41 'dbmclose',
42 'dbmopen',
43 'defined',
44 'delete',
45 'die',
46 'do',
47 'dump',
48 'each',
49 'else',
50 'elsif',
51 'endgrent',
52 'endhostent',
53 'endnetent',
54 'endprotoent',
55 'endpwent',
56 'endservent',
57 'eof',
58 'eval',
59 'exec',
60 'exists',
61 'exit',
62 'exp',
63 'fcntl',
64 'field',
65 'fileno',
66 'flock',
67 'for',
68 'foreach',
69 'fork',
70 'format',
71 'formline',
72 'getc',
73 'getgrent',
74 'getgrgid',
75 'getgrnam',
76 'gethostbyaddr',
77 'gethostbyname',
78 'gethostent',
79 'getlogin',
80 'getnetbyaddr',
81 'getnetbyname',
82 'getnetent',
83 'getpeername',
84 'getpgrp',
85 'getpriority',
86 'getprotobyname',
87 'getprotobynumber',
88 'getprotoent',
89 'getpwent',
90 'getpwnam',
91 'getpwuid',
92 'getservbyname',
93 'getservbyport',
94 'getservent',
95 'getsockname',
96 'getsockopt',
97 'given',
98 'glob',
99 'gmtime',
100 'goto',
101 'grep',
102 'gt',
103 'hex',
104 'if',
105 'index',
106 'int',
107 'ioctl',
108 'join',
109 'keys',
110 'kill',
111 'last',
112 'lc',
113 'lcfirst',
114 'length',
115 'link',
116 'listen',
117 'local',
118 'localtime',
119 'log',
120 'lstat',
121 'lt',
122 'ma',
123 'map',
124 'method',
125 'mkdir',
126 'msgctl',
127 'msgget',
128 'msgrcv',
129 'msgsnd',
130 'my',
131 'ne',
132 'next',
133 'no',
134 'not',
135 'oct',
136 'open',
137 'opendir',
138 'or',
139 'ord',
140 'our',
141 'pack',
142 'package',
143 'pipe',
144 'pop',
145 'pos',
146 'print',
147 'printf',
148 'prototype',
149 'push',
150 'q|0',
151 'qq',
152 'quotemeta',
153 'qw',
154 'qx',
155 'rand',
156 'read',
157 'readdir',
158 'readline',
159 'readlink',
160 'readpipe',
161 'recv',
162 'redo',
163 'ref',
164 'rename',
165 'require',
166 'reset',
167 'return',
168 'reverse',
169 'rewinddir',
170 'rindex',
171 'rmdir',
172 'say',
173 'scalar',
174 'seek',
175 'seekdir',
176 'select',
177 'semctl',
178 'semget',
179 'semop',
180 'send',
181 'setgrent',
182 'sethostent',
183 'setnetent',
184 'setpgrp',
185 'setpriority',
186 'setprotoent',
187 'setpwent',
188 'setservent',
189 'setsockopt',
190 'shift',
191 'shmctl',
192 'shmget',
193 'shmread',
194 'shmwrite',
195 'shutdown',
196 'sin',
197 'sleep',
198 'socket',
199 'socketpair',
200 'sort',
201 'splice',
202 'split',
203 'sprintf',
204 'sqrt',
205 'srand',
206 'stat',
207 'state',
208 'study',
209 'sub',
210 'substr',
211 'symlink',
212 'syscall',
213 'sysopen',
214 'sysread',
215 'sysseek',
216 'system',
217 'syswrite',
218 'tell',
219 'telldir',
220 'tie',
221 'tied',
222 'time',
223 'times',
224 'tr',
225 'truncate',
226 'uc',
227 'ucfirst',
228 'umask',
229 'undef',
230 'unless',
231 'unlink',
232 'unpack',
233 'unshift',
234 'untie',
235 'until',
236 'use',
237 'utime',
238 'values',
239 'vec',
240 'wait',
241 'waitpid',
242 'wantarray',
243 'warn',
244 'when',
245 'while',
246 'write',
247 'x|0',
248 'xor',
249 'y|0'
250 ];
251
252 // https://perldoc.perl.org/perlre#Modifiers
253 const REGEX_MODIFIERS = /[dualxmsipngr]{0,12}/; // aa and xx are valid, making max length 12
254 const PERL_KEYWORDS = {
255 $pattern: /[\w.]+/,
256 keyword: KEYWORDS.join(" ")
257 };
258 const SUBST = {
259 className: 'subst',
260 begin: '[$@]\\{',
261 end: '\\}',
262 keywords: PERL_KEYWORDS
263 };
264 const METHOD = {
265 begin: /->\{/,
266 end: /\}/
267 // contains defined later
268 };
269 const ATTR = {
270 scope: 'attr',
271 match: /\s+:\s*\w+(\s*\(.*?\))?/,
272 };
273 const VAR = {
274 scope: 'variable',
275 variants: [
276 { begin: /\$\d/ },
277 { begin: regex.concat(
278 /[$%@](?!")(\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,
279 // negative look-ahead tries to avoid matching patterns that are not
280 // Perl at all like $ident$, @ident@, etc.
281 `(?![A-Za-z])(?![@$%])`
282 )
283 },
284 {
285 // Only $= is a special Perl variable and one can't declare @= or %=.
286 begin: /[$%@](?!")[^\s\w{=]|\$=/,
287 relevance: 0
288 }
289 ],
290 contains: [ ATTR ],
291 };
292 const NUMBER = {
293 className: 'number',
294 variants: [
295 // decimal numbers:
296 // include the case where a number starts with a dot (eg. .9), and
297 // the leading 0? avoids mixing the first and second match on 0.x cases
298 { match: /0?\.[0-9][0-9_]+\b/ },
299 // include the special versioned number (eg. v5.38)
300 { match: /\bv?(0|[1-9][0-9_]*(\.[0-9_]+)?|[1-9][0-9_]*)\b/ },
301 // non-decimal numbers:
302 { match: /\b0[0-7][0-7_]*\b/ },
303 { match: /\b0x[0-9a-fA-F][0-9a-fA-F_]*\b/ },
304 { match: /\b0b[0-1][0-1_]*\b/ },
305 ],
306 relevance: 0
307 };
308 const STRING_CONTAINS = [
309 hljs.BACKSLASH_ESCAPE,
310 SUBST,
311 VAR
312 ];
313 const REGEX_DELIMS = [
314 /!/,
315 /\//,
316 /\|/,
317 /\?/,
318 /'/,
319 /"/, // valid but infrequent and weird
320 /#/ // valid but infrequent and weird
321 ];
322 /**
323 * @param {string|RegExp} prefix
324 * @param {string|RegExp} open
325 * @param {string|RegExp} close
326 */
327 const PAIRED_DOUBLE_RE = (prefix, open, close = '\\1') => {
328 const middle = (close === '\\1')
329 ? close
330 : regex.concat(close, open);
331 return regex.concat(
332 regex.concat("(?:", prefix, ")"),
333 open,
334 /(?:\\.|[^\\\/])*?/,
335 middle,
336 /(?:\\.|[^\\\/])*?/,
337 close,
338 REGEX_MODIFIERS
339 );
340 };
341 /**
342 * @param {string|RegExp} prefix
343 * @param {string|RegExp} open
344 * @param {string|RegExp} close
345 */
346 const PAIRED_RE = (prefix, open, close) => {
347 return regex.concat(
348 regex.concat("(?:", prefix, ")"),
349 open,
350 /(?:\\.|[^\\\/])*?/,
351 close,
352 REGEX_MODIFIERS
353 );
354 };
355 const PERL_DEFAULT_CONTAINS = [
356 VAR,
357 hljs.HASH_COMMENT_MODE,
358 hljs.COMMENT(
359 /^=\w/,
360 /=cut/,
361 { endsWithParent: true }
362 ),
363 METHOD,
364 {
365 className: 'string',
366 contains: STRING_CONTAINS,
367 variants: [
368 {
369 begin: 'q[qwxr]?\\s*\\(',
370 end: '\\)',
371 relevance: 5
372 },
373 {
374 begin: 'q[qwxr]?\\s*\\[',
375 end: '\\]',
376 relevance: 5
377 },
378 {
379 begin: 'q[qwxr]?\\s*\\{',
380 end: '\\}',
381 relevance: 5
382 },
383 {
384 begin: 'q[qwxr]?\\s*\\|',
385 end: '\\|',
386 relevance: 5
387 },
388 {
389 begin: 'q[qwxr]?\\s*<',
390 end: '>',
391 relevance: 5
392 },
393 {
394 begin: 'qw\\s+q',
395 end: 'q',
396 relevance: 5
397 },
398 {
399 begin: '\'',
400 end: '\'',
401 contains: [ hljs.BACKSLASH_ESCAPE ]
402 },
403 {
404 begin: '"',
405 end: '"'
406 },
407 {
408 begin: '`',
409 end: '`',
410 contains: [ hljs.BACKSLASH_ESCAPE ]
411 },
412 {
413 begin: /\{\w+\}/,
414 relevance: 0
415 },
416 {
417 begin: '-?\\w+\\s*=>',
418 relevance: 0
419 }
420 ]
421 },
422 NUMBER,
423 { // regexp container
424 begin: '(\\/\\/|' + hljs.RE_STARTERS_RE + '|\\b(split|return|print|reverse|grep)\\b)\\s*',
425 keywords: 'split return print reverse grep',
426 relevance: 0,
427 contains: [
428 hljs.HASH_COMMENT_MODE,
429 {
430 className: 'regexp',
431 variants: [
432 // allow matching common delimiters
433 { begin: PAIRED_DOUBLE_RE("s|tr|y", regex.either(...REGEX_DELIMS, { capture: true })) },
434 // and then paired delmis
435 { begin: PAIRED_DOUBLE_RE("s|tr|y", "\\(", "\\)") },
436 { begin: PAIRED_DOUBLE_RE("s|tr|y", "\\[", "\\]") },
437 { begin: PAIRED_DOUBLE_RE("s|tr|y", "\\{", "\\}") }
438 ],
439 relevance: 2
440 },
441 {
442 className: 'regexp',
443 variants: [
444 {
445 // could be a comment in many languages so do not count
446 // as relevant
447 begin: /(m|qr)\/\//,
448 relevance: 0
449 },
450 // prefix is optional with /regex/
451 { begin: PAIRED_RE("(?:m|qr)?", /\//, /\//) },
452 // allow matching common delimiters
453 { begin: PAIRED_RE("m|qr", regex.either(...REGEX_DELIMS, { capture: true }), /\1/) },
454 // allow common paired delmins
455 { begin: PAIRED_RE("m|qr", /\(/, /\)/) },
456 { begin: PAIRED_RE("m|qr", /\[/, /\]/) },
457 { begin: PAIRED_RE("m|qr", /\{/, /\}/) }
458 ]
459 }
460 ]
461 },
462 {
463 className: 'function',
464 beginKeywords: 'sub method',
465 end: '(\\s*\\(.*?\\))?[;{]',
466 excludeEnd: true,
467 relevance: 5,
468 contains: [ hljs.TITLE_MODE, ATTR ]
469 },
470 {
471 className: 'class',
472 beginKeywords: 'class',
473 end: '[;{]',
474 excludeEnd: true,
475 relevance: 5,
476 contains: [ hljs.TITLE_MODE, ATTR, NUMBER ]
477 },
478 {
479 begin: '-\\w\\b',
480 relevance: 0
481 },
482 {
483 begin: "^__DATA__$",
484 end: "^__END__$",
485 subLanguage: 'mojolicious',
486 contains: [
487 {
488 begin: "^@@.*",
489 end: "$",
490 className: "comment"
491 }
492 ]
493 }
494 ];
495 SUBST.contains = PERL_DEFAULT_CONTAINS;
496 METHOD.contains = PERL_DEFAULT_CONTAINS;
497
498 return {
499 name: 'Perl',
500 aliases: [
501 'pl',
502 'pm'
503 ],
504 keywords: PERL_KEYWORDS,
505 contains: PERL_DEFAULT_CONTAINS
506 };
507 }
508
509 return perl;
510
511 })();
512
513 hljs.registerLanguage('perl', hljsGrammar);
514 })();