private Node parseBranch(final TokenType term) { Node node = parseExp(term); if (token.type == TokenType.EOT || token.type == term || token.type == TokenType.ALT) { return node; } final ConsAltNode top = ConsAltNode.newListNode(node, null); ConsAltNode t = top; while (token.type != TokenType.EOT && token.type != term && token.type != TokenType.ALT) { node = parseExp(term); if (node.getType() == NodeType.LIST) { t.setCdr((ConsAltNode)node); while (((ConsAltNode)node).cdr != null ) { node = ((ConsAltNode)node).cdr; } t = ((ConsAltNode)node); } else { t.setCdr(ConsAltNode.newListNode(node, null)); t = t.cdr; } } return top; }
private Node parseBranch(TokenType term) { Node node = parseExp(term); if (token.type == TokenType.EOT || token.type == term || token.type == TokenType.ALT) { return node; } else { ConsAltNode top = ConsAltNode.newListNode(node, null); ConsAltNode t = top; while (token.type != TokenType.EOT && token.type != term && token.type != TokenType.ALT) { node = parseExp(term); if (node.getType() == NodeType.LIST) { t.setCdr((ConsAltNode)node); while (((ConsAltNode)node).cdr != null ) node = ((ConsAltNode)node).cdr; t = ((ConsAltNode)node); } else { t.setCdr(ConsAltNode.newListNode(node, null)); t = t.cdr; } } return top; } }
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 int compileNonCECLengthQuantifierNode(final QuantifierNode qn) { final boolean infinite = isRepeatInfinite(qn.upper); final int emptyInfo = qn.targetEmptyInfo; final int tlen = compileLengthTree(qn.target); /* anychar repeat */ if (qn.target.getType() == NodeType.CANY) { if (qn.greedy && infinite) { if (qn.nextHeadExact != null) { return OPSize.ANYCHAR_STAR_PEEK_NEXT + tlen * qn.lower; } return OPSize.ANYCHAR_STAR + tlen * qn.lower; } } int modTLen = 0; if (emptyInfo != 0) { modTLen = tlen + (OPSize.NULL_CHECK_START + OPSize.NULL_CHECK_END); } else { modTLen = tlen; } int len; if (infinite && (qn.lower <= 1 || tlen * qn.lower <= QUANTIFIER_EXPAND_LIMIT_SIZE)) { if (qn.lower == 1 && tlen > QUANTIFIER_EXPAND_LIMIT_SIZE) { len = OPSize.JUMP; } else { len = tlen * qn.lower; } if (qn.greedy) { if (qn.headExact != null) { len += OPSize.PUSH_OR_JUMP_EXACT1 + modTLen + OPSize.JUMP; } else if (qn.nextHeadExact != null) { len += OPSize.PUSH_IF_PEEK_NEXT + modTLen + OPSize.JUMP; } else { len += OPSize.PUSH + modTLen + OPSize.JUMP; } } else { len += OPSize.JUMP + modTLen + OPSize.PUSH; } } else if (qn.upper == 0 && qn.isRefered) { /* /(?<n>..){0}/ */ len = OPSize.JUMP + tlen; } else if (!infinite && qn.greedy && (qn.upper == 1 || (tlen + OPSize.PUSH) * qn.upper <= QUANTIFIER_EXPAND_LIMIT_SIZE )) { len = tlen * qn.lower; len += (OPSize.PUSH + tlen) * (qn.upper - qn.lower); } else if (!qn.greedy && qn.upper == 1 && qn.lower == 0) { /* '??' */ len = OPSize.PUSH + OPSize.JUMP + tlen; } else { len = OPSize.REPEAT_INC + modTLen + OPSize.OPCODE + OPSize.RELADDR + OPSize.MEMNUM; } return len; }
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 int quantifiersMemoryInfo(final Node node) { int info = 0; switch(node.getType()) { case NodeType.LIST: case NodeType.ALT: ConsAltNode can = (ConsAltNode)node; do { final int v = quantifiersMemoryInfo(can.car); if (v > info) { info = v; } } while ((can = can.cdr) != null); break; case NodeType.QTFR: final QuantifierNode qn = (QuantifierNode)node; if (qn.upper != 0) { info = quantifiersMemoryInfo(qn.target); } break; case NodeType.ENCLOSE: final EncloseNode en = (EncloseNode)node; switch (en.type) { case EncloseType.MEMORY: return TargetInfo.IS_EMPTY_MEM; case EncloseType.OPTION: case EncloseNode.STOP_BACKTRACK: info = quantifiersMemoryInfo(en.target); break; default: break; } // inner switch break; case NodeType.BREF: case NodeType.STR: case NodeType.CTYPE: case NodeType.CCLASS: case NodeType.CANY: case NodeType.ANCHOR: default: break; } // switch return info; }
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; }