private Node setupLookBehind(final Node node) { final AnchorNode an = (AnchorNode)node; final int len = getCharLengthTree(an.target); switch (returnCode) { case 0: an.charLength = len; break; case GET_CHAR_LEN_VARLEN: throw new SyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN); case GET_CHAR_LEN_TOP_ALT_VARLEN: if (syntax.differentLengthAltLookBehind()) { return divideLookBehindAlternatives(node); } throw new SyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN); default: break; } return node; }
private Node setupLookBehind(Node node) { AnchorNode an = (AnchorNode)node; int len = getCharLengthTree(an.target); switch(returnCode) { case 0: an.charLength = len; break; case GET_CHAR_LEN_VARLEN: throw new SyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN); case GET_CHAR_LEN_TOP_ALT_VARLEN: if (syntax.differentLengthAltLookBehind()) { return divideLookBehindAlternatives(node); } else { throw new SyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN); } } return node; }
private int compileLengthAnchorNode(final AnchorNode node) { int tlen; if (node.target != null) { tlen = compileLengthTree(node.target); } else { tlen = 0; } int len; switch (node.type) { case AnchorType.PREC_READ: len = OPSize.PUSH_POS + tlen + OPSize.POP_POS; break; case AnchorType.PREC_READ_NOT: len = OPSize.PUSH_POS_NOT + tlen + OPSize.FAIL_POS; break; case AnchorType.LOOK_BEHIND: len = OPSize.LOOK_BEHIND + tlen; break; case AnchorType.LOOK_BEHIND_NOT: len = OPSize.PUSH_LOOK_BEHIND_NOT + tlen + OPSize.FAIL_LOOK_BEHIND_NOT; break; default: len = OPSize.OPCODE; break; } // switch return len; }
private Node divideLookBehindAlternatives(final Node nodep) { Node node = nodep; final AnchorNode an = (AnchorNode)node; final int anchorType = an.type; Node head = an.target; Node np = ((ConsAltNode)head).car; swap(node, head); final Node tmp = node; node = head; head = tmp; ((ConsAltNode)node).setCar(head); ((AnchorNode)head).setTarget(np); np = node; while ((np = ((ConsAltNode)np).cdr) != null) { final AnchorNode insert = new AnchorNode(anchorType); insert.setTarget(((ConsAltNode)np).car); ((ConsAltNode)np).setCar(insert); } if (anchorType == AnchorType.LOOK_BEHIND_NOT) { np = node; do { ((ConsAltNode)np).toListNode(); /* alt -> list */ } while ((np = ((ConsAltNode)np).cdr) != null); } return node; }
private int compileLengthAnchorNode(AnchorNode node) { int tlen; if (node.target != null) { tlen = compileLengthTree(node.target); } else { tlen = 0; } int len; switch (node.type) { case AnchorType.PREC_READ: len = OPSize.PUSH_POS + tlen + OPSize.POP_POS; break; case AnchorType.PREC_READ_NOT: len = OPSize.PUSH_POS_NOT + tlen + OPSize.FAIL_POS; break; case AnchorType.LOOK_BEHIND: len = OPSize.LOOK_BEHIND + tlen; break; case AnchorType.LOOK_BEHIND_NOT: len = OPSize.PUSH_LOOK_BEHIND_NOT + tlen + OPSize.FAIL_LOOK_BEHIND_NOT; break; default: len = OPSize.OPCODE; break; } // switch return len; }
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; }
private Node divideLookBehindAlternatives(Node node) { AnchorNode an = (AnchorNode)node; int anchorType = an.type; Node head = an.target; Node np = ((ConsAltNode)head).car; swap(node, head); Node tmp = node; node = head; head = tmp; ((ConsAltNode)node).setCar(head); ((AnchorNode)head).setTarget(np); np = node; while ((np = ((ConsAltNode)np).cdr) != null) { AnchorNode insert = new AnchorNode(anchorType); insert.setTarget(((ConsAltNode)np).car); ((ConsAltNode)np).setCar(insert); } if (anchorType == AnchorType.LOOK_BEHIND_NOT) { np = node; do { ((ConsAltNode)np).toListNode(); /* alt -> list */ } while ((np = ((ConsAltNode)np).cdr) != null); } return node; }
@Override protected void compileAnchorNode(final AnchorNode node) { int len; int n; switch (node.type) { 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; case AnchorType.WORD_BOUND: addOpcode(OPCode.WORD_BOUND); break; case AnchorType.NOT_WORD_BOUND: addOpcode(OPCode.NOT_WORD_BOUND); break; case AnchorType.WORD_BEGIN: if (Config.USE_WORD_BEGIN_END) { addOpcode(OPCode.WORD_BEGIN); } break; case AnchorType.WORD_END: if (Config.USE_WORD_BEGIN_END) { addOpcode(OPCode.WORD_END); } break; case AnchorType.PREC_READ: addOpcode(OPCode.PUSH_POS); compileTree(node.target); addOpcode(OPCode.POP_POS); break; case AnchorType.PREC_READ_NOT: len = compileLengthTree(node.target); addOpcodeRelAddr(OPCode.PUSH_POS_NOT, len + OPSize.FAIL_POS); compileTree(node.target); addOpcode(OPCode.FAIL_POS); break; case AnchorType.LOOK_BEHIND: addOpcode(OPCode.LOOK_BEHIND); if (node.charLength < 0) { n = analyser.getCharLengthTree(node.target); if (analyser.returnCode != 0) { newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN); } } else { n = node.charLength; } addLength(n); compileTree(node.target); break; case AnchorType.LOOK_BEHIND_NOT: len = compileLengthTree(node.target); addOpcodeRelAddr(OPCode.PUSH_LOOK_BEHIND_NOT, len + OPSize.FAIL_LOOK_BEHIND_NOT); if (node.charLength < 0) { n = analyser.getCharLengthTree(node.target); if (analyser.returnCode != 0) { newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN); } } else { n = node.charLength; } addLength(n); compileTree(node.target); addOpcode(OPCode.FAIL_LOOK_BEHIND_NOT); break; default: newInternalException(ERR_PARSER_BUG); } // switch }
private int compileLengthTree(final Node node) { int len = 0; switch (node.getType()) { case NodeType.LIST: ConsAltNode lin = (ConsAltNode)node; do { len += compileLengthTree(lin.car); } while ((lin = lin.cdr) != null); break; case NodeType.ALT: ConsAltNode aln = (ConsAltNode)node; int n = 0; do { len += compileLengthTree(aln.car); n++; } while ((aln = aln.cdr) != null); len += (OPSize.PUSH + OPSize.JUMP) * (n - 1); break; case NodeType.STR: final StringNode sn = (StringNode)node; if (sn.isRaw()) { len = compileLengthStringRawNode(sn); } else { len = compileLengthStringNode(sn); } break; case NodeType.CCLASS: len = compileLengthCClassNode((CClassNode)node); break; case NodeType.CTYPE: case NodeType.CANY: len = OPSize.OPCODE; break; case NodeType.BREF: final BackRefNode br = (BackRefNode)node; len = ((!isIgnoreCase(regex.options) && br.backRef <= 2) ? OPSize.OPCODE : (OPSize.OPCODE + OPSize.MEMNUM)); break; case NodeType.QTFR: len = compileNonCECLengthQuantifierNode((QuantifierNode)node); break; case NodeType.ENCLOSE: len = compileLengthEncloseNode((EncloseNode)node); break; case NodeType.ANCHOR: len = compileLengthAnchorNode((AnchorNode)node); break; default: newInternalException(ERR_PARSER_BUG); } //switch return len; }
protected final void compileTree(final Node node) { switch (node.getType()) { case NodeType.LIST: ConsAltNode lin = (ConsAltNode)node; do { compileTree(lin.car); } while ((lin = lin.cdr) != null); break; case NodeType.ALT: compileAltNode((ConsAltNode)node); break; case NodeType.STR: final StringNode sn = (StringNode)node; if (sn.isRaw()) { compileStringRawNode(sn); } else { compileStringNode(sn); } break; case NodeType.CCLASS: compileCClassNode((CClassNode)node); break; case NodeType.CANY: compileAnyCharNode(); break; case NodeType.BREF: compileBackrefNode((BackRefNode)node); break; case NodeType.QTFR: compileNonCECQuantifierNode((QuantifierNode)node); break; case NodeType.ENCLOSE: final EncloseNode enode = (EncloseNode)node; if (enode.isOption()) { compileOptionNode(enode); } else { compileEncloseNode(enode); } break; case NodeType.ANCHOR: compileAnchorNode((AnchorNode)node); break; default: // undefined node type newInternalException(ERR_PARSER_BUG); } // switch }
private boolean checkTypeTree(final Node node, final int typeMask, final int encloseMask, final 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: final EncloseNode en = (EncloseNode)node; if ((en.type & encloseMask) == 0) { return true; } invalid = checkTypeTree(en.target, typeMask, encloseMask, anchorMask); break; case NodeType.ANCHOR: final 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; }