📄 token.java
字号:
/* * Copyright 1999-2002,2004,2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.sun.org.apache.xerces.internal.impl.xpath.regex;import java.util.Vector;import java.util.Hashtable;/** * This class represents a node in parse tree. * * @xerces.internal * * @version $Id: Token.java,v 1.2.6.1 2005/09/06 11:46:35 neerajbj Exp $ */class Token implements java.io.Serializable { private static final long serialVersionUID = 4049923761862293040L; static final boolean COUNTTOKENS = true; static int tokens = 0; static final int CHAR = 0; // Literal char static final int DOT = 11; // . static final int CONCAT = 1; // XY static final int UNION = 2; // X|Y|Z static final int CLOSURE = 3; // X* static final int RANGE = 4; // [a-zA-Z] etc. static final int NRANGE = 5; // [^a-zA-Z] etc. static final int PAREN = 6; // (X) or (?:X) static final int EMPTY = 7; // static final int ANCHOR = 8; // ^ $ \b \B \< \> \A \Z \z static final int NONGREEDYCLOSURE = 9; // *? +? static final int STRING = 10; // strings static final int BACKREFERENCE = 12; // back references static final int LOOKAHEAD = 20; // (?=...) static final int NEGATIVELOOKAHEAD = 21; // (?!...) static final int LOOKBEHIND = 22; // (?<=...) static final int NEGATIVELOOKBEHIND = 23; // (?<!...) static final int INDEPENDENT = 24; // (?>...) static final int MODIFIERGROUP = 25; // (?ims-ims:...) static final int CONDITION = 26; // (?(...)yes|no) static final int UTF16_MAX = 0x10ffff; int type; static Token token_dot; static Token token_0to9; static Token token_wordchars; static Token token_not_0to9; static Token token_not_wordchars; static Token token_spaces; static Token token_not_spaces; static Token token_empty; static Token token_linebeginning; static Token token_linebeginning2; static Token token_lineend; static Token token_stringbeginning; static Token token_stringend; static Token token_stringend2; static Token token_wordedge; static Token token_not_wordedge; static Token token_wordbeginning; static Token token_wordend; static { Token.token_empty = new Token(Token.EMPTY); Token.token_linebeginning = Token.createAnchor('^'); Token.token_linebeginning2 = Token.createAnchor('@'); Token.token_lineend = Token.createAnchor('$'); Token.token_stringbeginning = Token.createAnchor('A'); Token.token_stringend = Token.createAnchor('z'); Token.token_stringend2 = Token.createAnchor('Z'); Token.token_wordedge = Token.createAnchor('b'); Token.token_not_wordedge = Token.createAnchor('B'); Token.token_wordbeginning = Token.createAnchor('<'); Token.token_wordend = Token.createAnchor('>'); Token.token_dot = new Token(Token.DOT); Token.token_0to9 = Token.createRange(); Token.token_0to9.addRange('0', '9'); Token.token_wordchars = Token.createRange(); Token.token_wordchars.addRange('0', '9'); Token.token_wordchars.addRange('A', 'Z'); Token.token_wordchars.addRange('_', '_'); Token.token_wordchars.addRange('a', 'z'); Token.token_spaces = Token.createRange(); Token.token_spaces.addRange('\t', '\t'); Token.token_spaces.addRange('\n', '\n'); Token.token_spaces.addRange('\f', '\f'); Token.token_spaces.addRange('\r', '\r'); Token.token_spaces.addRange(' ', ' '); Token.token_not_0to9 = Token.complementRanges(Token.token_0to9); Token.token_not_wordchars = Token.complementRanges(Token.token_wordchars); Token.token_not_spaces = Token.complementRanges(Token.token_spaces); } static Token.ParenToken createLook(int type, Token child) { if (COUNTTOKENS) Token.tokens ++; return new Token.ParenToken(type, child, 0); } static Token.ParenToken createParen(Token child, int pnumber) { if (COUNTTOKENS) Token.tokens ++; return new Token.ParenToken(Token.PAREN, child, pnumber); } static Token.ClosureToken createClosure(Token tok) { if (COUNTTOKENS) Token.tokens ++; return new Token.ClosureToken(Token.CLOSURE, tok); } static Token.ClosureToken createNGClosure(Token tok) { if (COUNTTOKENS) Token.tokens ++; return new Token.ClosureToken(Token.NONGREEDYCLOSURE, tok); } static Token.ConcatToken createConcat(Token tok1, Token tok2) { if (COUNTTOKENS) Token.tokens ++; return new Token.ConcatToken(tok1, tok2); } static Token.UnionToken createConcat() { if (COUNTTOKENS) Token.tokens ++; return new Token.UnionToken(Token.CONCAT); // *** It is not a bug. } static Token.UnionToken createUnion() { if (COUNTTOKENS) Token.tokens ++; return new Token.UnionToken(Token.UNION); } static Token createEmpty() { return Token.token_empty; } static RangeToken createRange() { if (COUNTTOKENS) Token.tokens ++; return new RangeToken(Token.RANGE); } static RangeToken createNRange() { if (COUNTTOKENS) Token.tokens ++; return new RangeToken(Token.NRANGE); } static Token.CharToken createChar(int ch) { if (COUNTTOKENS) Token.tokens ++; return new Token.CharToken(Token.CHAR, ch); } static private Token.CharToken createAnchor(int ch) { if (COUNTTOKENS) Token.tokens ++; return new Token.CharToken(Token.ANCHOR, ch); } static Token.StringToken createBackReference(int refno) { if (COUNTTOKENS) Token.tokens ++; return new Token.StringToken(Token.BACKREFERENCE, null, refno); } static Token.StringToken createString(String str) { if (COUNTTOKENS) Token.tokens ++; return new Token.StringToken(Token.STRING, str, 0); } static Token.ModifierToken createModifierGroup(Token child, int add, int mask) { if (COUNTTOKENS) Token.tokens ++; return new Token.ModifierToken(child, add, mask); } static Token.ConditionToken createCondition(int refno, Token condition, Token yespat, Token nopat) { if (COUNTTOKENS) Token.tokens ++; return new Token.ConditionToken(refno, condition, yespat, nopat); } protected Token(int type) { this.type = type; } /** * A number of children. */ int size() { return 0; } Token getChild(int index) { return null; } void addChild(Token tok) { throw new RuntimeException("Not supported."); } // for RANGE or NRANGE protected void addRange(int start, int end) { throw new RuntimeException("Not supported."); } protected void sortRanges() { throw new RuntimeException("Not supported."); } protected void compactRanges() { throw new RuntimeException("Not supported."); } protected void mergeRanges(Token tok) { throw new RuntimeException("Not supported."); } protected void subtractRanges(Token tok) { throw new RuntimeException("Not supported."); } protected void intersectRanges(Token tok) { throw new RuntimeException("Not supported."); } static Token complementRanges(Token tok) { return RangeToken.complementRanges(tok); } void setMin(int min) { // for CLOSURE } void setMax(int max) { // for CLOSURE } int getMin() { // for CLOSURE return -1; } int getMax() { // for CLOSURE return -1; } int getReferenceNumber() { // for STRING return 0; } String getString() { // for STRING return null; } int getParenNumber() { return 0; } int getChar() { return -1; } public String toString() { return this.toString(0); } public String toString(int options) { return this.type == Token.DOT ? "." : ""; } /** * How many characters are needed? */ final int getMinLength() { switch (this.type) { case CONCAT: int sum = 0; for (int i = 0; i < this.size(); i ++) sum += this.getChild(i).getMinLength(); return sum; case CONDITION: case UNION: if (this.size() == 0) return 0; int ret = this.getChild(0).getMinLength(); for (int i = 1; i < this.size(); i ++) { int min = this.getChild(i).getMinLength(); if (min < ret) ret = min; } return ret; case CLOSURE: case NONGREEDYCLOSURE: if (this.getMin() >= 0) return this.getMin() * this.getChild(0).getMinLength(); return 0; case EMPTY: case ANCHOR: return 0; case DOT: case CHAR: case RANGE: case NRANGE: return 1; case INDEPENDENT: case PAREN: case MODIFIERGROUP: return this.getChild(0).getMinLength(); case BACKREFERENCE: return 0; // ******* case STRING: return this.getString().length(); case LOOKAHEAD: case NEGATIVELOOKAHEAD: case LOOKBEHIND: case NEGATIVELOOKBEHIND: return 0; // ***** Really? default: throw new RuntimeException("Token#getMinLength(): Invalid Type: "+this.type); } } final int getMaxLength() { switch (this.type) { case CONCAT: int sum = 0; for (int i = 0; i < this.size(); i ++) { int d = this.getChild(i).getMaxLength(); if (d < 0) return -1; sum += d; } return sum; case CONDITION: case UNION: if (this.size() == 0) return 0; int ret = this.getChild(0).getMaxLength(); for (int i = 1; ret >= 0 && i < this.size(); i ++) { int max = this.getChild(i).getMaxLength(); if (max < 0) { // infinity ret = -1; break; } if (max > ret) ret = max; } return ret; case CLOSURE: case NONGREEDYCLOSURE: if (this.getMax() >= 0) // When this.child.getMaxLength() < 0, // this returns minus value return this.getMax() * this.getChild(0).getMaxLength(); return -1; case EMPTY: case ANCHOR: return 0; case CHAR: return 1; case DOT: case RANGE: case NRANGE: return 2; case INDEPENDENT: case PAREN: case MODIFIERGROUP: return this.getChild(0).getMaxLength(); case BACKREFERENCE: return -1; // ****** case STRING: return this.getString().length(); case LOOKAHEAD: case NEGATIVELOOKAHEAD: case LOOKBEHIND: case NEGATIVELOOKBEHIND: return 0; // ***** Really? default: throw new RuntimeException("Token#getMaxLength(): Invalid Type: "+this.type); } } static final int FC_CONTINUE = 0; static final int FC_TERMINAL = 1; static final int FC_ANY = 2; private static final boolean isSet(int options, int flag) { return (options & flag) == flag; } final int analyzeFirstCharacter(RangeToken result, int options) { switch (this.type) { case CONCAT: int ret = FC_CONTINUE; for (int i = 0; i < this.size(); i ++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -