@Override protected void compileCallNode(CallNode node) { addOpcode(OPCode.CALL); node.unsetAddrList.add(codeLength, node.target); addAbsAddr(0); /*dummy addr.*/ }
@Override protected final void addCompileString(byte[]bytes, int p, int mbLength, int byteLength, boolean ignoreCase) { int op = selectStrOpcode(mbLength, byteLength, ignoreCase); addOpcode(op); if (op == OPCode.EXACTMBN) addLength(mbLength); if (isNeedStrLenOpExact(op)) { if (op == OPCode.EXACTN_IC || op == OPCode.EXACTN_IC_SB) { addLength(byteLength); } else { addLength(byteLength / mbLength); } } if (Config.USE_STRING_TEMPLATES && opTemplated(op)) { addInt(templateNum); addInt(p); addTemplate(bytes); } else { addBytes(bytes, p, byteLength); } }
private void compileRangeRepeatNode(QuantifierNode qn, int targetLen, int emptyInfo) { regex.requireStack = true; int numRepeat = regex.numRepeat; addOpcode(qn.greedy ? OPCode.REPEAT : OPCode.REPEAT_NG); addMemNum(numRepeat); /* OP_REPEAT ID */ regex.numRepeat++; addRelAddr(targetLen + OPSize.REPEAT_INC); entryRepeatRange(numRepeat, qn.lower, qn.upper); compileTreeEmptyCheck(qn.target, emptyInfo); if ((Config.USE_SUBEXP_CALL && regex.numCall > 0) || qn.isInRepeat()) { addOpcode(qn.greedy ? OPCode.REPEAT_INC_SG : OPCode.REPEAT_INC_NG_SG); } else { addOpcode(qn.greedy ? OPCode.REPEAT_INC : OPCode.REPEAT_INC_NG); } addMemNum(numRepeat); /* OP_REPEAT ID */ }
private void addOpcodeRelAddr(int opcode, int addr) { addOpcode(opcode); addRelAddr(addr); }
int tlen = compileLengthTree(qn.target); compileTreeNTimes(qn.target, qn.lower); if (qn.nextHeadExact != null && !cknOn(ckn)) { if (isMultiline(regex.options)) { addOpcode(OPCode.ANYCHAR_ML_STAR_PEEK_NEXT); } else { addOpcode(OPCode.ANYCHAR_STAR_PEEK_NEXT); if (cknOn(ckn)) { addStateCheckNum(ckn); addBytes(sn.bytes, sn.p, 1); return; } else { if (isMultiline(regex.options)) { if (cknOn(ckn)) { addOpcode(OPCode.STATE_CHECK_ANYCHAR_ML_STAR); } else { addOpcode(OPCode.ANYCHAR_ML_STAR); if (cknOn(ckn)) { addOpcode(OPCode.STATE_CHECK_ANYCHAR_STAR); } else { addOpcode(OPCode.ANYCHAR_STAR); if (cknOn(ckn)) { addStateCheckNum(ckn);
if (Config.USE_SUBEXP_CALL && node.isCalled()) { regex.requireStack = true; addOpcode(OPCode.CALL); node.callAddr = codeLength + OPSize.ABSADDR + OPSize.JUMP; node.setAddrFixed(); addAbsAddr(node.callAddr); len = compileLengthTree(node.target); len += OPSize.MEMORY_START_PUSH + OPSize.RETURN; if (bsAt(regex.btMemEnd, node.regNum)) { addOpcodeRelAddr(OPCode.JUMP, len); addOpcode(OPCode.MEMORY_START_PUSH); } else { addOpcode(OPCode.MEMORY_START); addMemNum(node.regNum); compileTree(node.target); addOpcode(node.isRecursion() ? OPCode.MEMORY_END_PUSH_REC : OPCode.MEMORY_END_PUSH); } else { addOpcode(node.isRecursion() ? OPCode.MEMORY_END_REC : OPCode.MEMORY_END); addMemNum(node.regNum); addOpcode(OPCode.RETURN); } else if (Config.USE_SUBEXP_CALL && node.isRecursion()) { // USE_SUBEXP_CALL if (bsAt(regex.btMemEnd, node.regNum)) { addOpcode(OPCode.MEMORY_END_PUSH_REC); } else {
int tlen = compileLengthTree(qn.target); compileTreeNTimes(qn.target, qn.lower); if (qn.nextHeadExact != null) { if (isMultiline(regex.options)) { addOpcode(OPCode.ANYCHAR_ML_STAR_PEEK_NEXT); } else { addOpcode(OPCode.ANYCHAR_STAR_PEEK_NEXT); addBytes(sn.bytes, sn.p, 1); return; } else { if (isMultiline(regex.options)) { addOpcode(OPCode.ANYCHAR_ML_STAR); } else { addOpcode(OPCode.ANYCHAR_STAR); if (qn.greedy) { if (qn.headExact != null) { addOpcodeRelAddr(OPCode.JUMP, OPSize.PUSH_OR_JUMP_EXACT1); } else if (qn.nextHeadExact != null) { addOpcodeRelAddr(OPCode.JUMP, OPSize.PUSH_IF_PEEK_NEXT); } else { addOpcodeRelAddr(OPCode.JUMP, OPSize.PUSH); addOpcodeRelAddr(OPCode.JUMP, OPSize.JUMP); compileTreeNTimes(qn.target, qn.lower);
case AnchorType.BEGIN_BUF: addOpcode(OPCode.BEGIN_BUF); break; case AnchorType.END_BUF: addOpcode(OPCode.END_BUF); break; case AnchorType.BEGIN_LINE: addOpcode(OPCode.BEGIN_LINE); break; case AnchorType.END_LINE: addOpcode(OPCode.END_LINE); break; case AnchorType.SEMI_END_BUF: addOpcode(OPCode.SEMI_END_BUF); break; case AnchorType.BEGIN_POSITION: addOpcode(OPCode.BEGIN_POSITION); break; addOpcode(OPCode.ASCII_WORD_BOUND); } else { addOpcode(OPCode.WORD_BOUND); addOpcode(OPCode.ASCII_NOT_WORD_BOUND); } else { addOpcode(OPCode.NOT_WORD_BOUND); if (Config.USE_WORD_BEGIN_END) { if (node.asciiRange) { addOpcode(OPCode.ASCII_WORD_BEGIN); } else { addOpcode(OPCode.WORD_BEGIN); if (Config.USE_WORD_BEGIN_END) { if (node.asciiRange) { addOpcode(OPCode.ASCII_WORD_END); } else { addOpcode(OPCode.WORD_END); addOpcode(OPCode.KEEP); break;
BackRefNode br = node; if (Config.USE_BACKREF_WITH_LEVEL && br.isNestLevel()) { addOpcode(OPCode.BACKREF_WITH_LEVEL); addOption(regex.options & Option.IGNORECASE); addLength(br.nestLevel); addLength(br.backNum); for (int i=br.backNum-1; i>=0; i--) addMemNum(br.back[i]); return; } else { // USE_BACKREF_AT_LEVEL if (br.backNum == 1) { if (isIgnoreCase(regex.options)) { addOpcode(OPCode.BACKREFN_IC); addMemNum(br.back[0]); } else { switch (br.back[0]) { case 1: addOpcode(OPCode.BACKREF1); break; case 2: addOpcode(OPCode.BACKREF2); break; default: addOpcode(OPCode.BACKREFN); addOpcode(br.back[0]); break; addOpcode(OPCode.BACKREF_MULTI_IC); } else {
private void compileTreeEmptyCheck(Node node, int emptyInfo) { int savedNumNullCheck = regex.numNullCheck; if (emptyInfo != 0) { regex.requireStack = true; addOpcode(OPCode.NULL_CHECK_START); addMemNum(regex.numNullCheck); /* NULL CHECK ID */ regex.numNullCheck++; } compileTree(node); if (emptyInfo != 0) { switch(emptyInfo) { case TargetInfo.IS_EMPTY: addOpcode(OPCode.NULL_CHECK_END); break; case TargetInfo.IS_EMPTY_MEM: addOpcode(OPCode.NULL_CHECK_END_MEMST); break; case TargetInfo.IS_EMPTY_REC: addOpcode(OPCode.NULL_CHECK_END_MEMST_PUSH); break; } // switch addMemNum(savedNumNullCheck); /* NULL CHECK ID */ } }
@Override protected void compileCClassNode(CClassNode cc) { if (cc.mbuf == null) { if (cc.isNot()) { addOpcode(OPCode.CCLASS_NOT); } else { addOpcode(OPCode.CCLASS); } addInts(cc.bs.bits, BitSet.BITSET_SIZE); // add_bitset } else { if (enc.minLength() > 1 || cc.bs.isEmpty()) { if (cc.isNot()) { addOpcode(OPCode.CCLASS_MB_NOT); } else { addOpcode(OPCode.CCLASS_MB); } addMultiByteCClass(cc.mbuf); } else { if (cc.isNot()) { addOpcode(OPCode.CCLASS_MIX_NOT); } else { addOpcode(OPCode.CCLASS_MIX); } // store the bit set and mbuf themself! addInts(cc.bs.bits, BitSet.BITSET_SIZE); // add_bitset addMultiByteCClass(cc.mbuf); } } }
private void addLength(int length) { addInt(length); }
@Override protected void compileCTypeNode(CTypeNode node) { CTypeNode cn = node; int op; switch (cn.ctype) { case CharacterType.WORD: if (cn.not) { if (cn.asciiRange) { op = OPCode.ASCII_NOT_WORD; } else { op = OPCode.NOT_WORD; } } else { if (cn.asciiRange) { op = OPCode.ASCII_WORD; } else { op = OPCode.WORD; } } break; default: newInternalException(PARSER_BUG); return; // not reached } // inner switch addOpcode(op); }
new ArrayCompiler(this).compile(root);
private int compileLengthStringRawNode(StringNode sn) { if (sn.length() <= 0) return 0; return addCompileStringlength(sn.bytes, sn.p, 1 /*sb*/, sn.length(), false); }
int tlen = compileLengthTree(qn.target); compileTreeNTimes(qn.target, qn.lower); if (qn.nextHeadExact != null && !cknOn(ckn)) { if (isMultiline(regex.options)) { addOpcode(OPCode.ANYCHAR_ML_STAR_PEEK_NEXT); } else { addOpcode(OPCode.ANYCHAR_STAR_PEEK_NEXT); if (cknOn(ckn)) { addStateCheckNum(ckn); addBytes(sn.bytes, sn.p, 1); return; } else { if (isMultiline(regex.options)) { if (cknOn(ckn)) { addOpcode(OPCode.STATE_CHECK_ANYCHAR_ML_STAR); } else { addOpcode(OPCode.ANYCHAR_ML_STAR); if (cknOn(ckn)) { addOpcode(OPCode.STATE_CHECK_ANYCHAR_STAR); } else { addOpcode(OPCode.ANYCHAR_STAR); if (cknOn(ckn)) { addStateCheckNum(ckn);
if (Config.USE_SUBEXP_CALL && node.isCalled()) { regex.requireStack = true; addOpcode(OPCode.CALL); node.callAddr = codeLength + OPSize.ABSADDR + OPSize.JUMP; node.setAddrFixed(); addAbsAddr(node.callAddr); len = compileLengthTree(node.target); len += OPSize.MEMORY_START_PUSH + OPSize.RETURN; if (bsAt(regex.btMemEnd, node.regNum)) { addOpcodeRelAddr(OPCode.JUMP, len); addOpcode(OPCode.MEMORY_START_PUSH); } else { addOpcode(OPCode.MEMORY_START); addMemNum(node.regNum); compileTree(node.target); addOpcode(node.isRecursion() ? OPCode.MEMORY_END_PUSH_REC : OPCode.MEMORY_END_PUSH); } else { addOpcode(node.isRecursion() ? OPCode.MEMORY_END_REC : OPCode.MEMORY_END); addMemNum(node.regNum); addOpcode(OPCode.RETURN); } else if (Config.USE_SUBEXP_CALL && node.isRecursion()) { // USE_SUBEXP_CALL if (bsAt(regex.btMemEnd, node.regNum)) { addOpcode(OPCode.MEMORY_END_PUSH_REC); } else {