1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // © 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html 4 /* 5 *************************************************************************** 6 * Copyright (C) 2002-2009 International Business Machines Corporation * 7 * and others. All rights reserved. * 8 *************************************************************************** 9 */ 10 package android.icu.text; 11 12 import java.text.ParsePosition; 13 import java.util.HashMap; 14 15 import android.icu.lang.UCharacter; 16 17 class RBBISymbolTable implements SymbolTable{ 18 19 HashMap<String, RBBISymbolTableEntry> fHashTable; 20 RBBIRuleScanner fRuleScanner; 21 22 // These next two fields are part of the mechanism for passing references to 23 // already-constructed UnicodeSets back to the UnicodeSet constructor 24 // when the pattern includes $variable references. 25 String ffffString; 26 UnicodeSet fCachedSetLookup; 27 28 29 30 static class RBBISymbolTableEntry { 31 String key; 32 RBBINode val; 33 } 34 35 RBBISymbolTable(RBBIRuleScanner rs)36 RBBISymbolTable(RBBIRuleScanner rs) { 37 fRuleScanner = rs; 38 fHashTable = new HashMap<String, RBBISymbolTableEntry>(); 39 ffffString = "\uffff"; 40 } 41 42 // 43 // RBBISymbolTable::lookup This function from the abstract symbol table inteface 44 // looks up a variable name and returns a UnicodeString 45 // containing the substitution text. 46 // 47 // The variable name does NOT include the leading $. 48 // lookup(String s)49 public char[] lookup(String s) { 50 RBBISymbolTableEntry el; 51 RBBINode varRefNode; 52 RBBINode exprNode; 53 54 RBBINode usetNode; 55 String retString; 56 57 el = fHashTable.get(s); 58 if (el == null) { 59 return null; 60 } 61 62 // Walk through any chain of variable assignments that ultimately resolve to a Set Ref. 63 varRefNode = el.val; 64 while (varRefNode.fLeftChild.fType == RBBINode.varRef) { 65 varRefNode = varRefNode.fLeftChild; 66 } 67 68 exprNode = varRefNode.fLeftChild; // Root node of expression for variable 69 if (exprNode.fType == RBBINode.setRef) { 70 // The $variable refers to a single UnicodeSet 71 // return the ffffString, which will subsequently be interpreted as a 72 // stand-in character for the set by RBBISymbolTable::lookupMatcher() 73 usetNode = exprNode.fLeftChild; 74 fCachedSetLookup = usetNode.fInputSet; 75 retString = ffffString; 76 } else { 77 // The variable refers to something other than just a set. 78 // This is an error in the rules being compiled. $Variables inside of UnicodeSets 79 // must refer only to another set, not to some random non-set expression. 80 // Note: single characters are represented as sets, so they are ok. 81 fRuleScanner.error(RBBIRuleBuilder.U_BRK_MALFORMED_SET); 82 retString = exprNode.fText; 83 fCachedSetLookup = null; 84 } 85 return retString.toCharArray(); 86 } 87 88 // 89 // RBBISymbolTable::lookupMatcher This function from the abstract symbol table 90 // interface maps a single stand-in character to a 91 // pointer to a Unicode Set. The Unicode Set code uses this 92 // mechanism to get all references to the same $variable 93 // name to refer to a single common Unicode Set instance. 94 // 95 // This implementation cheats a little, and does not maintain a map of stand-in chars 96 // to sets. Instead, it takes advantage of the fact that the UnicodeSet 97 // constructor will always call this function right after calling lookup(), 98 // and we just need to remember what set to return between these two calls. lookupMatcher(int ch)99 public UnicodeMatcher lookupMatcher(int ch) { 100 UnicodeSet retVal = null; 101 if (ch == 0xffff) { 102 retVal = fCachedSetLookup; 103 fCachedSetLookup = null; 104 } 105 return retVal; 106 } 107 108 // 109 // RBBISymbolTable::parseReference This function from the abstract symbol table interface 110 // looks for a $variable name in the source text. 111 // It does not look it up, only scans for it. 112 // It is used by the UnicodeSet parser. 113 // parseReference(String text, ParsePosition pos, int limit)114 public String parseReference(String text, ParsePosition pos, int limit) { 115 int start = pos.getIndex(); 116 int i = start; 117 String result = ""; 118 while (i < limit) { 119 int c = UTF16.charAt(text, i); 120 if ((i == start && !UCharacter.isUnicodeIdentifierStart(c)) 121 || !UCharacter.isUnicodeIdentifierPart(c)) { 122 break; 123 } 124 i += UTF16.getCharCount(c); 125 } 126 if (i == start) { // No valid name chars 127 return result; // Indicate failure with empty string 128 } 129 pos.setIndex(i); 130 result = text.substring(start, i); 131 return result; 132 } 133 134 // 135 // RBBISymbolTable::lookupNode Given a key (a variable name), return the 136 // corresponding RBBI Node. If there is no entry 137 // in the table for this name, return NULL. 138 // lookupNode(String key)139 RBBINode lookupNode(String key) { 140 141 RBBINode retNode = null; 142 RBBISymbolTableEntry el; 143 144 el = fHashTable.get(key); 145 if (el != null) { 146 retNode = el.val; 147 } 148 return retNode; 149 } 150 151 // 152 // RBBISymbolTable::addEntry Add a new entry to the symbol table. 153 // Indicate an error if the name already exists - 154 // this will only occur in the case of duplicate 155 // variable assignments. 156 // addEntry(String key, RBBINode val)157 void addEntry(String key, RBBINode val) { 158 RBBISymbolTableEntry e; 159 e = fHashTable.get(key); 160 if (e != null) { 161 fRuleScanner.error(RBBIRuleBuilder.U_BRK_VARIABLE_REDFINITION); 162 return; 163 } 164 165 e = new RBBISymbolTableEntry(); 166 e.key = key; 167 e.val = val; 168 fHashTable.put(e.key, e); 169 } 170 171 // 172 // RBBISymbolTable::print Debugging function, dump out the symbol table contents. 173 // 174 ///CLOVER:OFF rbbiSymtablePrint()175 void rbbiSymtablePrint() { 176 System.out 177 .print("Variable Definitions\n" 178 + "Name Node Val String Val\n" 179 + "----------------------------------------------------------------------\n"); 180 181 RBBISymbolTableEntry[] syms = fHashTable.values().toArray(new RBBISymbolTableEntry[0]); 182 183 for (int i = 0; i < syms.length; i++) { 184 RBBISymbolTableEntry s = syms[i]; 185 186 System.out.print(" " + s.key + " "); // TODO: format output into columns. 187 System.out.print(" " + s.val + " "); 188 System.out.print(s.val.fLeftChild.fText); 189 System.out.print("\n"); 190 } 191 192 System.out.println("\nParsed Variable Definitions\n"); 193 for (int i = 0; i < syms.length; i++) { 194 RBBISymbolTableEntry s = syms[i]; 195 System.out.print(s.key); 196 s.val.fLeftChild.printTree(true); 197 System.out.print("\n"); 198 } 199 } 200 ///CLOVER:ON 201 202 } 203