/* * Copyright (c) 1998-2011 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */ package com.caucho.quercus.lib; import com.caucho.quercus.QuercusModuleException; import com.caucho.quercus.annotation.Optional; import com.caucho.quercus.env.*; import com.caucho.quercus.lib.file.FileModule; import com.caucho.quercus.module.AbstractQuercusModule; import com.caucho.quercus.module.IniDefinitions; import com.caucho.quercus.module.IniDefinition; import com.caucho.util.IntMap; import com.caucho.util.L10N; import com.caucho.vfs.WriteStream; import java.io.IOException; import java.util.Locale; import java.util.logging.Logger; /** * Quercus tokenizer */ public class TokenModule extends AbstractQuercusModule { private static final L10N L = new L10N(TokenModule.class); private static final Logger log = Logger.getLogger(TokenModule.class.getName()); public static final int T_ABSTRACT = 256; public static final int T_AND_EQUAL = 257; public static final int T_ARRAY = 258; public static final int T_ARRAY_CAST = 259; public static final int T_AS = 260; public static final int T_BAD_CHARACTER = 261; public static final int T_BOOLEAN_AND = 262; public static final int T_BOOLEAN_OR = 263; public static final int T_BOOL_CAST = 264; public static final int T_BREAK = 265; public static final int T_CASE = 266; public static final int T_CATCH = 267; public static final int T_CHARACTER = 268; public static final int T_CLASS = 269; public static final int T_CLONE = 270; public static final int T_CLOSE_TAG = 271; public static final int T_COMMENT = 272; public static final int T_CONCAT_EQUAL = 273; public static final int T_CONST = 274; public static final int T_CONSTANT_ENCAPSED_STRING = 275; public static final int T_CONTINUE = 276; public static final int T_CURLY_OPEN = 277; public static final int T_DEC = 278; public static final int T_DECLARE = 279; public static final int T_DEFAULT = 280; public static final int T_DIV_EQUAL = 281; public static final int T_DNUMBER = 282; public static final int T_DOC_COMMENT = 283; public static final int T_DO = 284; public static final int T_DOLLAR_OPEN_CURLY_BRACES = 285; public static final int T_DOUBLE_ARROW = 286; public static final int T_DOUBLE_CAST = 287; public static final int T_DOUBLE_COLON = 288; public static final int T_ECHO = 289; public static final int T_ELSE = 290; public static final int T_ELSEIF = 291; public static final int T_EMPTY = 292; public static final int T_ENCAPSED_AND_WHITESPACE = 293; public static final int T_ENDDECLARE = 294; public static final int T_ENDFOR = 295; public static final int T_ENDFOREACH = 296; public static final int T_ENDIF = 297; public static final int T_ENDSWITCH = 298; public static final int T_ENDWHILE = 299; public static final int T_END_HEREDOC = 300; public static final int T_EVAL = 301; public static final int T_EXIT = 302; public static final int T_EXTENDS = 303; public static final int T_FILE = 304; public static final int T_FINAL = 305; public static final int T_FOR = 306; public static final int T_FOREACH = 307; public static final int T_FUNCTION = 308; public static final int T_GLOBAL = 309; public static final int T_HALT_COMPILER = 310; public static final int T_IF = 311; public static final int T_IMPLEMENTS = 312; public static final int T_INC = 313; public static final int T_INCLUDE = 314; public static final int T_INCLUDE_ONCE = 315; public static final int T_INLINE_HTML = 316; public static final int T_INSTANCEOF = 317; public static final int T_INT_CAST = 318; public static final int T_INTERFACE = 319; public static final int T_ISSET = 320; public static final int T_IS_EQUAL = 321; public static final int T_IS_GREATER_OR_EQUAL = 322; public static final int T_IS_IDENTICAL = 323; public static final int T_IS_NOT_EQUAL = 324; public static final int T_IS_NOT_IDENTICAL = 325; public static final int T_IS_SMALLER_OR_EQUAL = 326; public static final int T_LINE = 327; public static final int T_LIST = 328; public static final int T_LNUMBER = 329; public static final int T_LOGICAL_AND = 330; public static final int T_LOGICAL_OR = 331; public static final int T_LOGICAL_XOR = 332; public static final int T_MINUS_EQUAL = 333; public static final int T_ML_COMMENT = 334; public static final int T_MOD_EQUAL = 335; public static final int T_MUL_EQUAL = 336; public static final int T_NEW = 337; public static final int T_NUM_STRING = 338; public static final int T_OBJECT_CAST = 339; public static final int T_OBJECT_OPERATOR = 340; public static final int T_OLD_FUNCTION = 341; public static final int T_OPEN_TAG = 342; public static final int T_OPEN_TAG_WITH_ECHO = 343; public static final int T_OR_EQUAL = 344; public static final int T_PAAMAYIM_NEKUDOTAYIM = T_DOUBLE_COLON; public static final int T_PLUS_EQUAL = 345; public static final int T_PRINT = 346; public static final int T_PRIVATE = 347; public static final int T_PUBLIC = 348; public static final int T_PROTECTED = 349; public static final int T_REQUIRE = 350; public static final int T_REQUIRE_ONCE = 351; public static final int T_RETURN = 352; public static final int T_SL = 353; public static final int T_SL_EQUAL = 354; public static final int T_SR = 355; public static final int T_SR_EQUAL = 356; public static final int T_START_HEREDOC = 357; public static final int T_STATIC = 358; public static final int T_STRING = 359; public static final int T_STRING_CAST = 360; public static final int T_STRING_VARNAME = 361; public static final int T_SWITCH = 362; public static final int T_THROW = 363; public static final int T_TRY = 364; public static final int T_UNSET = 365; public static final int T_UNSET_CAST = 366; public static final int T_USE = 367; public static final int T_VAR = 368; public static final int T_VARIABLE = 369; public static final int T_WHILE = 370; public static final int T_WHITESPACE = 371; public static final int T_XOR_EQUAL = 372; public static final int T_FUNC_C = 373; public static final int T_CLASS_C = 374; private static final IntMap _reservedMap = new IntMap(); private static final IniDefinitions _iniDefinitions = new IniDefinitions(); public String []getLoadedExtensions() { return new String[] { "tokenizer" }; } /** * Returns the default php.ini values. */ public IniDefinitions getIniDefinitions() { return _iniDefinitions; } public static Value highlight_file(Env env, StringValue filename, @Optional boolean isReturn) { StringValue v = FileModule.file_get_contents(env, filename, false, null, 0, Integer.MAX_VALUE); if (v == null) return BooleanValue.FALSE; return highlight_string(env, v, isReturn); } public static Value highlight_string(Env env, StringValue s, @Optional boolean isReturn) { try { StringValue sb = isReturn ? env.createUnicodeBuilder() : null; WriteStream out = env.getOut(); Token lexer = new Token(env, s); int token; StringValue topColor = env.createString("#000000"); StringValue lastColor = topColor; highlight(sb, out, "<code>"); highlight(sb, out, "<span style=\"color: #000000\">\n"); while ((token = lexer.nextToken()) >= 0) { StringValue color = getColor(env, token); if (color != null && ! color.equals(lastColor)) { if (! topColor.equals(lastColor)) highlight(sb, out, "</span>"); if (! topColor.equals(color)) highlight(sb, out, "<span style=\"color: " + color + "\">"); lastColor = color; } if (0x20 <= token && token <= 0x7f) { if (sb != null) sb.append((char) token); else out.print((char) token); } else { StringValue lexeme = lexer.getLexeme(); highlight(sb, out, lexeme); } } if (! topColor.equals(lastColor)) highlight(sb, out, "</span>\n"); highlight(sb, out, "</span>\n"); highlight(sb, out, "</code>"); if (sb != null) return sb; else return BooleanValue.TRUE; } catch (IOException e) { throw new QuercusModuleException(e); } } private static void highlight(StringValue sb, WriteStream out, String string) throws IOException { if (sb != null) { sb.append(string); } else { out.print(string); } } private static void highlight(StringValue sb, WriteStream out, StringValue string) throws IOException { if (sb != null) { int len = string.length(); for (int i = 0; i < len; i++) { char ch = string.charAt(i); switch (ch) { case '<': sb.append("<"); break; case '>': sb.append(">"); break; case ' ': sb.append(" "); break; default: sb.append(ch); break; } } } else { int len = string.length(); for (int i = 0; i < len; i++) { char ch = string.charAt(i); switch (ch) { case '<': out.print("<"); break; case '>': out.print(">"); break; case ' ': out.print(" "); break; default: out.print(ch); break; } } } } private static StringValue getColor(Env env, int token) { switch (token) { case T_INLINE_HTML: return env.getIni("highlight.html"); case T_BAD_CHARACTER: case T_CHARACTER: case T_CLOSE_TAG: case T_DNUMBER: case T_END_HEREDOC: case T_FILE: case T_LINE: case T_LNUMBER: case T_OPEN_TAG: case T_OPEN_TAG_WITH_ECHO: case T_STRING: return env.getIni("highlight.default"); case T_COMMENT: case T_DOC_COMMENT: case T_ML_COMMENT: return env.getIni("highlight.comment"); case T_CONSTANT_ENCAPSED_STRING: //case T_STRING: return env.getIni("highlight.string"); case T_ENCAPSED_AND_WHITESPACE: case T_WHITESPACE: return null; default: return env.getIni("highlight.keyword"); } } /** * Parses the string. */ public static ArrayValue token_get_all(Env env, StringValue s) { ArrayValue result = new ArrayValueImpl(); Token lexer = new Token(env, s); int token; while ((token = lexer.nextToken()) >= 0) { if (0x20 <= token && token <= 0x7f) { result.put(env.createString((char) token)); } else { result.put(new ArrayValueImpl() .append(LongValue.create(token)) .append(lexer.getLexeme())); } } return result; } /** * Returns the token name for th egiven token. */ public static String token_name(int token) { switch (token) { case T_ABSTRACT: return "T_ABSTRACT"; case T_AND_EQUAL: return "T_AND_EQUAL"; case T_ARRAY: return "T_ARRAY"; case T_ARRAY_CAST: return "T_ARRAY_CAST"; case T_AS: return "T_AS"; case T_BAD_CHARACTER: return "T_BAD_CHARACTER"; case T_BOOLEAN_AND: return "T_BOOLEAN_AND"; case T_BOOLEAN_OR: return "T_BOOLEAN_OR"; case T_BOOL_CAST: return "T_BOOL_CAST"; case T_BREAK: return "T_BREAK"; case T_CASE: return "T_CASE"; case T_CATCH: return "T_CATCH"; case T_CHARACTER: return "T_CHARACTER"; case T_CLASS: return "T_CLASS"; case T_CLONE: return "T_CLONE"; case T_CLOSE_TAG: return "T_CLOSE_TAG"; case T_COMMENT: return "T_COMMENT"; case T_CONCAT_EQUAL: return "T_CONCAT_EQUAL"; case T_CONST: return "T_CONST"; case T_CONSTANT_ENCAPSED_STRING: return "T_CONSTANT_ENCAPSED_STRING"; case T_CONTINUE: return "T_CONTINUE"; case T_CURLY_OPEN: return "T_CURLY_OPEN"; case T_DEC: return "T_DEC"; case T_DECLARE: return "T_DECLARE"; case T_DEFAULT: return "T_DEFAULT"; case T_DIV_EQUAL: return "T_DIV_EQUAL"; case T_DNUMBER: return "T_DNUMBER"; case T_DOC_COMMENT: return "T_DOC_COMMENT"; case T_DO: return "T_DO"; case T_DOLLAR_OPEN_CURLY_BRACES: return "T_DOLLAR_OPEN_CURLY_BRACES"; case T_DOUBLE_ARROW: return "T_DOUBLE_ARROW"; case T_DOUBLE_CAST: return "T_DOUBLE_CAST"; case T_DOUBLE_COLON: return "T_DOUBLE_COLON"; case T_ECHO: return "T_ECHO"; case T_ELSE: return "T_ELSE"; case T_ELSEIF: return "T_ELSEIF"; case T_EMPTY: return "T_EMPTY"; case T_ENCAPSED_AND_WHITESPACE: return "T_ENCAPSED_AND_WHITESPACE"; case T_ENDDECLARE: return "T_ENDDECLARE"; case T_ENDFOR: return "T_ENDFOR"; case T_ENDFOREACH: return "T_ENDFOREACH"; case T_ENDIF: return "T_ENDIF"; case T_ENDSWITCH: return "T_ENDSWITCH"; case T_ENDWHILE: return "T_ENDWHILE"; case T_END_HEREDOC: return "T_END_HEREDOC"; case T_EVAL: return "T_EVAL"; case T_EXIT: return "T_EXIT"; case T_EXTENDS: return "T_EXTENDS"; case T_FILE: return "T_FILE"; case T_FINAL: return "T_FINAL"; case T_FOR: return "T_FOR"; case T_FOREACH: return "T_FOREACH"; case T_FUNCTION: return "T_FUNCTION"; case T_GLOBAL: return "T_GLOBAL"; case T_HALT_COMPILER: return "T_HALT_COMPILER"; case T_IF: return "T_IF"; case T_IMPLEMENTS: return "T_IMPLEMENTS"; case T_INC: return "T_INC"; case T_INCLUDE: return "T_INCLUDE"; case T_INCLUDE_ONCE: return "T_INCLUDE_ONCE"; case T_INLINE_HTML: return "T_INLINE_HTML"; case T_INSTANCEOF: return "T_INSTANCEOF"; case T_INT_CAST: return "T_INT_CAST"; case T_INTERFACE: return "T_INTERFACE"; case T_ISSET: return "T_ISSET"; case T_IS_EQUAL: return "T_IS_EQUAL"; case T_IS_GREATER_OR_EQUAL: return "T_IS_GREATER_OR_EQUAL"; case T_IS_IDENTICAL: return "T_IS_IDENTICAL"; case T_IS_NOT_EQUAL: return "T_IS_NOT_EQUAL"; case T_IS_NOT_IDENTICAL: return "T_IS_NOT_IDENTICAL"; case T_IS_SMALLER_OR_EQUAL: return "T_IS_SMALLER_OR_EQUAL"; case T_LINE: return "T_LINE"; case T_LIST: return "T_LIST"; case T_LNUMBER: return "T_LNUMBER"; case T_LOGICAL_AND: return "T_LOGICAL_AND"; case T_LOGICAL_OR: return "T_LOGICAL_OR"; case T_LOGICAL_XOR: return "T_LOGICAL_XOR"; case T_MINUS_EQUAL: return "T_MINUS_EQUAL"; case T_ML_COMMENT: return "T_ML_COMMENT"; case T_MOD_EQUAL: return "T_MOD_EQUAL"; case T_MUL_EQUAL: return "T_MUL_EQUAL"; case T_NEW: return "T_NEW"; case T_NUM_STRING: return "T_NUM_STRING"; case T_OBJECT_CAST: return "T_OBJECT_CAST"; case T_OBJECT_OPERATOR: return "T_OBJECT_OPERATOR"; case T_OLD_FUNCTION: return "T_OLD_FUNCTION"; case T_OPEN_TAG: return "T_OPEN_TAG"; case T_OPEN_TAG_WITH_ECHO: return "T_OPEN_TAG_WITH_ECHO"; case T_OR_EQUAL: return "T_OR_EQUAL"; case T_PLUS_EQUAL: return "T_PLUS_EQUAL"; case T_PRINT: return "T_PRINT"; case T_PRIVATE: return "T_PRIVATE"; case T_PUBLIC: return "T_PUBLIC"; case T_PROTECTED: return "T_PROTECTED"; case T_REQUIRE: return "T_REQUIRE"; case T_REQUIRE_ONCE: return "T_REQUIRE_ONCE"; case T_RETURN: return "T_RETURN"; case T_SL: return "T_SL"; case T_SL_EQUAL: return "T_SL_EQUAL"; case T_SR: return "T_SR"; case T_SR_EQUAL: return "T_SR_EQUAL"; case T_START_HEREDOC: return "T_START_HEREDOC"; case T_STATIC: return "T_STATIC"; case T_STRING: return "T_STRING"; case T_STRING_CAST: return "T_STRING_CAST"; case T_STRING_VARNAME: return "T_STRING_VARNAME"; case T_SWITCH: return "T_SWITCH"; case T_THROW: return "T_THROW"; case T_TRY: return "T_TRY"; case T_UNSET: return "T_UNSET"; case T_UNSET_CAST: return "T_UNSET_CAST"; case T_USE: return "T_USE"; case T_VAR: return "T_VAR"; case T_VARIABLE: return "T_VARIABLE"; case T_WHILE: return "T_WHILE"; case T_WHITESPACE: return "T_WHITESPACE"; case T_XOR_EQUAL: return "T_XOR_EQUAL"; case T_FUNC_C: return "T_FUNC_C"; case T_CLASS_C: return "T_CLASS_C"; default: return "UNDEFINED"; } } static class Token { private Env _env; private final StringValue _s; private final int _length; private int _i; private boolean _inPhp; private StringValue _lexeme; Token(Env env, StringValue s) { _env = env; _s = s; _length = s.length(); } int nextToken() { _lexeme = _env.createUnicodeBuilder(); if (! _inPhp) { _inPhp = true; if (parseHtml()) { return T_INLINE_HTML; } } int ch = read(); switch (ch) { case -1: return -1; case ' ': case '\t': case '\r': case '\n': _lexeme.append((char) ch); while (Character.isWhitespace((ch = read()))) { _lexeme.append((char) ch); } unread(); return T_WHITESPACE; case '{': case '}': case ';': case '[': case ']': case ',': case '@': case '(': case ')': return ch; case '&': if ((ch = read()) == '&') { _lexeme.append("&&"); return T_BOOLEAN_AND; } else if (ch == '=') { _lexeme.append("&="); return T_AND_EQUAL; } else { unread(); return '&'; } case '|': if ((ch = read()) == '|') { _lexeme.append("||"); return T_BOOLEAN_OR; } else if (ch == '=') { _lexeme.append("|="); return T_OR_EQUAL; } else { unread(); return '|'; } case '?': if ((ch = read()) == '>') { _lexeme.append("?>"); _inPhp = false; return T_CLOSE_TAG; } else { unread(); return '?'; } case '/': if ((ch = read()) == '/') { _lexeme.append("//"); while ((ch = read()) >= 0 && ch != '\r' && ch != '\n') { _lexeme.append((char) ch); } unread(); return T_COMMENT; } else if (ch == '=') { _lexeme.append("/="); return T_DIV_EQUAL; } else if (ch == '*') { int token = T_COMMENT; _lexeme.append("/*"); if ((ch = read()) == '*') { token = T_DOC_COMMENT; _lexeme.append("*"); } else unread(); while ((ch = read()) >= 0) { _lexeme.append((char) ch); if (ch != '*') { } else if ((ch = read()) == '/') { _lexeme.append((char) ch); return token; } else unread(); } return token; } else { unread(); return '/'; } case '#': _lexeme.append((char) '#'); while ((ch = read()) >= 0 && ch != '\r' && ch != '\n') { _lexeme.append((char) ch); } unread(); return T_COMMENT; case '.': if ((ch = read()) == '=') { _lexeme.append(".="); return T_CONCAT_EQUAL; } else { unread(); return '.'; } case '\'': case '"': case '`': { int end = ch; _lexeme.append((char) ch); while ((ch = read()) >= 0 && ch != end) { _lexeme.append((char) ch); if (ch == '\\') { _lexeme.append((char) read()); } } if (ch > 0) _lexeme.append((char) ch); return T_CONSTANT_ENCAPSED_STRING; } case '-': if ((ch = read()) == '-') { _lexeme.append("--"); return T_DEC; } else if (ch == '=') { _lexeme.append("-="); return T_MINUS_EQUAL; } else if (ch == '>') { _lexeme.append("->"); return T_OBJECT_OPERATOR; } else { unread(); return '-'; } case '+': if ((ch = read()) == '+') { _lexeme.append("++"); return T_INC; } else if (ch == '=') { _lexeme.append("+="); return T_PLUS_EQUAL; } else { unread(); return '+'; } case '>': if ((ch = read()) == '>') { if ((ch = read()) == '=') { _lexeme.append(">>="); return T_SR_EQUAL; } else { unread(); _lexeme.append(">>"); return T_SR; } } else if (ch == '=') { _lexeme.append(">="); return T_IS_GREATER_OR_EQUAL; } else { unread(); return '>'; } case '$': if ((ch = read()) == '{') { _lexeme.append("${"); return T_DOLLAR_OPEN_CURLY_BRACES; } else if (ch == '$') { unread(); return '$'; } else if (Character.isJavaIdentifierStart(ch)) { unread(); _lexeme.append("$"); readIdentifier(); return T_VARIABLE; } else { unread(); return '$'; } case '=': if ((ch = read()) == '=') { if ((ch = read()) == '=') { _lexeme.append("==="); return T_IS_IDENTICAL; } else { unread(); _lexeme.append("=="); return T_IS_EQUAL; } } else if (ch == '>') { _lexeme.append("=>"); return T_DOUBLE_ARROW; } else { unread(); return '='; } case '!': if ((ch = read()) == '=') { if ((ch = read()) == '=') { _lexeme.append("!=="); return T_IS_NOT_IDENTICAL; } else { unread(); _lexeme.append("!="); return T_IS_NOT_EQUAL; } } else { unread(); return '!'; } case ':': if ((ch = read()) == ':') { _lexeme.append("::"); return T_DOUBLE_COLON; } else { unread(); return ':'; } case '<': if ((ch = read()) == '?') { if ((ch = read()) == '=') { _lexeme.append("<?="); return T_OPEN_TAG_WITH_ECHO; } else if (ch != 'p') { unread(); _lexeme.append("<?"); return T_OPEN_TAG; } else if ((ch = read()) != 'h') { unread(); unread(); _lexeme.append("<?"); return T_OPEN_TAG; } else if ((ch = read()) != 'p') { unread(); unread(); unread(); _lexeme.append("<?"); return T_OPEN_TAG; } else { _lexeme.append("<?php"); return T_OPEN_TAG; } } else if (ch == '%') { if ((ch = read()) == '=') { _lexeme.append("<%="); return T_OPEN_TAG_WITH_ECHO; } else { unread(); _lexeme.append("<%"); return T_OPEN_TAG; } } else if (ch == '<') { if ((ch = read()) == '=') { _lexeme.append("<<="); return T_SL_EQUAL; } else if (ch == '<') { _lexeme.append("<<<"); return T_START_HEREDOC; } else { unread(); _lexeme.append("<<"); return T_SL; } } else if (ch == '=') { _lexeme.append("<="); return T_IS_SMALLER_OR_EQUAL; } else if (ch == '>') { _lexeme.append("<>"); return T_IS_NOT_EQUAL; } else { unread(); return '<'; } case '*': if ((ch = read()) == '=') { _lexeme.append("*="); return T_MUL_EQUAL; } else { unread(); return '*'; } case '%': if ((ch = read()) == '=') { _lexeme.append("%="); return T_MOD_EQUAL; } else { unread(); return '%'; } case '^': if ((ch = read()) == '=') { _lexeme.append("^="); return T_XOR_EQUAL; } else { unread(); return '^'; } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': unread(); return parseNumber(); default: if (Character.isJavaIdentifierStart(ch)) { unread(); readIdentifier(); int lexeme = _reservedMap.get(_lexeme.toString().toLowerCase(Locale.ENGLISH)); if (lexeme > 0) return lexeme; return T_STRING; } _lexeme.append((char) ch); return T_BAD_CHARACTER; } } StringValue getLexeme() { return _lexeme; } private boolean parseHtml() { int ch; while ((ch = read()) >= 0) { if (ch != '<') _lexeme.append((char) ch); else if ((ch = read()) == '?' || ch == '%') { unread(); unread(); return _lexeme.length() > 0; } else { _lexeme.append((char) '<'); unread(); } } return _lexeme.length() > 0; } private void readIdentifier() { int ch; while (Character.isJavaIdentifierPart((ch = read()))) { _lexeme.append((char) ch); } unread(); } private int parseNumber() { boolean isInt = false; int ch; while ('0' <= (ch = read()) && ch <= '9' || ch == '.' || ch == 'x' || ch == 'X' || 'a' <= ch && ch <= 'f' || 'A' <= ch && ch <= 'F') { _lexeme.append((char) ch); if ('a' <= ch && ch <= 'f' || 'A' <= ch && ch <= 'f' || ch == 'x' || ch == 'X') isInt = true; } unread(); return T_LNUMBER; } private int read() { if (_i < _length) return _s.charAt(_i++); else { _i++; return -1; } } private void unread() { if (_i <= _length) _i--; } } static { _reservedMap.put("abstract", T_ABSTRACT); _reservedMap.put("array", T_ARRAY); _reservedMap.put("as", T_AS); _reservedMap.put("break", T_BREAK); _reservedMap.put("case", T_CASE); _reservedMap.put("catch", T_CATCH); _reservedMap.put("class", T_CLASS); _reservedMap.put("clone", T_CLONE); _reservedMap.put("const", T_CONST); _reservedMap.put("continue", T_CONTINUE); _reservedMap.put("declare", T_DECLARE); _reservedMap.put("default", T_DEFAULT); _reservedMap.put("do", T_DO); _reservedMap.put("echo", T_ECHO); _reservedMap.put("else", T_ELSE); _reservedMap.put("elseif", T_ELSEIF); _reservedMap.put("empty", T_EMPTY); _reservedMap.put("enddeclare", T_ENDDECLARE); _reservedMap.put("endfor", T_ENDFOR); _reservedMap.put("endforeach", T_ENDFOREACH); _reservedMap.put("endif", T_ENDIF); _reservedMap.put("endswitch", T_ENDSWITCH); _reservedMap.put("eval", T_EVAL); _reservedMap.put("exit", T_EXIT); _reservedMap.put("die", T_EXIT); _reservedMap.put("extends", T_EXTENDS); _reservedMap.put("__FILE__", T_FILE); _reservedMap.put("final", T_FINAL); _reservedMap.put("for", T_FOR); _reservedMap.put("foreach", T_FOREACH); _reservedMap.put("function", T_FUNCTION); _reservedMap.put("cfunction", T_FUNCTION); _reservedMap.put("global", T_GLOBAL); _reservedMap.put("__halt_compiler", T_HALT_COMPILER); _reservedMap.put("if", T_IF); _reservedMap.put("implements", T_IMPLEMENTS); _reservedMap.put("include", T_INCLUDE); _reservedMap.put("include_once", T_INCLUDE_ONCE); _reservedMap.put("instanceof", T_INSTANCEOF); _reservedMap.put("isset", T_ISSET); _reservedMap.put("list", T_LIST); _reservedMap.put("and", T_LOGICAL_AND); _reservedMap.put("or", T_LOGICAL_OR); _reservedMap.put("xor", T_LOGICAL_XOR); _reservedMap.put("new", T_NEW); _reservedMap.put("old_function", T_OLD_FUNCTION); _reservedMap.put("print", T_PRINT); _reservedMap.put("private", T_PRIVATE); _reservedMap.put("public", T_PUBLIC); _reservedMap.put("protected", T_PROTECTED); _reservedMap.put("require", T_REQUIRE); _reservedMap.put("require_once", T_REQUIRE_ONCE); _reservedMap.put("return", T_RETURN); _reservedMap.put("static", T_STATIC); _reservedMap.put("switch", T_SWITCH); _reservedMap.put("throw", T_THROW); _reservedMap.put("try", T_TRY); _reservedMap.put("unset", T_UNSET); _reservedMap.put("var", T_VAR); _reservedMap.put("while", T_WHILE); _reservedMap.put("__FUNCTION__", T_FUNC_C); _reservedMap.put("__CLASS__", T_CLASS_C); } static final IniDefinition INI_HIGHLIGHT_STRING = _iniDefinitions.add("highlight.string", "#DD0000", PHP_INI_ALL); static final IniDefinition INI_HIGHLIGHT_COMMENT = _iniDefinitions.add("highlight.comment", "#FF8000", PHP_INI_ALL); static final IniDefinition INI_HIGHLIGHT_KEYWORD = _iniDefinitions.add("highlight.keyword", "#007700", PHP_INI_ALL); static final IniDefinition INI_HIGHLIGHT_BG = _iniDefinitions.add("highlight.bg", "#ffffff", PHP_INI_ALL); static final IniDefinition INI_HIGHLIGHT_DEFAULT = _iniDefinitions.add("highlight.default", "#0000BB", PHP_INI_ALL); static final IniDefinition INI_HIGHLIGHT_HTML = _iniDefinitions.add("highlight.html", "#000000", PHP_INI_ALL); }