1 /* 2 * Permission is hereby granted, free of charge, to any person obtaining a copy of 3 * this software and associated documentation files (the "Software"), to deal in 4 * the Software without restriction, including without limitation the rights to 5 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 6 * of the Software, and to permit persons to whom the Software is furnished to do 7 * so, subject to the following conditions: 8 * 9 * The above copyright notice and this permission notice shall be included in all 10 * copies or substantial portions of the Software. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 * SOFTWARE. 19 */ 20 package jdk.nashorn.internal.runtime.regexp.joni; 21 22 import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode; 23 import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode; 24 import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode; 25 import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode; 26 import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode; 27 import jdk.nashorn.internal.runtime.regexp.joni.ast.Node; 28 import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode; 29 import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode; 30 import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType; 31 import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages; 32 import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException; 33 import jdk.nashorn.internal.runtime.regexp.joni.exception.SyntaxException; 34 35 abstract class Compiler implements ErrorMessages { 36 protected final Analyser analyser; 37 protected final Regex regex; 38 Compiler(final Analyser analyser)39 protected Compiler(final Analyser analyser) { 40 this.analyser = analyser; 41 this.regex = analyser.regex; 42 } 43 compile()44 final void compile() { 45 prepare(); 46 compileTree(analyser.root); 47 finish(); 48 } 49 prepare()50 protected abstract void prepare(); finish()51 protected abstract void finish(); 52 compileAltNode(ConsAltNode node)53 protected abstract void compileAltNode(ConsAltNode node); 54 compileStringRawNode(final StringNode sn)55 private void compileStringRawNode(final StringNode sn) { 56 if (sn.length() <= 0) { 57 return; 58 } 59 addCompileString(sn.chars, sn.p, sn.length(), false); 60 } 61 compileStringNode(final StringNode node)62 private void compileStringNode(final StringNode node) { 63 final StringNode sn = node; 64 if (sn.length() <= 0) { 65 return; 66 } 67 68 final boolean ambig = sn.isAmbig(); 69 70 int p, prev; 71 p = prev = sn.p; 72 final int end = sn.end; 73 final char[] chars = sn.chars; 74 p++; 75 int slen = 1; 76 77 while (p < end) { 78 slen++; 79 p++; 80 } 81 addCompileString(chars, prev, slen, ambig); 82 } 83 addCompileString(char[] chars, int p, int strLength, boolean ignoreCase)84 protected abstract void addCompileString(char[] chars, int p, int strLength, boolean ignoreCase); 85 compileCClassNode(CClassNode node)86 protected abstract void compileCClassNode(CClassNode node); compileAnyCharNode()87 protected abstract void compileAnyCharNode(); compileBackrefNode(BackRefNode node)88 protected abstract void compileBackrefNode(BackRefNode node); compileNonCECQuantifierNode(QuantifierNode node)89 protected abstract void compileNonCECQuantifierNode(QuantifierNode node); compileOptionNode(EncloseNode node)90 protected abstract void compileOptionNode(EncloseNode node); compileEncloseNode(EncloseNode node)91 protected abstract void compileEncloseNode(EncloseNode node); compileAnchorNode(AnchorNode node)92 protected abstract void compileAnchorNode(AnchorNode node); 93 compileTree(final Node node)94 protected final void compileTree(final Node node) { 95 switch (node.getType()) { 96 case NodeType.LIST: 97 ConsAltNode lin = (ConsAltNode)node; 98 do { 99 compileTree(lin.car); 100 } while ((lin = lin.cdr) != null); 101 break; 102 103 case NodeType.ALT: 104 compileAltNode((ConsAltNode)node); 105 break; 106 107 case NodeType.STR: 108 final StringNode sn = (StringNode)node; 109 if (sn.isRaw()) { 110 compileStringRawNode(sn); 111 } else { 112 compileStringNode(sn); 113 } 114 break; 115 116 case NodeType.CCLASS: 117 compileCClassNode((CClassNode)node); 118 break; 119 120 case NodeType.CANY: 121 compileAnyCharNode(); 122 break; 123 124 case NodeType.BREF: 125 compileBackrefNode((BackRefNode)node); 126 break; 127 128 case NodeType.QTFR: 129 compileNonCECQuantifierNode((QuantifierNode)node); 130 break; 131 132 case NodeType.ENCLOSE: 133 final EncloseNode enode = (EncloseNode)node; 134 if (enode.isOption()) { 135 compileOptionNode(enode); 136 } else { 137 compileEncloseNode(enode); 138 } 139 break; 140 141 case NodeType.ANCHOR: 142 compileAnchorNode((AnchorNode)node); 143 break; 144 145 default: 146 // undefined node type 147 newInternalException(ERR_PARSER_BUG); 148 } // switch 149 } 150 compileTreeNTimes(final Node node, final int n)151 protected final void compileTreeNTimes(final Node node, final int n) { 152 for (int i=0; i<n; i++) { 153 compileTree(node); 154 } 155 } 156 newSyntaxException(final String message)157 protected void newSyntaxException(final String message) { 158 throw new SyntaxException(message); 159 } 160 newInternalException(final String message)161 protected void newInternalException(final String message) { 162 throw new InternalException(message); 163 } 164 } 165