View Javadoc

1   /*
2    * PerlTokenMarker.java - Perl token marker
3    * Copyright (C) 1998, 1999 Slava Pestov
4    *
5    * You may use and modify this package for any purpose. Redistribution is
6    * permitted, in both source and binary form, provided that this notice
7    * remains intact in all source distributions of this package.
8    */
9   
10  package org.syntax.jedit.tokenmarker;
11  
12  import javax.swing.text.Segment;
13  
14  import org.syntax.jedit.KeywordMap;
15  import org.syntax.jedit.SyntaxUtilities;
16  
17  /***
18   * Perl token marker.
19   *
20   * @author Slava Pestov
21   * @version $Id: PerlTokenMarker.java,v 1.11 1999/12/13 03:40:30 sp Exp $
22   */
23  public class PerlTokenMarker extends TokenMarker
24  {
25  	// public members
26  	public static final byte S_ONE = Token.INTERNAL_FIRST;
27  	public static final byte S_TWO = (byte)(Token.INTERNAL_FIRST + 1);
28  	public static final byte S_END = (byte)(Token.INTERNAL_FIRST + 2);
29  
30  	public PerlTokenMarker()
31  	{
32  		this(getKeywords());
33  	}
34  
35  	public PerlTokenMarker(KeywordMap keywords)
36  	{
37  		this.keywords = keywords;
38  	}
39  
40  	public byte markTokensImpl(byte _token, Segment line, int lineIndex)
41  	{
42  		char[] array = line.array;
43  		int offset = line.offset;
44  		token = _token;
45  		lastOffset = offset;
46  		lastKeyword = offset;
47  		matchChar = '\0';
48  		matchCharBracket = false;
49  		matchSpacesAllowed = false;
50  		int length = line.count + offset;
51  
52  		if(token == Token.LITERAL1 && lineIndex != 0
53  			&& lineInfo[lineIndex - 1].obj != null)
54  		{
55  			String str = (String)lineInfo[lineIndex - 1].obj;
56  			if(str != null && str.length() == line.count
57  				&& SyntaxUtilities.regionMatches(false,line,
58  				offset,str))
59  			{
60  				addToken(line.count,token);
61  				return Token.NULL;
62  			}
63  			else
64  			{
65  				addToken(line.count,token);
66  				lineInfo[lineIndex].obj = str;
67  				return token;
68  			}
69  		}
70  
71  		boolean backslash = false;
72  loop:		for(int i = offset; i < length; i++)
73  		{
74  			int i1 = (i+1);
75  
76  			char c = array[i];
77  			if(c == '//')
78  			{
79  				backslash = !backslash;
80  				continue;
81  			}
82  
83  			switch(token)
84  			{
85  			case Token.NULL:
86  				switch(c)
87  				{
88  				case '#':
89  					if(doKeyword(line,i,c))
90  						break;
91  					if(backslash)
92  						backslash = false;
93  					else
94  					{
95  						addToken(i - lastOffset,token);
96  						addToken(length - i,Token.COMMENT1);
97  						lastOffset = lastKeyword = length;
98  						break loop;
99  					}
100 					break;
101 				case '=':
102 					backslash = false;
103 					if(i == offset)
104 					{
105 						token = Token.COMMENT2;
106 						addToken(length - i,token);
107 						lastOffset = lastKeyword = length;
108 						break loop;
109 					}
110 					else
111 						doKeyword(line,i,c);
112 					break;
113 				case '$': case '&': case '%': case '@':
114 					backslash = false;
115 					if(doKeyword(line,i,c))
116 						break;
117 					if(length - i > 1)
118 					{
119 						if(c == '&' && (array[i1] == '&'
120 							|| Character.isWhitespace(
121 							array[i1])))
122 							i++;
123 						else
124 						{
125 							addToken(i - lastOffset,token);
126 							lastOffset = lastKeyword = i;
127 							token = Token.KEYWORD2;
128 						}
129 					}
130 					break;
131 				case '"':
132 					if(doKeyword(line,i,c))
133 						break;
134 					if(backslash)
135 						backslash = false;
136 					else
137 					{
138 						addToken(i - lastOffset,token);
139 						token = Token.LITERAL1;
140 						lineInfo[lineIndex].obj = null;
141 						lastOffset = lastKeyword = i;
142 					}
143 					break;
144 				case '\'':
145 					if(backslash)
146 						backslash = false;
147 					else
148 					{
149 						int oldLastKeyword = lastKeyword;
150 						if(doKeyword(line,i,c))
151 							break;
152 						if(i != oldLastKeyword)
153 							break;
154 						addToken(i - lastOffset,token);
155 						token = Token.LITERAL2;
156 						lastOffset = lastKeyword = i;
157 					}
158 					break;
159 				case '`':
160 					if(doKeyword(line,i,c))
161 						break;
162 					if(backslash)
163 						backslash = false;
164 					else
165 					{
166 						addToken(i - lastOffset,token);
167 						token = Token.OPERATOR;
168 						lastOffset = lastKeyword = i;
169 					}
170 					break;
171 				case '<':
172 					if(doKeyword(line,i,c))
173 						break;
174 					if(backslash)
175 						backslash = false;
176 					else
177 					{
178 						if(length - i > 2 && array[i1] == '<'
179 							&& !Character.isWhitespace(array[i+2]))
180 						{
181 							addToken(i - lastOffset,token);
182 							lastOffset = lastKeyword = i;
183 							token = Token.LITERAL1;
184 							int len = length - (i+2);
185 							if(array[length - 1] == ';')
186 								len--;
187 							lineInfo[lineIndex].obj =
188 								createReadinString(array,i + 2,len);
189 						}
190 					}
191 					break;
192 				case ':':
193 					backslash = false;
194 					if(doKeyword(line,i,c))
195 						break;
196 					// Doesn't pick up all labels,
197 					// but at least doesn't mess up
198 					if(lastKeyword != 0)
199 						break;
200 					addToken(i1 - lastOffset,Token.LABEL);
201 					lastOffset = lastKeyword = i1;
202 					break;
203 				case '-':
204 					backslash = false;
205 					if(doKeyword(line,i,c))
206 						break;
207 					if(i != lastKeyword || length - i <= 1)
208 						break;
209 					switch(array[i1])
210 					{
211 					case 'r': case 'w': case 'x':
212 					case 'o': case 'R': case 'W':
213 					case 'X': case 'O': case 'e':
214 					case 'z': case 's': case 'f':
215 					case 'd': case 'l': case 'p':
216 					case 'S': case 'b': case 'c':
217 					case 't': case 'u': case 'g':
218 					case 'k': case 'T': case 'B':
219 					case 'M': case 'A': case 'C':
220 						addToken(i - lastOffset,token);
221 						addToken(2,Token.KEYWORD3);
222 						lastOffset = lastKeyword = i+2;
223 						i++;
224 					}
225 					break;
226 				case '/': case '?':
227 					if(doKeyword(line,i,c))
228 						break;
229 					if(length - i > 1)
230 					{
231 						backslash = false;
232 						char ch = array[i1];
233 						if(Character.isWhitespace(ch))
234 							break;
235 						matchChar = c;
236 						matchSpacesAllowed = false;
237 						addToken(i - lastOffset,token);
238 						token = S_ONE;
239 						lastOffset = lastKeyword = i;
240 					}
241 					break;
242 				default:
243 					backslash = false;
244 					if(!Character.isLetterOrDigit(c)
245 						&& c != '_')
246 						doKeyword(line,i,c);
247 					break;
248 				}
249 				break;
250 			case Token.KEYWORD2:
251 				backslash = false;
252 				// This test checks for an end-of-variable
253 				// condition
254 				if(!Character.isLetterOrDigit(c) && c != '_'
255 					&& c != '#' && c != '\'' && c != ':'
256 					&& c != '&')
257 				{
258 					// If this is the first character
259 					// of the variable name ($'aaa)
260 					// ignore it
261 					if(i != offset && array[i-1] == '$')
262 					{
263 						addToken(i1 - lastOffset,token);
264 						lastOffset = lastKeyword = i1;
265 					}
266 					// Otherwise, end of variable...
267 					else
268 					{
269 						addToken(i - lastOffset,token);
270 						lastOffset = lastKeyword = i;
271 						// Wind back so that stuff
272 						// like $hello$fred is picked
273 						// up
274 						i--;
275 						token = Token.NULL;
276 					}
277 				}
278 				break;
279 			case S_ONE: case S_TWO:
280 				if(backslash)
281 					backslash = false;
282 				else
283 				{
284 					if(matchChar == '\0')
285 					{
286 						if(Character.isWhitespace(matchChar)
287 							&& !matchSpacesAllowed)
288 							break;
289 						else
290 							matchChar = c;
291 					}
292 					else
293 					{
294 						switch(matchChar)
295 						{
296 						case '(':
297 							matchChar = ')';
298 							matchCharBracket = true;
299 							break;
300 						case '[':
301 							matchChar = ']';
302 							matchCharBracket = true;
303 							break;
304 						case '{':
305 							matchChar = '}';
306 							matchCharBracket = true;
307 							break;
308 						case '<':
309 							matchChar = '>';
310 							matchCharBracket = true;
311 							break;
312 						default:
313 							matchCharBracket = false;
314 							break;
315 						}
316 						if(c != matchChar)
317 							break;
318 						if(token == S_TWO)
319 						{
320 							token = S_ONE;
321 							if(matchCharBracket)
322 								matchChar = '\0';
323 						}
324 						else
325 						{
326 							token = S_END;
327 							addToken(i1 - lastOffset,
328 								Token.LITERAL2);
329 							lastOffset = lastKeyword = i1;
330 						}
331 					}
332 				}
333 				break;
334 			case S_END:
335 				backslash = false;
336 				if(!Character.isLetterOrDigit(c)
337 					&& c != '_')
338 					doKeyword(line,i,c);
339 				break;
340 			case Token.COMMENT2:
341 				backslash = false;
342 				if(i == offset)
343 				{
344 					addToken(line.count,token);
345 					if(length - i > 3 && SyntaxUtilities
346 						.regionMatches(false,line,offset,"=cut"))
347 						token = Token.NULL;
348 					lastOffset = lastKeyword = length;
349 					break loop;
350 				}
351 				break;
352 			case Token.LITERAL1:
353 				if(backslash)
354 					backslash = false;
355 				/* else if(c == '$')
356 					backslash = true; */
357 				else if(c == '"')
358 				{
359 					addToken(i1 - lastOffset,token);
360 					token = Token.NULL;
361 					lastOffset = lastKeyword = i1;
362 				}
363 				break;
364 			case Token.LITERAL2:
365 				if(backslash)
366 					backslash = false;
367 				/* else if(c == '$')
368 					backslash = true; */
369 				else if(c == '\'')
370 				{
371 					addToken(i1 - lastOffset,Token.LITERAL1);
372 					token = Token.NULL;
373 					lastOffset = lastKeyword = i1;
374 				}
375 				break;
376 			case Token.OPERATOR:
377 				if(backslash)
378 					backslash = false;
379 				else if(c == '`')
380 				{
381 					addToken(i1 - lastOffset,token);
382 					token = Token.NULL;
383 					lastOffset = lastKeyword = i1;
384 				}
385 				break;
386 			default:
387 				throw new InternalError("Invalid state: "
388 					+ token);
389 			}
390 		}
391 
392 		if(token == Token.NULL)
393 			doKeyword(line,length,'\0');
394 
395 		switch(token)
396 		{
397 		case Token.KEYWORD2:
398 			addToken(length - lastOffset,token);
399 			token = Token.NULL;
400 			break;
401 		case Token.LITERAL2:
402 			addToken(length - lastOffset,Token.LITERAL1);
403 			break;
404 		case S_END:
405 			addToken(length - lastOffset,Token.LITERAL2);
406 			token = Token.NULL;
407 			break;
408 		case S_ONE: case S_TWO:
409 			addToken(length - lastOffset,Token.INVALID);
410 			token = Token.NULL;
411 			break;
412 		default:
413 			addToken(length - lastOffset,token);
414 			break;
415 		}
416 		return token;
417 	}
418 
419 	// private members
420 	private KeywordMap keywords;
421 	private byte token;
422 	private int lastOffset;
423 	private int lastKeyword;
424 	private char matchChar;
425 	private boolean matchCharBracket;
426 	private boolean matchSpacesAllowed;
427 
428 	private boolean doKeyword(Segment line, int i, char c)
429 	{
430 		int i1 = i+1;
431 
432 		if(token == S_END)
433 		{
434 			addToken(i - lastOffset,Token.LITERAL2);
435 			token = Token.NULL;
436 			lastOffset = i;
437 			lastKeyword = i1;
438 			return false;
439 		}
440 
441 		int len = i - lastKeyword;
442 		byte id = keywords.lookup(line,lastKeyword,len);
443 		if(id == S_ONE || id == S_TWO)
444 		{
445 			if(lastKeyword != lastOffset)
446 				addToken(lastKeyword - lastOffset,Token.NULL);
447 			addToken(len,Token.LITERAL2);
448 			lastOffset = i;
449 			lastKeyword = i1;
450 			if(Character.isWhitespace(c))
451 				matchChar = '\0';
452 			else
453 				matchChar = c;
454 			matchSpacesAllowed = true;
455 			token = id;
456 			return true;
457 		}
458 		else if(id != Token.NULL)
459 		{
460 			if(lastKeyword != lastOffset)
461 				addToken(lastKeyword - lastOffset,Token.NULL);
462 			addToken(len,id);
463 			lastOffset = i;
464 		}
465 		lastKeyword = i1;
466 		return false;
467 	}
468 
469 	// Converts < EOF >, < 'EOF' >, etc to <EOF>
470 	private String createReadinString(char[] array, int start, int len)
471 	{
472 		int idx1 = start;
473 		int idx2 = start + len - 1;
474 
475 		while((idx1 <= idx2) && (!Character.isLetterOrDigit(array[idx1])))
476 			idx1++;
477 
478 		while((idx1 <= idx2) && (!Character.isLetterOrDigit(array[idx2])))
479 			idx2--;
480 
481 		return new String(array, idx1, idx2 - idx1 + 1);
482 	}
483 
484 	private static KeywordMap perlKeywords;
485 
486 	private static KeywordMap getKeywords()
487 	{
488 		if(perlKeywords == null)
489 		{
490 			perlKeywords = new KeywordMap(false);
491 			perlKeywords.add("my",Token.KEYWORD1);
492 			perlKeywords.add("local",Token.KEYWORD1);
493 			perlKeywords.add("new",Token.KEYWORD1);
494 			perlKeywords.add("if",Token.KEYWORD1);
495 			perlKeywords.add("until",Token.KEYWORD1);
496 			perlKeywords.add("while",Token.KEYWORD1);
497 			perlKeywords.add("elsif",Token.KEYWORD1);
498 			perlKeywords.add("else",Token.KEYWORD1);
499 			perlKeywords.add("eval",Token.KEYWORD1);
500 			perlKeywords.add("unless",Token.KEYWORD1);
501 			perlKeywords.add("foreach",Token.KEYWORD1);
502 			perlKeywords.add("continue",Token.KEYWORD1);
503 			perlKeywords.add("exit",Token.KEYWORD1);
504 			perlKeywords.add("die",Token.KEYWORD1);
505 			perlKeywords.add("last",Token.KEYWORD1);
506 			perlKeywords.add("goto",Token.KEYWORD1);
507 			perlKeywords.add("next",Token.KEYWORD1);
508 			perlKeywords.add("redo",Token.KEYWORD1);
509 			perlKeywords.add("goto",Token.KEYWORD1);
510 			perlKeywords.add("return",Token.KEYWORD1);
511 			perlKeywords.add("do",Token.KEYWORD1);
512 			perlKeywords.add("sub",Token.KEYWORD1);
513 			perlKeywords.add("use",Token.KEYWORD1);
514 			perlKeywords.add("require",Token.KEYWORD1);
515 			perlKeywords.add("package",Token.KEYWORD1);
516 			perlKeywords.add("BEGIN",Token.KEYWORD1);
517 			perlKeywords.add("END",Token.KEYWORD1);
518 			perlKeywords.add("eq",Token.OPERATOR);
519 			perlKeywords.add("ne",Token.OPERATOR);
520 			perlKeywords.add("not",Token.OPERATOR);
521 			perlKeywords.add("and",Token.OPERATOR);
522 			perlKeywords.add("or",Token.OPERATOR);
523 
524 			perlKeywords.add("abs",Token.KEYWORD3);
525 			perlKeywords.add("accept",Token.KEYWORD3);
526 			perlKeywords.add("alarm",Token.KEYWORD3);
527 			perlKeywords.add("atan2",Token.KEYWORD3);
528 			perlKeywords.add("bind",Token.KEYWORD3);
529 			perlKeywords.add("binmode",Token.KEYWORD3);
530 			perlKeywords.add("bless",Token.KEYWORD3);
531 			perlKeywords.add("caller",Token.KEYWORD3);
532 			perlKeywords.add("chdir",Token.KEYWORD3);
533 			perlKeywords.add("chmod",Token.KEYWORD3);
534 			perlKeywords.add("chomp",Token.KEYWORD3);
535 			perlKeywords.add("chr",Token.KEYWORD3);
536 			perlKeywords.add("chroot",Token.KEYWORD3);
537 			perlKeywords.add("chown",Token.KEYWORD3);
538 			perlKeywords.add("closedir",Token.KEYWORD3);
539 			perlKeywords.add("close",Token.KEYWORD3);
540 			perlKeywords.add("connect",Token.KEYWORD3);
541 			perlKeywords.add("cos",Token.KEYWORD3);
542 			perlKeywords.add("crypt",Token.KEYWORD3);
543 			perlKeywords.add("dbmclose",Token.KEYWORD3);
544 			perlKeywords.add("dbmopen",Token.KEYWORD3);
545 			perlKeywords.add("defined",Token.KEYWORD3);
546 			perlKeywords.add("delete",Token.KEYWORD3);
547 			perlKeywords.add("die",Token.KEYWORD3);
548 			perlKeywords.add("dump",Token.KEYWORD3);
549 			perlKeywords.add("each",Token.KEYWORD3);
550 			perlKeywords.add("endgrent",Token.KEYWORD3);
551 			perlKeywords.add("endhostent",Token.KEYWORD3);
552 			perlKeywords.add("endnetent",Token.KEYWORD3);
553 			perlKeywords.add("endprotoent",Token.KEYWORD3);
554 			perlKeywords.add("endpwent",Token.KEYWORD3);
555 			perlKeywords.add("endservent",Token.KEYWORD3);
556 			perlKeywords.add("eof",Token.KEYWORD3);
557 			perlKeywords.add("exec",Token.KEYWORD3);
558 			perlKeywords.add("exists",Token.KEYWORD3);
559 			perlKeywords.add("exp",Token.KEYWORD3);
560 			perlKeywords.add("fctnl",Token.KEYWORD3);
561 			perlKeywords.add("fileno",Token.KEYWORD3);
562 			perlKeywords.add("flock",Token.KEYWORD3);
563 			perlKeywords.add("fork",Token.KEYWORD3);
564 			perlKeywords.add("format",Token.KEYWORD3);
565 			perlKeywords.add("formline",Token.KEYWORD3);
566 			perlKeywords.add("getc",Token.KEYWORD3);
567 			perlKeywords.add("getgrent",Token.KEYWORD3);
568 			perlKeywords.add("getgrgid",Token.KEYWORD3);
569 			perlKeywords.add("getgrnam",Token.KEYWORD3);
570 			perlKeywords.add("gethostbyaddr",Token.KEYWORD3);
571 			perlKeywords.add("gethostbyname",Token.KEYWORD3);
572 			perlKeywords.add("gethostent",Token.KEYWORD3);
573 			perlKeywords.add("getlogin",Token.KEYWORD3);
574 			perlKeywords.add("getnetbyaddr",Token.KEYWORD3);
575 			perlKeywords.add("getnetbyname",Token.KEYWORD3);
576 			perlKeywords.add("getnetent",Token.KEYWORD3);
577 			perlKeywords.add("getpeername",Token.KEYWORD3);
578 			perlKeywords.add("getpgrp",Token.KEYWORD3);
579 			perlKeywords.add("getppid",Token.KEYWORD3);
580 			perlKeywords.add("getpriority",Token.KEYWORD3);
581 			perlKeywords.add("getprotobyname",Token.KEYWORD3);
582 			perlKeywords.add("getprotobynumber",Token.KEYWORD3);
583 			perlKeywords.add("getprotoent",Token.KEYWORD3);
584 			perlKeywords.add("getpwent",Token.KEYWORD3);
585 			perlKeywords.add("getpwnam",Token.KEYWORD3);
586 			perlKeywords.add("getpwuid",Token.KEYWORD3);
587 			perlKeywords.add("getservbyname",Token.KEYWORD3);
588 			perlKeywords.add("getservbyport",Token.KEYWORD3);
589 			perlKeywords.add("getservent",Token.KEYWORD3);
590 			perlKeywords.add("getsockname",Token.KEYWORD3);
591 			perlKeywords.add("getsockopt",Token.KEYWORD3);
592 			perlKeywords.add("glob",Token.KEYWORD3);
593 			perlKeywords.add("gmtime",Token.KEYWORD3);
594 			perlKeywords.add("grep",Token.KEYWORD3);
595 			perlKeywords.add("hex",Token.KEYWORD3);
596 			perlKeywords.add("import",Token.KEYWORD3);
597 			perlKeywords.add("index",Token.KEYWORD3);
598 			perlKeywords.add("int",Token.KEYWORD3);
599 			perlKeywords.add("ioctl",Token.KEYWORD3);
600 			perlKeywords.add("join",Token.KEYWORD3);
601 			perlKeywords.add("keys",Token.KEYWORD3);
602 			perlKeywords.add("kill",Token.KEYWORD3);
603 			perlKeywords.add("lcfirst",Token.KEYWORD3);
604 			perlKeywords.add("lc",Token.KEYWORD3);
605 			perlKeywords.add("length",Token.KEYWORD3);
606 			perlKeywords.add("link",Token.KEYWORD3);
607 			perlKeywords.add("listen",Token.KEYWORD3);
608 			perlKeywords.add("log",Token.KEYWORD3);
609 			perlKeywords.add("localtime",Token.KEYWORD3);
610 			perlKeywords.add("lstat",Token.KEYWORD3);
611 			perlKeywords.add("map",Token.KEYWORD3);
612 			perlKeywords.add("mkdir",Token.KEYWORD3);
613 			perlKeywords.add("msgctl",Token.KEYWORD3);
614 			perlKeywords.add("msgget",Token.KEYWORD3);
615 			perlKeywords.add("msgrcv",Token.KEYWORD3);
616 			perlKeywords.add("no",Token.KEYWORD3);
617 			perlKeywords.add("oct",Token.KEYWORD3);
618 			perlKeywords.add("opendir",Token.KEYWORD3);
619 			perlKeywords.add("open",Token.KEYWORD3);
620 			perlKeywords.add("ord",Token.KEYWORD3);
621 			perlKeywords.add("pack",Token.KEYWORD3);
622 			perlKeywords.add("pipe",Token.KEYWORD3);
623 			perlKeywords.add("pop",Token.KEYWORD3);
624 			perlKeywords.add("pos",Token.KEYWORD3);
625 			perlKeywords.add("printf",Token.KEYWORD3);
626 			perlKeywords.add("print",Token.KEYWORD3);
627 			perlKeywords.add("push",Token.KEYWORD3);
628 			perlKeywords.add("quotemeta",Token.KEYWORD3);
629 			perlKeywords.add("rand",Token.KEYWORD3);
630 			perlKeywords.add("readdir",Token.KEYWORD3);
631 			perlKeywords.add("read",Token.KEYWORD3);
632 			perlKeywords.add("readlink",Token.KEYWORD3);
633 			perlKeywords.add("recv",Token.KEYWORD3);
634 			perlKeywords.add("ref",Token.KEYWORD3);
635 			perlKeywords.add("rename",Token.KEYWORD3);
636 			perlKeywords.add("reset",Token.KEYWORD3);
637 			perlKeywords.add("reverse",Token.KEYWORD3);
638 			perlKeywords.add("rewinddir",Token.KEYWORD3);
639 			perlKeywords.add("rindex",Token.KEYWORD3);
640 			perlKeywords.add("rmdir",Token.KEYWORD3);
641 			perlKeywords.add("scalar",Token.KEYWORD3);
642 			perlKeywords.add("seekdir",Token.KEYWORD3);
643 			perlKeywords.add("seek",Token.KEYWORD3);
644 			perlKeywords.add("select",Token.KEYWORD3);
645 			perlKeywords.add("semctl",Token.KEYWORD3);
646 			perlKeywords.add("semget",Token.KEYWORD3);
647 			perlKeywords.add("semop",Token.KEYWORD3);
648 			perlKeywords.add("send",Token.KEYWORD3);
649 			perlKeywords.add("setgrent",Token.KEYWORD3);
650 			perlKeywords.add("sethostent",Token.KEYWORD3);
651 			perlKeywords.add("setnetent",Token.KEYWORD3);
652 			perlKeywords.add("setpgrp",Token.KEYWORD3);
653 			perlKeywords.add("setpriority",Token.KEYWORD3);
654 			perlKeywords.add("setprotoent",Token.KEYWORD3);
655 			perlKeywords.add("setpwent",Token.KEYWORD3);
656 			perlKeywords.add("setsockopt",Token.KEYWORD3);
657 			perlKeywords.add("shift",Token.KEYWORD3);
658 			perlKeywords.add("shmctl",Token.KEYWORD3);
659 			perlKeywords.add("shmget",Token.KEYWORD3);
660 			perlKeywords.add("shmread",Token.KEYWORD3);
661 			perlKeywords.add("shmwrite",Token.KEYWORD3);
662 			perlKeywords.add("shutdown",Token.KEYWORD3);
663 			perlKeywords.add("sin",Token.KEYWORD3);
664 			perlKeywords.add("sleep",Token.KEYWORD3);
665 			perlKeywords.add("socket",Token.KEYWORD3);
666 			perlKeywords.add("socketpair",Token.KEYWORD3);
667 			perlKeywords.add("sort",Token.KEYWORD3);
668 			perlKeywords.add("splice",Token.KEYWORD3);
669 			perlKeywords.add("split",Token.KEYWORD3);
670 			perlKeywords.add("sprintf",Token.KEYWORD3);
671 			perlKeywords.add("sqrt",Token.KEYWORD3);
672 			perlKeywords.add("srand",Token.KEYWORD3);
673 			perlKeywords.add("stat",Token.KEYWORD3);
674 			perlKeywords.add("study",Token.KEYWORD3);
675 			perlKeywords.add("substr",Token.KEYWORD3);
676 			perlKeywords.add("symlink",Token.KEYWORD3);
677 			perlKeywords.add("syscall",Token.KEYWORD3);
678 			perlKeywords.add("sysopen",Token.KEYWORD3);
679 			perlKeywords.add("sysread",Token.KEYWORD3);
680 			perlKeywords.add("syswrite",Token.KEYWORD3);
681 			perlKeywords.add("telldir",Token.KEYWORD3);
682 			perlKeywords.add("tell",Token.KEYWORD3);
683 			perlKeywords.add("tie",Token.KEYWORD3);
684 			perlKeywords.add("tied",Token.KEYWORD3);
685 			perlKeywords.add("time",Token.KEYWORD3);
686 			perlKeywords.add("times",Token.KEYWORD3);
687 			perlKeywords.add("truncate",Token.KEYWORD3);
688 			perlKeywords.add("uc",Token.KEYWORD3);
689 			perlKeywords.add("ucfirst",Token.KEYWORD3);
690 			perlKeywords.add("umask",Token.KEYWORD3);
691 			perlKeywords.add("undef",Token.KEYWORD3);
692 			perlKeywords.add("unlink",Token.KEYWORD3);
693 			perlKeywords.add("unpack",Token.KEYWORD3);
694 			perlKeywords.add("unshift",Token.KEYWORD3);
695 			perlKeywords.add("untie",Token.KEYWORD3);
696 			perlKeywords.add("utime",Token.KEYWORD3);
697 			perlKeywords.add("values",Token.KEYWORD3);
698 			perlKeywords.add("vec",Token.KEYWORD3);
699 			perlKeywords.add("wait",Token.KEYWORD3);
700 			perlKeywords.add("waitpid",Token.KEYWORD3);
701 			perlKeywords.add("wantarray",Token.KEYWORD3);
702 			perlKeywords.add("warn",Token.KEYWORD3);
703 			perlKeywords.add("write",Token.KEYWORD3);
704 
705 			perlKeywords.add("m",S_ONE);
706 			perlKeywords.add("q",S_ONE);
707 			perlKeywords.add("qq",S_ONE);
708 			perlKeywords.add("qw",S_ONE);
709 			perlKeywords.add("qx",S_ONE);
710 			perlKeywords.add("s",S_TWO);
711 			perlKeywords.add("tr",S_TWO);
712 			perlKeywords.add("y",S_TWO);
713 		}
714 		return perlKeywords;
715 	}	
716 }