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