Home | History | Annotate | Download | only in text
      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#License
      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 
     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     //
     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.
     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     //
    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     //
    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     //
    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
    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