39 import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode; |
39 import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode; |
40 import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode; |
40 import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode; |
41 import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType; |
41 import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType; |
42 import jdk.nashorn.internal.runtime.regexp.joni.constants.EncloseType; |
42 import jdk.nashorn.internal.runtime.regexp.joni.constants.EncloseType; |
43 import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType; |
43 import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType; |
44 import jdk.nashorn.internal.runtime.regexp.joni.constants.RegexState; |
|
45 import jdk.nashorn.internal.runtime.regexp.joni.constants.StackPopLevel; |
44 import jdk.nashorn.internal.runtime.regexp.joni.constants.StackPopLevel; |
46 import jdk.nashorn.internal.runtime.regexp.joni.constants.TargetInfo; |
45 import jdk.nashorn.internal.runtime.regexp.joni.constants.TargetInfo; |
47 import jdk.nashorn.internal.runtime.regexp.joni.encoding.ObjPtr; |
46 import jdk.nashorn.internal.runtime.regexp.joni.encoding.ObjPtr; |
|
47 import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException; |
|
48 import jdk.nashorn.internal.runtime.regexp.joni.exception.SyntaxException; |
|
49 import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException; |
48 |
50 |
49 final class Analyser extends Parser { |
51 final class Analyser extends Parser { |
50 |
52 |
51 protected Analyser(ScanEnvironment env, char[] chars, int p, int end) { |
53 protected Analyser(ScanEnvironment env, char[] chars, int p, int end) { |
52 super(env, chars, p, end); |
54 super(env, chars, p, end); |
53 } |
55 } |
54 |
56 |
55 protected final void compile() { |
57 protected final void compile() { |
56 regex.state = RegexState.COMPILING; |
|
57 |
|
58 if (Config.DEBUG) { |
58 if (Config.DEBUG) { |
59 Config.log.println(new String(chars, getBegin(), getEnd())); |
59 Config.log.println(new String(chars, getBegin(), getEnd())); |
60 } |
60 } |
61 |
61 |
62 reset(); |
62 reset(); |
113 Config.log.println("stack used: " + regex.stackNeeded); |
113 Config.log.println("stack used: " + regex.stackNeeded); |
114 if (Config.USE_STRING_TEMPLATES) Config.log.print("templates: " + regex.templateNum + "\n"); |
114 if (Config.USE_STRING_TEMPLATES) Config.log.print("templates: " + regex.templateNum + "\n"); |
115 Config.log.println(new ByteCodePrinter(regex).byteCodeListToString()); |
115 Config.log.println(new ByteCodePrinter(regex).byteCodeListToString()); |
116 |
116 |
117 } // DEBUG_COMPILE |
117 } // DEBUG_COMPILE |
118 |
|
119 regex.state = RegexState.NORMAL; |
|
120 } |
118 } |
121 |
119 |
122 private void swap(Node a, Node b) { |
120 private void swap(Node a, Node b) { |
123 a.swap(b); |
121 a.swap(b); |
124 |
122 |
185 switch (node.getType()) { |
183 switch (node.getType()) { |
186 case NodeType.BREF: |
184 case NodeType.BREF: |
187 BackRefNode br = (BackRefNode)node; |
185 BackRefNode br = (BackRefNode)node; |
188 if (br.isRecursion()) break; |
186 if (br.isRecursion()) break; |
189 |
187 |
190 if (br.back[0] > env.numMem) newValueException(ERR_INVALID_BACKREF); |
188 if (br.backRef > env.numMem) { |
191 min = getMinMatchLength(env.memNodes[br.back[0]]); |
189 throw new ValueException(ERR_INVALID_BACKREF); |
192 |
190 } |
193 for (int i=1; i<br.backNum; i++) { |
191 min = getMinMatchLength(env.memNodes[br.backRef]); |
194 if (br.back[i] > env.numMem) newValueException(ERR_INVALID_BACKREF); |
192 |
195 int tmin = getMinMatchLength(env.memNodes[br.back[i]]); |
|
196 if (min > tmin) min = tmin; |
|
197 } |
|
198 break; |
193 break; |
199 |
194 |
200 case NodeType.LIST: |
195 case NodeType.LIST: |
201 ConsAltNode can = (ConsAltNode)node; |
196 ConsAltNode can = (ConsAltNode)node; |
202 do { |
197 do { |
304 if (br.isRecursion()) { |
299 if (br.isRecursion()) { |
305 max = MinMaxLen.INFINITE_DISTANCE; |
300 max = MinMaxLen.INFINITE_DISTANCE; |
306 break; |
301 break; |
307 } |
302 } |
308 |
303 |
309 for (int i=0; i<br.backNum; i++) { |
304 if (br.backRef > env.numMem) { |
310 if (br.back[i] > env.numMem) newValueException(ERR_INVALID_BACKREF); |
305 throw new ValueException(ERR_INVALID_BACKREF); |
311 int tmax = getMaxMatchLength(env.memNodes[br.back[i]]); |
306 } |
312 if (max < tmax) max = tmax; |
307 int tmax = getMaxMatchLength(env.memNodes[br.backRef]); |
313 } |
308 if (max < tmax) max = tmax; |
314 break; |
309 break; |
315 |
310 |
316 case NodeType.QTFR: |
311 case NodeType.QTFR: |
317 QuantifierNode qn = (QuantifierNode)node; |
312 QuantifierNode qn = (QuantifierNode)node; |
318 if (qn.upper != 0) { |
313 if (qn.upper != 0) { |
710 switch(returnCode) { |
703 switch(returnCode) { |
711 case 0: |
704 case 0: |
712 an.charLength = len; |
705 an.charLength = len; |
713 break; |
706 break; |
714 case GET_CHAR_LEN_VARLEN: |
707 case GET_CHAR_LEN_VARLEN: |
715 newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN); |
708 throw new SyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN); |
716 break; |
|
717 case GET_CHAR_LEN_TOP_ALT_VARLEN: |
709 case GET_CHAR_LEN_TOP_ALT_VARLEN: |
718 if (syntax.differentLengthAltLookBehind()) { |
710 if (syntax.differentLengthAltLookBehind()) { |
719 return divideLookBehindAlternatives(node); |
711 return divideLookBehindAlternatives(node); |
720 } else { |
712 } else { |
721 newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN); |
713 throw new SyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN); |
722 } |
714 } |
723 } |
715 } |
724 return node; |
716 return node; |
725 } |
717 } |
726 |
718 |
953 case NodeType.CANY: |
945 case NodeType.CANY: |
954 break; |
946 break; |
955 |
947 |
956 case NodeType.BREF: |
948 case NodeType.BREF: |
957 BackRefNode br = (BackRefNode)node; |
949 BackRefNode br = (BackRefNode)node; |
958 for (int i=0; i<br.backNum; i++) { |
950 if (br.backRef > env.numMem) { |
959 if (br.back[i] > env.numMem) newValueException(ERR_INVALID_BACKREF); |
951 throw new ValueException(ERR_INVALID_BACKREF); |
960 env.backrefedMem = bsOnAt(env.backrefedMem, br.back[i]); |
952 } |
961 env.btMemStart = bsOnAt(env.btMemStart, br.back[i]); |
953 env.backrefedMem = bsOnAt(env.backrefedMem, br.backRef); |
962 ((EncloseNode)env.memNodes[br.back[i]]).setMemBackrefed(); |
954 env.btMemStart = bsOnAt(env.btMemStart, br.backRef); |
963 } |
955 ((EncloseNode)env.memNodes[br.backRef]).setMemBackrefed(); |
964 break; |
956 break; |
965 |
957 |
966 case NodeType.QTFR: |
958 case NodeType.QTFR: |
967 QuantifierNode qn = (QuantifierNode)node; |
959 QuantifierNode qn = (QuantifierNode)node; |
968 Node target = qn.target; |
960 Node target = qn.target; |
1062 case AnchorType.PREC_READ_NOT: |
1054 case AnchorType.PREC_READ_NOT: |
1063 setupTree(an.target, (state | IN_NOT)); |
1055 setupTree(an.target, (state | IN_NOT)); |
1064 break; |
1056 break; |
1065 |
1057 |
1066 case AnchorType.LOOK_BEHIND: |
1058 case AnchorType.LOOK_BEHIND: |
1067 if (checkTypeTree(an.target, NodeType.ALLOWED_IN_LB, EncloseType.ALLOWED_IN_LB, AnchorType.ALLOWED_IN_LB)) newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN); |
1059 if (checkTypeTree(an.target, NodeType.ALLOWED_IN_LB, EncloseType.ALLOWED_IN_LB, AnchorType.ALLOWED_IN_LB)) { |
|
1060 throw new SyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN); |
|
1061 } |
1068 node = setupLookBehind(node); |
1062 node = setupLookBehind(node); |
1069 if (node.getType() != NodeType.ANCHOR) continue restart; |
1063 if (node.getType() != NodeType.ANCHOR) continue restart; |
1070 setupTree(((AnchorNode)node).target, state); |
1064 setupTree(((AnchorNode)node).target, state); |
1071 break; |
1065 break; |
1072 |
1066 |
1073 case AnchorType.LOOK_BEHIND_NOT: |
1067 case AnchorType.LOOK_BEHIND_NOT: |
1074 if (checkTypeTree(an.target, NodeType.ALLOWED_IN_LB, EncloseType.ALLOWED_IN_LB, AnchorType.ALLOWED_IN_LB)) newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN); |
1068 if (checkTypeTree(an.target, NodeType.ALLOWED_IN_LB, EncloseType.ALLOWED_IN_LB, AnchorType.ALLOWED_IN_LB)) { |
|
1069 throw new SyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN); |
|
1070 } |
1075 node = setupLookBehind(node); |
1071 node = setupLookBehind(node); |
1076 if (node.getType() != NodeType.ANCHOR) continue restart; |
1072 if (node.getType() != NodeType.ANCHOR) continue restart; |
1077 setupTree(((AnchorNode)node).target, (state | IN_NOT)); |
1073 setupTree(((AnchorNode)node).target, (state | IN_NOT)); |
1078 break; |
1074 break; |
1079 |
1075 |
1216 break; |
1212 break; |
1217 } |
1213 } |
1218 |
1214 |
1219 Node[]nodes = oenv.scanEnv.memNodes; |
1215 Node[]nodes = oenv.scanEnv.memNodes; |
1220 |
1216 |
1221 int min = getMinMatchLength(nodes[br.back[0]]); |
1217 int min = getMinMatchLength(nodes[br.backRef]); |
1222 int max = getMaxMatchLength(nodes[br.back[0]]); |
1218 int max = getMaxMatchLength(nodes[br.backRef]); |
1223 |
1219 |
1224 for (int i=1; i<br.backNum; i++) { |
|
1225 int tmin = getMinMatchLength(nodes[br.back[i]]); |
|
1226 int tmax = getMaxMatchLength(nodes[br.back[i]]); |
|
1227 if (min > tmin) min = tmin; |
|
1228 if (max < tmax) max = tmax; |
|
1229 } |
|
1230 opt.length.set(min, max); |
1220 opt.length.set(min, max); |
1231 break; |
1221 break; |
1232 } |
1222 } |
1233 |
1223 |
1234 |
1224 |