📄 regexpnode.java
字号:
{ return _min * _node.minLength() + _tail.minLength(); } @Override boolean []firstSet(boolean []firstSet) { firstSet = _node.firstSet(firstSet); if (_min > 0 && ! _node.isNullable()) return firstSet; firstSet = _tail.firstSet(firstSet); return firstSet; } // // match functions // @Override int match(StringValue string, int strlen, int offset, RegexpState state) { state._loopCount[_index] = 0; RegexpNode node = _node; int min = _min; int i; for (i = 0; i < min - 1; i++) { state._loopCount[_index] = i; offset = node.match(string, strlen, offset, state); if (offset < 0) return offset; } state._loopCount[_index] = i; state._loopOffset[_index] = offset; int tail = node.match(string, strlen, offset, state); if (tail >= 0) return tail; else if (state._loopCount[_index] < _min) return tail; else return _tail.match(string, strlen, offset, state); } @Override public String toString() { return "LoopHead[" + _min + ", " + _max + ", " + _node + "]"; } } static class LoopTail extends RegexpNode { private final int _index; private LoopHead _head; private RegexpNode _next; LoopTail(int index, LoopHead head) { _index = index; _head = head; _next = N_END; } @Override RegexpNode getHead() { return _head; } @Override RegexpNode concat(RegexpNode next) { if (_next != null) _next = _next.concat(next); else _next = next; if (_next == this) throw new IllegalStateException(); return this; } // // match functions // @Override int match(StringValue string, int strlen, int offset, RegexpState state) { int oldCount = state._loopCount[_index]; if (oldCount + 1 < _head._min) return offset; else if (oldCount + 1 < _head._max) { int oldOffset = state._loopOffset[_index]; if (oldOffset != offset) { state._loopCount[_index] = oldCount + 1; state._loopOffset[_index] = offset; int tail = _head._node.match(string, strlen, offset, state); if (tail >= 0) return tail; state._loopCount[_index] = oldCount; state._loopOffset[_index] = oldOffset; } } return _next.match(string, strlen, offset, state); } @Override public String toString() { return "LoopTail[" + _next + "]"; } } static class LoopHeadUngreedy extends RegexpNode { private final int _index; final RegexpNode _node; private final LoopTailUngreedy _tail; private int _min; private int _max; LoopHeadUngreedy(Regcomp parser, RegexpNode node, int min, int max) { _index = parser.nextLoopIndex(); _min = min; _max = max; _tail = new LoopTailUngreedy(_index, this); _node = node.getTail().concat(_tail).getHead(); } @Override RegexpNode getTail() { return _tail; } @Override RegexpNode concat(RegexpNode next) { _tail.concat(next); return this; } @Override RegexpNode createLoop(Regcomp parser, int min, int max) { if (min == 0 && max == 1) { _min = 0; return this; } else return new LoopHead(parser, this, min, max); } @Override int minLength() { return _min * _node.minLength() + _tail.minLength(); } // // match functions // @Override int match(StringValue string, int strlen, int offset, RegexpState state) { state._loopCount[_index] = 0; RegexpNode node = _node; int min = _min; for (int i = 0; i < min; i++) { state._loopCount[_index] = i; state._loopOffset[_index] = offset; offset = node.match(string, strlen, offset, state); if (offset < 0) return -1; } int tail = _tail._next.match(string, strlen, offset, state); if (tail >= 0) return tail; if (min < _max) { state._loopCount[_index] = min; state._loopOffset[_index] = offset; return node.match(string, strlen, offset, state); } else return -1; } @Override public String toString() { return "LoopHeadUngreedy[" + _min + ", " + _max + ", " + _node + "]"; } } static class LoopTailUngreedy extends RegexpNode { private final int _index; private LoopHeadUngreedy _head; private RegexpNode _next; LoopTailUngreedy(int index, LoopHeadUngreedy head) { _index = index; _head = head; _next = N_END; } @Override RegexpNode getHead() { return _head; } @Override RegexpNode concat(RegexpNode next) { if (_next != null) _next = _next.concat(next); else _next = next; if (_next == this) throw new IllegalStateException(); return this; } // // match functions // @Override int match(StringValue string, int strlen, int offset, RegexpState state) { int i = state._loopCount[_index]; int oldOffset = state._loopOffset[_index]; if (i < _head._min) return offset; if (offset == oldOffset) return -1; int tail = _next.match(string, strlen, offset, state); if (tail >= 0) return tail; if (i + 1 < _head._max) { state._loopCount[_index] = i + 1; state._loopOffset[_index] = offset; tail = _head._node.match(string, strlen, offset, state); state._loopCount[_index] = i; state._loopOffset[_index] = oldOffset; return tail; } else return -1; } @Override public String toString() { return "LoopTailUngreedy[" + _next + "]"; } } static class Or extends RegexpNode { private RegexpNode _left; private Or _right; private Or(RegexpNode left, Or right) { _left = left; _right = right; } static Or create(RegexpNode left, RegexpNode right) { if (left instanceof Or) return ((Or) left).append(right); else if (right instanceof Or) return new Or(left, (Or) right); else return new Or(left, new Or(right, null)); } private Or append(RegexpNode right) { if (_right != null) _right = _right.append(right); else if (right instanceof Or) _right = (Or) right; else _right = new Or(right, null); return this; } @Override int minLength() { if (_right != null) return Math.min(_left.minLength(), _right.minLength()); else return _left.minLength(); } @Override int firstChar() { if (_right == null) return _left.firstChar(); int leftChar = _left.firstChar(); int rightChar = _right.firstChar(); if (leftChar == rightChar) return leftChar; else return -1; } @Override boolean []firstSet(boolean []firstSet) { if (_right == null) return _left.firstSet(firstSet); firstSet = _left.firstSet(firstSet); firstSet = _right.firstSet(firstSet); return firstSet; } @Override int match(StringValue string, int strlen, int offset, RegexpState state) { for (Or ptr = this; ptr != null; ptr = ptr._right) { int value = ptr._left.match(string, strlen, offset, state); if (value >= 0) return value; } return -1; } } static class PossessiveLoop extends RegexpNode { private final RegexpNode _node; private RegexpNode _next = N_END; private int _min; private int _max; PossessiveLoop(RegexpNode node, int min, int max) { _node = node.getHead(); _min = min; _max = max; } @Override RegexpNode concat(RegexpNode next) { if (next == null) throw new NullPointerException(); if (_next != null) _next = _next.concat(next); else _next = next; return this; } @Override RegexpNode createLoop(Regcomp parser, int min, int max) { if (min == 0 && max == 1) { _min = 0; return this; } else return new LoopHead(parser, this, min, max); } // // match functions // @Override int match(StringValue string, int strlen, int offset, RegexpState state) { RegexpNode node = _node; int min = _min; int max = _max; int i; for (i = 0; i < min; i++) { offset = node.match(string, strlen, offset, state); if (offset < 0) return -1; } for (; i < max; i++) { int tail = node.match(string, strlen, offset, state); if (tail < 0 || tail == offset) return _next.match(string, strlen, offset, state); offset = tail; } return _next.match(string, strlen, offset, state); } @Override public String toString() { return "PossessiveLoop[" + _min + ", " + _max + ", " + _node + ", " + _next + "]"; } } static final PropC PROP_C = new PropC(); static final PropNotC PROP_NOT_C = new PropNotC(); static final Prop PROP_Cc = new Prop(Character.CONTROL); static final PropNot PROP_NOT_Cc = new PropNot(Character.CONTROL); static final Prop PROP_Cf = new Prop(Character.FORMAT); static final PropNot PROP_NOT_Cf = new PropNot(Character.FORMAT); static final Prop PROP_Cn = new Prop(Character.UNASSIGNED); static final PropNot PROP_NOT_Cn = new PropNot(Character.UNASSIGNED); static final Prop PROP_Co = new Prop(Character.PRIVATE_USE); static final PropNot PROP_NOT_Co = new PropNot(Character.PRIVATE_USE); static final Prop PROP_Cs = new Prop(Character.SURROGATE); static final PropNot PROP_NOT_Cs = new PropNot(Character.SURROGATE); static final PropL PROP_L = new PropL(); static final PropNotL PROP_NOT_L = new PropNotL(); static final Prop PROP_Ll = new Prop(Character.LOWERCASE_LETTER); static final PropNot PROP_NOT_Ll = new PropNot(Character.LOWERCASE_LETTER); static final Prop PROP_Lm = new Prop(Character.MODIFIER_LETTER); static final PropNot PROP_NOT_Lm = new PropNot(Character.MODIFIER_LETTER); static final Prop PROP_Lo = new Prop(Character.OTHER_LETTER); static final PropNot PROP_NOT_Lo = new PropNot(Character.OTHER_LETTER); static final Prop PROP_Lt = new Prop(Character.TITLECASE_LETTER); static final PropNot PROP_NOT_Lt = new PropNot(Character.TITLECASE_LETTER); static final Prop PROP_Lu = new Prop(Character.UPPERCASE_LETTER); static final PropNot PROP_NOT_Lu = new PropNot(Character.UPPERCASE_LETTER); static final PropM PROP_M = new PropM(); static final PropNotM PROP_NOT_M = new PropNotM(); static final Prop PROP_Mc = new Prop(Character.COMBINING_SPACING_MARK); static final PropNot PROP_NOT_Mc = new PropNot(Character.COMBINING_SPACING_MARK); static final Prop PROP_Me = new Prop(Character.ENCLOSING_MARK); static final PropNot PROP_NOT_Me = new PropNot(Character.ENCLOSING_MARK); static final Prop PROP_Mn = new Prop(Character.NON_SPACING_MARK); static final PropNot PROP_NOT_Mn = new PropNot(Character.NON_SPACING_MARK); static final PropN PROP_N = new PropN(); static final PropNotN PROP_NOT_N = new PropNotN(); static final Prop PROP_Nd = new Prop(Character.DECIMAL_DIGIT_NUMBER); static final PropNot PROP_NOT_Nd = new PropNot(Character.DECIMAL_DIGIT_NUMBER); static final Prop PROP_Nl = new Prop(Character.LETTER_NUMBER); static final PropNot PROP_NOT_Nl = new PropNot(Character.LETTER_NUMBER); static final Prop PROP_No = new Prop(Character.OTHER_NUMBER); static final PropNot PROP_NOT_No = new PropNot(Character.OTHER_NUMBER); static final PropP PROP_P = new PropP(); static final PropNotP PROP_NOT_P = new PropNotP(); static final Prop PROP_Pc = new Prop(Character.CONNECTOR_PUNCTUATION); static final PropNot PROP_NOT_Pc = new PropNot(Character.CONNECTOR_PUNCTUATION); static final Prop PROP_Pd = new Prop(Character.DASH_PUNCTUATION); static final PropNot PROP_NOT_Pd = new PropNot(Character.DASH_PUNCTUATION); static final Prop PROP_Pe = new Prop(Character.END_PUNCTUATION); static final PropNot PROP_NOT_Pe = new PropNot(Character.END_PUNCTUATION); static final Prop PROP_Pf = new Prop(Character.FINAL_QUOTE_PUNCTUATION); static final PropNot PROP_NOT_Pf = new PropNot(Character.FINAL_QUOTE_PUNCTUATION); static final Prop PROP_Pi = new Prop(Character.INITIAL_QUOTE_PUNCTUATION); static final PropNot PROP_NOT_Pi = new PropNot(Character.INITIAL_QUOTE_PUNCTUATION); static final Prop PROP_Po = new Prop(Character.OTHER_PUNCTUATION); static final PropNot PROP_NOT_Po = new PropNot(Character.OTHER_PUNCTUATION); static final Prop PROP_Ps = new Prop(Character.START_PUNCTUATION); static final PropNot PROP_NOT_Ps = new PropNot(Character.START_PUNCTUATION); static final PropS PROP_S = new PropS(); static final PropNotS PROP_NOT_S = new PropNotS(); static final Prop PROP_Sc = new Prop(Character.CURRENCY_SYMBOL); static final PropNot PROP_NOT_Sc = new PropNot(Character.CURRENCY_SYMBOL); static final Prop PROP_Sk = new Prop(Character.MODIFIER_SYMBOL); static final PropNot PROP_NOT_Sk = new PropNot(Character.MODIFIER_SYMBOL); static final Prop PROP_Sm = new Prop(Character.MATH_SYMBOL); static final PropNot PROP_NOT_Sm = new PropNot(Character.MATH_SYMBOL); static final Prop PROP_So = new Prop(Character.OTHER_SYMBOL); static final PropNot PROP_NOT_So = new PropNot(Character.OTHER_SYMBOL); static final PropZ PROP_Z = new PropZ(); static final PropNotZ PROP_NOT_Z = new PropNotZ(); static final Prop PROP_Zl = new Prop(Character.LINE_SEPARATOR); static final PropNot PROP_NOT_Zl = new PropNot(Character.LINE_SEPARATOR); static final Prop PROP_Zp = new Prop(Character.PARAGRAPH_SEPARATOR); static final PropNot PROP_NOT_Zp = new PropNot(Character.PARAGRAPH_SEPARATOR); static final Prop PROP_Zs = new Prop(Character.SPACE_SEPARATOR); static final PropNot PROP_NOT_Zs = new PropNot(Character.SPACE_SEPARATOR); private static class Prop extends AbstractCharNode { private final int _category; Prop(int category) { _category = category; } @Override int match(StringValue string, int strlen, int offset, RegexpState state) { if (offset < strlen) { char ch = string.charAt(offset); if (Character.getType(ch) == _category) return offset + 1; } return -1; } } private static class PropNot extends AbstractCharNode { private final int _category; PropNot(int category) { _category = category; } @Override int match(StringValue string, int strlen, int offset, RegexpState state) { if (offset < strlen) { char ch = string.charAt(offset); if (Character.getType(ch) != _category) return offset + 1; } return -1; } } static class PropC extends AbstractCharNode { @Override int match(StringValue string, int strlen, int offset, RegexpState state) { if (offset < strlen) { char ch = string.charAt(offset); int value = Character.getType(ch); if (value == Character.CONTROL || value == Character.FORMAT || value == Character.UNASSIGNED || value == Character.PRIVATE_USE || value == Character.SURROGATE) { return offset + 1; } } return -1; } } static class PropNotC extends AbstractCharNode { @Override int match(StringValue string, int strlen, int offset, RegexpState state) { if (offset < strlen) { char ch = string.charAt(offset); int value = Character.getType(ch); if (! (value == Character.CONTROL || value == Character.FORMAT || value == Character.UNASSIGNED
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -