• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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