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.joni; 21 22 import jdk.nashorn.internal.joni.ast.AnchorNode; 23 import jdk.nashorn.internal.joni.ast.BackRefNode; 24 import jdk.nashorn.internal.joni.ast.CClassNode; 25 import jdk.nashorn.internal.joni.ast.CTypeNode; 26 import jdk.nashorn.internal.joni.ast.CallNode; 27 import jdk.nashorn.internal.joni.ast.ConsAltNode; 28 import jdk.nashorn.internal.joni.ast.EncloseNode; 29 import jdk.nashorn.internal.joni.ast.Node; 30 import jdk.nashorn.internal.joni.ast.QuantifierNode; 31 import jdk.nashorn.internal.joni.ast.StringNode; 32 import jdk.nashorn.internal.joni.constants.NodeType; 33 import jdk.nashorn.internal.joni.exception.ErrorMessages; 34 import jdk.nashorn.internal.joni.exception.InternalException; 35 import jdk.nashorn.internal.joni.exception.SyntaxException; 36 37 abstract class Compiler implements ErrorMessages { 38 protected final Analyser analyser; 39 protected final Regex regex; 40 41 protected Compiler(Analyser analyser) { 42 this.analyser = analyser; 43 this.regex = analyser.regex; 44 } 45 46 final void compile() { 47 prepare(); 48 compileTree(analyser.root); 49 finish(); 50 } 51 52 protected abstract void prepare(); 53 protected abstract void finish(); 54 55 protected abstract void compileAltNode(ConsAltNode node); 56 57 private void compileStringRawNode(StringNode sn) { 58 if (sn.length() <= 0) return; 59 addCompileString(sn.chars, sn.p, 1 /*sb*/, sn.length(), false); 60 } 61 62 private void compileStringNode(StringNode node) { 63 StringNode sn = node; 64 if (sn.length() <= 0) return; 65 66 boolean ambig = sn.isAmbig(); 67 68 int p, prev; 69 p = prev = sn.p; 70 int end = sn.end; 71 char[] chars = sn.chars; 72 p++; 73 int slen = 1; 74 75 while (p < end) { 76 slen++; 77 p++; 78 } 79 addCompileString(chars, prev, 1, slen, ambig); 80 } 81 82 protected abstract void addCompileString(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase); 83 84 protected abstract void compileCClassNode(CClassNode node); 85 protected abstract void compileCTypeNode(CTypeNode node); 86 protected abstract void compileAnyCharNode(); 87 protected abstract void compileCallNode(CallNode node); 88 protected abstract void compileBackrefNode(BackRefNode node); 89 protected abstract void compileCECQuantifierNode(QuantifierNode node); 90 protected abstract void compileNonCECQuantifierNode(QuantifierNode node); 91 protected abstract void compileOptionNode(EncloseNode node); 92 protected abstract void compileEncloseNode(EncloseNode node); 93 protected abstract void compileAnchorNode(AnchorNode node); 94 95 protected final void compileTree(Node node) { 96 switch (node.getType()) { 97 case NodeType.LIST: 98 ConsAltNode lin = (ConsAltNode)node; 99 do { 100 compileTree(lin.car); 101 } while ((lin = lin.cdr) != null); 102 break; 103 104 case NodeType.ALT: 105 compileAltNode((ConsAltNode)node); 106 break; 107 108 case NodeType.STR: 109 StringNode sn = (StringNode)node; 110 if (sn.isRaw()) { 111 compileStringRawNode(sn); 112 } else { 113 compileStringNode(sn); 114 } 115 break; 116 117 case NodeType.CCLASS: 118 compileCClassNode((CClassNode)node); 119 break; 120 121 case NodeType.CTYPE: 122 compileCTypeNode((CTypeNode)node); 123 break; 124 125 case NodeType.CANY: 126 compileAnyCharNode(); 127 break; 128 129 case NodeType.BREF: 130 compileBackrefNode((BackRefNode)node); 131 break; 132 133 case NodeType.CALL: 134 if (Config.USE_SUBEXP_CALL) { 135 compileCallNode((CallNode)node); 136 break; 137 } // USE_SUBEXP_CALL 138 break; 139 140 case NodeType.QTFR: 141 if (Config.USE_COMBINATION_EXPLOSION_CHECK) { 142 compileCECQuantifierNode((QuantifierNode)node); 143 } else { 144 compileNonCECQuantifierNode((QuantifierNode)node); 145 } 146 break; 147 148 case NodeType.ENCLOSE: 149 EncloseNode enode = (EncloseNode)node; 150 if (enode.isOption()) { 151 compileOptionNode(enode); 152 } else { 153 compileEncloseNode(enode); 154 } 155 break; 156 157 case NodeType.ANCHOR: 158 compileAnchorNode((AnchorNode)node); 159 break; 160 161 default: 162 // undefined node type 163 newInternalException(ERR_PARSER_BUG); 164 } // switch 165 } 166 167 protected final void compileTreeNTimes(Node node, int n) { 168 for (int i=0; i<n; i++) compileTree(node); 169 } 170 171 protected void newSyntaxException(String message) { 172 throw new SyntaxException(message); 173 } 174 175 protected void newInternalException(String message) { 176 throw new InternalException(message); 177 } 178 }