@Override protected void compileOptionNode(final EncloseNode node) { final int prev = regex.options; if (isDynamic(prev ^ node.option)) { addOpcodeOption(OPCode.SET_OPTION_PUSH, node.option); addOpcodeOption(OPCode.SET_OPTION, prev); addOpcode(OPCode.FAIL); } regex.options = node.option; compileTree(node.target); regex.options = prev; if (isDynamic(prev ^ node.option)) { addOpcodeOption(OPCode.SET_OPTION, prev); } }
@Override protected void compileOptionNode(EncloseNode node) { int prev = regex.options; if (isDynamic(prev ^ node.option)) { addOpcodeOption(OPCode.SET_OPTION_PUSH, node.option); addOpcodeOption(OPCode.SET_OPTION, prev); addOpcode(OPCode.FAIL); } regex.options = node.option; compileTree(node.target); regex.options = prev; if (isDynamic(prev ^ node.option)) { addOpcodeOption(OPCode.SET_OPTION, prev); } }
private int compileLengthOptionNode(final EncloseNode node) { final int prev = regex.options; regex.options = node.option; final int tlen = compileLengthTree(node.target); regex.options = prev; if (isDynamic(prev ^ node.option)) { return OPSize.SET_OPTION_PUSH + OPSize.SET_OPTION + OPSize.FAIL + tlen + OPSize.SET_OPTION; } return tlen; }
private int compileLengthEncloseNode(final EncloseNode node) { if (node.isOption()) { return compileLengthOptionNode(node); } int tlen; if (node.target != null) { tlen = compileLengthTree(node.target); } else { tlen = 0; } int len; switch (node.type) { case EncloseType.MEMORY: if (bsAt(regex.btMemStart, node.regNum)) { len = OPSize.MEMORY_START_PUSH; } else { len = OPSize.MEMORY_START; } len += tlen + (bsAt(regex.btMemEnd, node.regNum) ? OPSize.MEMORY_END_PUSH : OPSize.MEMORY_END); break; case EncloseType.STOP_BACKTRACK: if (node.isStopBtSimpleRepeat()) { final QuantifierNode qn = (QuantifierNode)node.target; tlen = compileLengthTree(qn.target); len = tlen * qn.lower + OPSize.PUSH + tlen + OPSize.POP + OPSize.JUMP; } else { len = OPSize.PUSH_STOP_BT + tlen + OPSize.POP_STOP_BT; } break; default: newInternalException(ERR_PARSER_BUG); return 0; // not reached } // switch return len; }
private Node parseExpRepeat(final Node targetp, final boolean group) { Node target = targetp; while (token.type == TokenType.OP_REPEAT || token.type == TokenType.INTERVAL) { // repeat: if (target.isInvalidQuantifier()) { throw new SyntaxException(ERR_TARGET_OF_REPEAT_OPERATOR_INVALID); } final QuantifierNode qtfr = new QuantifierNode(token.getRepeatLower(), token.getRepeatUpper(), token.type == TokenType.INTERVAL); qtfr.greedy = token.getRepeatGreedy(); final int ret = qtfr.setQuantifier(target, group, env, chars, getBegin(), getEnd()); Node qn = qtfr; if (token.getRepeatPossessive()) { final EncloseNode en = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose en.setTarget(qn); qn = en; } if (ret == 0) { target = qn; } else if (ret == 2) { /* split case: /abc+/ */ target = ConsAltNode.newListNode(target, null); final ConsAltNode tmp = ((ConsAltNode)target).setCdr(ConsAltNode.newListNode(qn, null)); fetchToken(); return parseExpRepeatForCar(target, tmp, group); } fetchToken(); // goto re_entry } return target; }
private int compileLengthOptionNode(EncloseNode node) { int prev = regex.options; regex.options = node.option; int tlen = compileLengthTree(node.target); regex.options = prev; if (isDynamic(prev ^ node.option)) { return OPSize.SET_OPTION_PUSH + OPSize.SET_OPTION + OPSize.FAIL + tlen + OPSize.SET_OPTION; } else { return tlen; } }
private int compileLengthEncloseNode(EncloseNode node) { if (node.isOption()) { return compileLengthOptionNode(node); } int tlen; if (node.target != null) { tlen = compileLengthTree(node.target); } else { tlen = 0; } int len; switch (node.type) { case EncloseType.MEMORY: if (bsAt(regex.btMemStart, node.regNum)) { len = OPSize.MEMORY_START_PUSH; } else { len = OPSize.MEMORY_START; } len += tlen + (bsAt(regex.btMemEnd, node.regNum) ? OPSize.MEMORY_END_PUSH : OPSize.MEMORY_END); break; case EncloseType.STOP_BACKTRACK: if (node.isStopBtSimpleRepeat()) { QuantifierNode qn = (QuantifierNode)node.target; tlen = compileLengthTree(qn.target); len = tlen * qn.lower + OPSize.PUSH + tlen + OPSize.POP + OPSize.JUMP; } else { len = OPSize.PUSH_STOP_BT + tlen + OPSize.POP_STOP_BT; } break; default: newInternalException(ERR_PARSER_BUG); return 0; // not reached } // switch return len; }
private Node parseExpRepeat(Node target, boolean group) { while (token.type == TokenType.OP_REPEAT || token.type == TokenType.INTERVAL) { // repeat: if (target.isInvalidQuantifier()) { throw new SyntaxException(ERR_TARGET_OF_REPEAT_OPERATOR_INVALID); } QuantifierNode qtfr = new QuantifierNode(token.getRepeatLower(), token.getRepeatUpper(), token.type == TokenType.INTERVAL); qtfr.greedy = token.getRepeatGreedy(); int ret = qtfr.setQuantifier(target, group, env, chars, getBegin(), getEnd()); Node qn = qtfr; if (token.getRepeatPossessive()) { EncloseNode en = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose en.setTarget(qn); qn = en; } if (ret == 0) { target = qn; } else if (ret == 2) { /* split case: /abc+/ */ target = ConsAltNode.newListNode(target, null); ConsAltNode tmp = ((ConsAltNode)target).setCdr(ConsAltNode.newListNode(qn, null)); fetchToken(); return parseExpRepeatForCar(target, tmp, group); } fetchToken(); // goto re_entry } return target; }
private boolean checkTypeTree(Node node, int typeMask, int encloseMask, int anchorMask) { if ((node.getType2Bit() & typeMask) == 0) return true; boolean invalid = false; switch(node.getType()) { case NodeType.LIST: case NodeType.ALT: ConsAltNode can = (ConsAltNode)node; do { invalid = checkTypeTree(can.car, typeMask, encloseMask, anchorMask); } while (!invalid && (can = can.cdr) != null); break; case NodeType.QTFR: invalid = checkTypeTree(((QuantifierNode)node).target, typeMask, encloseMask, anchorMask); break; case NodeType.ENCLOSE: EncloseNode en = (EncloseNode)node; if ((en.type & encloseMask) == 0) return true; invalid = checkTypeTree(en.target, typeMask, encloseMask, anchorMask); break; case NodeType.ANCHOR: AnchorNode an = (AnchorNode)node; if ((an.type & anchorMask) == 0) return true; if (an.target != null) invalid = checkTypeTree(an.target, typeMask, encloseMask, anchorMask); break; default: break; } // switch return invalid; }