📄 regexpnode.java
字号:
// // match functions // @Override int match(StringValue string, int length, int offset, RegexpState state) { RegexpNode next = _next; RegexpNode node = _node; int min = _min; int max = _max; int i; int tail; for (i = 0; i < min; i++) { tail = node.match(string, length, offset + i, state); if (tail < 0) return tail; } for (; i <= max; i++) { tail = next.match(string, length, offset + i, state); if (tail >= 0) return tail; if (node.match(string, length, offset + i, state) < 0) { return -1; } } return -1; } @Override public String toString() { return "CharUngreedyLoop[" + _min + ", " + _max + ", " + _node + ", " + _next + "]"; } } static class Concat extends RegexpNode { private final RegexpNode _head; private RegexpNode _next; Concat(RegexpNode head, RegexpNode next) { if (head == null || next == null) throw new NullPointerException(); _head = head; _next = next; } @Override RegexpNode concat(RegexpNode next) { _next = _next.concat(next); return this; } // // optim functions // @Override int minLength() { return _head.minLength() + _next.minLength(); } @Override int firstChar() { return _head.firstChar(); } @Override boolean []firstSet(boolean []firstSet) { firstSet = _head.firstSet(firstSet); if (_head.isNullable()) firstSet = _next.firstSet(firstSet); return firstSet; } @Override String prefix() { return _head.prefix(); } @Override int match(StringValue string, int length, int offset, RegexpState state) { offset = _head.match(string, length, offset, state); if (offset < 0) return -1; else return _next.match(string, length, offset, state); } @Override public String toString() { return "Concat[" + _head + ", " + _next + "]"; } } static class ConditionalHead extends RegexpNode { private RegexpNode _first; private RegexpNode _second; private RegexpNode _tail; private final int _group; ConditionalHead(int group) { _group = group; _tail = new ConditionalTail(this); } void setFirst(RegexpNode first) { _first = first; } void setSecond(RegexpNode second) { _second = second; } void setTail(RegexpNode tail) { _tail = tail; } @Override RegexpNode getTail() { return _tail; } @Override RegexpNode concat(RegexpNode next) { _tail.concat(next); return this; } @Override RegexpNode createLoop(Regcomp parser, int min, int max) { return _tail.createLoop(parser, min, max); } /** * Create an or expression */ @Override RegexpNode createOr(RegexpNode node) { return _tail.createOr(node); } @Override int match(StringValue string, int length, int offset, RegexpState state) { int begin = state.getBegin(_group); int end = state.getEnd(_group); if (_group <= state.getLength() && begin <= end) { return _first.match(string, length, offset, state); } else if (_second != null) return _second.match(string, length, offset, state); else return _tail.match(string, length, offset, state); } } static class ConditionalTail extends RegexpNode { private RegexpNode _head; private RegexpNode _next; ConditionalTail(ConditionalHead head) { _next = N_END; _head = head; head.setTail(this); } @Override RegexpNode getHead() { return _head; } @Override RegexpNode concat(RegexpNode next) { if (_next != null) _next = _next.concat(next); else _next = next; return _head; } @Override RegexpNode createLoop(Regcomp parser, int min, int max) { LoopHead head = new LoopHead(parser, _head, min, max); _next = _next.concat(head.getTail()); return head; } @Override RegexpNode createLoopUngreedy(Regcomp parser, int min, int max) { LoopHeadUngreedy head = new LoopHeadUngreedy(parser, _head, min, max); _next = _next.concat(head.getTail()); return head; } /** * Create an or expression */ @Override RegexpNode createOr(RegexpNode node) { _next = _next.createOr(node); return getHead(); } @Override int match(StringValue string, int length, int offset, RegexpState state) { return _next.match(string, length, offset, state); } } static class End extends RegexpNode { @Override RegexpNode concat(RegexpNode next) { return next; } @Override int match(StringValue string, int length, int offset, RegexpState state) { return offset; } } static class Group extends RegexpNode { private final RegexpNode _node; private final int _group; Group(RegexpNode node, int group) { _node = node.getHead(); _group = group; } @Override int match(StringValue string, int length, int offset, RegexpState state) { int oldBegin = state.getBegin(_group); state.setBegin(_group, offset); int tail = _node.match(string, length, offset, state); if (tail >= 0) { state.setEnd(_group, tail); return tail; } else { state.setBegin(_group, oldBegin); return -1; } } } static class GroupHead extends RegexpNode { private RegexpNode _node; private RegexpNode _tail; private final int _group; GroupHead(int group) { _group = group; _tail = new GroupTail(group, this); } void setNode(RegexpNode node) { _node = node.getHead(); // php/4eh1 if (_node == this) _node = _tail; } @Override RegexpNode getTail() { return _tail; } @Override RegexpNode concat(RegexpNode next) { _tail.concat(next); return this; } @Override RegexpNode createLoop(Regcomp parser, int min, int max) { return _tail.createLoop(parser, min, max); } @Override RegexpNode createLoopUngreedy(Regcomp parser, int min, int max) { return _tail.createLoopUngreedy(parser, min, max); } @Override int minLength() { return _node.minLength(); } @Override int firstChar() { return _node.firstChar(); } @Override boolean []firstSet(boolean []firstSet) { return _node.firstSet(firstSet); } @Override String prefix() { return _node.prefix(); } @Override int match(StringValue string, int length, int offset, RegexpState state) { int oldBegin = state.getBegin(_group); state.setBegin(_group, offset); int tail = _node.match(string, length, offset, state); if (tail >= 0) return tail; else { state.setBegin(_group, oldBegin); return tail; } } @Override public String toString() { return "GroupHead[" + _group + ", " + _node + "]"; } } static class GroupTail extends RegexpNode { private RegexpNode _head; private RegexpNode _next; private final int _group; private GroupTail(int group, GroupHead head) { _next = N_END; _head = head; _group = group; } @Override RegexpNode getHead() { return _head; } @Override RegexpNode concat(RegexpNode next) { if (_next != null) _next = _next.concat(next); else _next = next; return _head; } @Override RegexpNode createLoop(Regcomp parser, int min, int max) { LoopHead head = new LoopHead(parser, _head, min, max); _next = head.getTail(); return head; } @Override RegexpNode createLoopUngreedy(Regcomp parser, int min, int max) { LoopHeadUngreedy head = new LoopHeadUngreedy(parser, _head, min, max); _next = head.getTail(); return head; } /** * Create an or expression */ @Override RegexpNode createOr(RegexpNode node) { _next = _next.createOr(node); return getHead(); } @Override int minLength() { return _next.minLength(); } @Override int match(StringValue string, int length, int offset, RegexpState state) { int oldEnd = state.getEnd(_group); int oldLength = state.getLength(); if (_group > 0) { state.setEnd(_group, offset); if (oldLength < _group) state.setLength(_group); } int tail = _next.match(string, length, offset, state); if (tail < 0) { state.setEnd(_group, oldEnd); state.setLength(oldLength); return -1; } else { return tail; } } @Override public String toString() { return "GroupTail[" + _group + ", " + _next + "]"; } } static class GroupRef extends RegexpNode { private final int _group; GroupRef(int group) { _group = group; } @Override int match(StringValue string, int length, int offset, RegexpState state) { if (state.getLength() < _group) return -1; int groupBegin = state.getBegin(_group); int groupLength = state.getEnd(_group) - groupBegin; if (string.regionMatches(offset, string, groupBegin, groupLength)) { return offset + groupLength; } else return -1; } } static class Lookahead extends RegexpNode { private final RegexpNode _head; Lookahead(RegexpNode head) { _head = head; } @Override int match(StringValue string, int length, int offset, RegexpState state) { if (_head.match(string, length, offset, state) >= 0) return offset; else return -1; } } static class NotLookahead extends RegexpNode { private final RegexpNode _head; NotLookahead(RegexpNode head) { _head = head; } @Override int match(StringValue string, int length, int offset, RegexpState state) { if (_head.match(string, length, offset, state) < 0) return offset; else return -1; } } static class Lookbehind extends RegexpNode { private final RegexpNode _head; Lookbehind(RegexpNode head) { _head = head.getHead(); } @Override int match(StringValue string, int strlen, int offset, RegexpState state) { int length = _head.minLength(); if (offset < length) return -1; else if (_head.match(string, strlen, offset - length, state) >= 0) return offset; else return -1; } } static class NotLookbehind extends RegexpNode { private final RegexpNode _head; NotLookbehind(RegexpNode head) { _head = head; } @Override int match(StringValue string, int strlen, int offset, RegexpState state) { int length = _head.minLength(); if (offset < length) return offset; else if (_head.match(string, strlen, offset - length, state) < 0) return offset; else return -1; } } /** * A nullable node can match an empty string. */ abstract static class NullableNode extends RegexpNode { @Override boolean isNullable() { return true; } } static class LoopHead extends RegexpNode { private final int _index; final RegexpNode _node; private final RegexpNode _tail; private int _min; private int _max; LoopHead(Regcomp parser, RegexpNode node, int min, int max) { _index = parser.nextLoopIndex(); _tail = new LoopTail(_index, this); _node = node.concat(_tail).getHead(); _min = min; _max = max; } @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()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -