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