/* * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package jdk.nashorn.internal.runtime.regexp.joni; import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.Node; import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode; import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType; import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages; import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException; import jdk.nashorn.internal.runtime.regexp.joni.exception.SyntaxException; abstract class Compiler implements ErrorMessages { protected final Analyser analyser; protected final Regex regex; protected Compiler(final Analyser analyser) { this.analyser = analyser; this.regex = analyser.regex; } final void compile() { prepare(); compileTree(analyser.root); finish(); } protected abstract void prepare(); protected abstract void finish(); protected abstract void compileAltNode(ConsAltNode node); private void compileStringRawNode(final StringNode sn) { if (sn.length() <= 0) { return; } addCompileString(sn.chars, sn.p, sn.length(), false); } private void compileStringNode(final StringNode node) { final StringNode sn = node; if (sn.length() <= 0) { return; } final boolean ambig = sn.isAmbig(); int p, prev; p = prev = sn.p; final int end = sn.end; final char[] chars = sn.chars; p++; int slen = 1; while (p < end) { slen++; p++; } addCompileString(chars, prev, slen, ambig); } protected abstract void addCompileString(char[] chars, int p, int strLength, boolean ignoreCase); protected abstract void compileCClassNode(CClassNode node); protected abstract void compileAnyCharNode(); protected abstract void compileBackrefNode(BackRefNode node); protected abstract void compileNonCECQuantifierNode(QuantifierNode node); protected abstract void compileOptionNode(EncloseNode node); protected abstract void compileEncloseNode(EncloseNode node); protected abstract void compileAnchorNode(AnchorNode node); 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 } protected final void compileTreeNTimes(final Node node, final int n) { for (int i=0; i<n; i++) { compileTree(node); } } protected void newSyntaxException(final String message) { throw new SyntaxException(message); } protected void newInternalException(final String message) { throw new InternalException(message); } }