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 }