• 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#License
4 /********************************************************************
5  * COPYRIGHT:
6  * Copyright (c) 2001-2016, International Business Machines Corporation and
7  * others. All Rights Reserved.
8  ********************************************************************/
9 
10 package ohos.global.icu.text;
11 
12 import java.util.HashSet;
13 import java.util.List;
14 import java.util.Set;
15 
16 import ohos.global.icu.impl.Assert;
17 
18 /**
19  *   This class represents a node in the parse tree created by the RBBI Rule compiler.
20  */
21 class RBBINode {
22 
23 
24  //   enum NodeType {
25      static final int    setRef = 0;
26      static final int    uset = 1;
27      static final int    varRef = 2;
28      static final int    leafChar = 3;
29      static final int    lookAhead = 4;
30      static final int    tag = 5;
31      static final int    endMark = 6;
32      static final int    opStart = 7;
33      static final int    opCat = 8;
34      static final int    opOr = 9;
35      static final int    opStar = 10;
36      static final int    opPlus = 11;
37      static final int    opQuestion = 12;
38      static final int    opBreak = 13;
39      static final int    opReverse = 14;
40      static final int    opLParen = 15;
41      static final int    nodeTypeLimit = 16;    //  For Assertion checking only.
42 
43      static final String []  nodeTypeNames = {
44          "setRef",
45          "uset",
46          "varRef",
47          "leafChar",
48          "lookAhead",
49          "tag",
50          "endMark",
51          "opStart",
52          "opCat",
53          "opOr",
54          "opStar",
55          "opPlus",
56          "opQuestion",
57          "opBreak",
58          "opReverse",
59          "opLParen"
60      };
61 
62 //    enum OpPrecedence {
63     static final int    precZero   = 0;
64     static final int    precStart  = 1;
65     static final int    precLParen = 2;
66     static final int    precOpOr   = 3;
67     static final int    precOpCat  = 4;
68 
69     int          fType;   // enum NodeType
70     RBBINode      fParent;
71     RBBINode      fLeftChild;
72     RBBINode      fRightChild;
73     UnicodeSet    fInputSet;           // For uset nodes only.
74     int          fPrecedence = precZero;   // enum OpPrecedence, For binary ops only.
75 
76     String       fText;                 // Text corresponding to this node.
77                                         //   May be lazily evaluated when (if) needed
78                                         //   for some node types.
79     int           fFirstPos;            // Position in the rule source string of the
80                                         //   first text associated with the node.
81                                         //   If there's a left child, this will be the same
82                                         //   as that child's left pos.
83     int           fLastPos;             //  Last position in the rule source string
84                                         //    of any text associated with this node.
85                                         //    If there's a right child, this will be the same
86                                         //    as that child's last postion.
87 
88     boolean      fNullable;            //  See Aho DFA table generation algorithm
89     int           fVal;                 // For leafChar nodes, the value.
90                                         //   Values are the character category,
91                                         //   corresponds to columns in the final
92                                         //   state transition table.
93 
94     boolean      fLookAheadEnd;        // For endMark nodes, set TRUE if
95                                        //   marking the end of a look-ahead rule.
96 
97     boolean      fRuleRoot;             // True if this node is the root of a rule.
98     boolean      fChainIn;              // True if chaining into this rule is allowed
99                                         //     (no '^' present).
100 
101 
102     Set<RBBINode> fFirstPosSet;         // See Aho DFA table generation algorithm
103     Set<RBBINode> fLastPosSet;          // See Aho.
104     Set<RBBINode> fFollowPos;           // See Aho.
105 
106     int           fSerialNum;           //  Debugging aids.  Each node gets a unique serial number.
107     static int    gLastSerial;
108 
RBBINode(int t)109     RBBINode(int t) {
110         Assert.assrt(t < nodeTypeLimit);
111         fSerialNum = ++gLastSerial;
112         fType = t;
113 
114         fFirstPosSet = new HashSet<RBBINode>();
115         fLastPosSet = new HashSet<RBBINode>();
116         fFollowPos = new HashSet<RBBINode>();
117         if (t == opCat) {
118             fPrecedence = precOpCat;
119         } else if (t == opOr) {
120             fPrecedence = precOpOr;
121         } else if (t == opStart) {
122             fPrecedence = precStart;
123         } else if (t == opLParen) {
124             fPrecedence = precLParen;
125         } else {
126             fPrecedence = precZero;
127         }
128     }
129 
130     RBBINode(RBBINode other) {
131         fSerialNum = ++gLastSerial;
132         fType = other.fType;
133         fInputSet = other.fInputSet;
134         fPrecedence = other.fPrecedence;
135         fText = other.fText;
136         fFirstPos = other.fFirstPos;
137         fLastPos = other.fLastPos;
138         fNullable = other.fNullable;
139         fVal = other.fVal;
140         fRuleRoot = false;
141         fChainIn = other.fChainIn;
142         fFirstPosSet = new HashSet<RBBINode>(other.fFirstPosSet);
143         fLastPosSet = new HashSet<RBBINode>(other.fLastPosSet);
144         fFollowPos = new HashSet<RBBINode>(other.fFollowPos);
145     }
146 
147     //-------------------------------------------------------------------------
148     //
149     //        cloneTree Make a copy of the subtree rooted at this node.
150     //                      Discard any variable references encountered along the way,
151     //                      and replace with copies of the variable's definitions.
152     //                      Used to replicate the expression underneath variable
153     //                      references in preparation for generating the DFA tables.
154     //
155     //-------------------------------------------------------------------------
156     RBBINode cloneTree() {
157         RBBINode n;
158 
159         if (fType == RBBINode.varRef) {
160             // If the current node is a variable reference, skip over it
161             //   and clone the definition of the variable instead.
162             n = fLeftChild.cloneTree();
163         } else if (fType == RBBINode.uset) {
164             n = this;
165         } else {
166             n = new RBBINode(this);
167             if (fLeftChild != null) {
168                 n.fLeftChild = fLeftChild.cloneTree();
169                 n.fLeftChild.fParent = n;
170             }
171             if (fRightChild != null) {
172                 n.fRightChild = fRightChild.cloneTree();
173                 n.fRightChild.fParent = n;
174             }
175         }
176         return n;
177     }
178 
179 
180 
181     //-------------------------------------------------------------------------
182     //
183     //       flattenVariables Walk a parse tree, replacing any variable
184     //                          references with a copy of the variable's definition.
185     //                          Aside from variables, the tree is not changed.
186     //
187     //                          Return the root of the tree. If the root was not a variable
188     //                          reference, it remains unchanged - the root we started with
189     //                          is the root we return. If, however, the root was a variable
190     //                          reference, the root of the newly cloned replacement tree will
191     //                          be returned, and the original tree deleted.
192     //
193     //                          This function works by recursively walking the tree
194     //                          without doing anything until a variable reference is
195     //                          found, then calling cloneTree() at that point. Any
196     //                          nested references are handled by cloneTree(), not here.
197     //
198     //-------------------------------------------------------------------------
199     RBBINode flattenVariables() {
200         if (fType == varRef) {
201             RBBINode retNode  = fLeftChild.cloneTree();
202             retNode.fRuleRoot = this.fRuleRoot;
203             retNode.fChainIn  = this.fChainIn;
204             return retNode;
205         }
206 
207         if (fLeftChild != null) {
208             fLeftChild = fLeftChild.flattenVariables();
209             fLeftChild.fParent = this;
210         }
211         if (fRightChild != null) {
212             fRightChild = fRightChild.flattenVariables();
213             fRightChild.fParent = this;
214         }
215         return this;
216     }
217 
218     //-------------------------------------------------------------------------
219     //
220     //      flattenSets Walk the parse tree, replacing any nodes of type setRef
221     //                     with a copy of the expression tree for the set. A set's
222     //                     equivalent expression tree is precomputed and saved as
223     //                     the left child of the uset node.
224     //
225     //-------------------------------------------------------------------------
226     void flattenSets() {
227         Assert.assrt(fType != setRef);
228 
229         if (fLeftChild != null) {
230             if (fLeftChild.fType == setRef) {
231                 RBBINode setRefNode = fLeftChild;
232                 RBBINode usetNode = setRefNode.fLeftChild;
233                 RBBINode replTree = usetNode.fLeftChild;
234                 fLeftChild = replTree.cloneTree();
235                 fLeftChild.fParent = this;
236             } else {
237                 fLeftChild.flattenSets();
238             }
239         }
240 
241         if (fRightChild != null) {
242             if (fRightChild.fType == setRef) {
243                 RBBINode setRefNode = fRightChild;
244                 RBBINode usetNode = setRefNode.fLeftChild;
245                 RBBINode replTree = usetNode.fLeftChild;
246                 fRightChild = replTree.cloneTree();
247                 fRightChild.fParent = this;
248                 // delete setRefNode;
249             } else {
250                 fRightChild.flattenSets();
251             }
252         }
253     }
254 
255     //-------------------------------------------------------------------------
256     //
257     //       findNodes() Locate all the nodes of the specified type, starting
258     //                       at the specified root.
259     //
260     //-------------------------------------------------------------------------
261     void findNodes(List<RBBINode> dest, int kind) {
262         if (fType == kind) {
263             dest.add(this);
264         }
265         if (fLeftChild != null) {
266             fLeftChild.findNodes(dest, kind);
267         }
268         if (fRightChild != null) {
269             fRightChild.findNodes(dest, kind);
270         }
271     }
272 
273 
274 
275     //-------------------------------------------------------------------------
276     //
277     //        print. Print out a single node, for debugging.
278     //
279     //-------------------------------------------------------------------------
280     ///CLOVER:OFF
281     static void printNode(RBBINode n) {
282 
283         if (n==null) {
284             System.out.print (" -- null --\n");
285         } else {
286             RBBINode.printInt( n.fSerialNum, 10);
287             RBBINode.printString(nodeTypeNames[n.fType], 11);
288             RBBINode.printInt(n.fParent==null? 0     : n.fParent.fSerialNum, 11);
289             RBBINode.printInt(n.fLeftChild==null? 0  : n.fLeftChild.fSerialNum, 11);
290             RBBINode.printInt(n.fRightChild==null? 0 : n.fRightChild.fSerialNum, 12);
291             RBBINode.printInt(n.fFirstPos, 12);
292             RBBINode.printInt(n.fVal, 7);
293 
294             if (n.fType == varRef) {
295                 System.out.print(" " + n.fText);
296             }
297         }
298         System.out.println("");
299     }
300     ///CLOVER:ON
301 
302 
303     // Print a String in a fixed field size.
304     // Debugging function.
305     ///CLOVER:OFF
306     static void printString(String s, int minWidth) {
307         for (int i = minWidth; i < 0; i++) {
308             // negative width means pad leading spaces, not fixed width.
309             System.out.print(' ');
310         }
311         for (int i = s.length(); i < minWidth; i++) {
312             System.out.print(' ');
313         }
314         System.out.print(s);
315     }
316     ///CLOVER:ON
317 
318     //
319     //  Print an int in a fixed size field.
320     //  Debugging function.
321     //
322     ///CLOVER:OFF
323     static void printInt(int i, int minWidth) {
324         String s = Integer.toString(i);
325         printString(s, Math.max(minWidth, s.length() + 1));
326     }
327     ///CLOVER:ON
328 
329     ///CLOVER:OFF
330     static void printHex(int i, int minWidth) {
331         String s = Integer.toString(i, 16);
332         String leadingZeroes = "00000"
333                 .substring(0, Math.max(0, 5 - s.length()));
334         s = leadingZeroes + s;
335         printString(s, minWidth);
336     }
337     ///CLOVER:ON
338 
339 
340     // -------------------------------------------------------------------------
341     //
342     //        print. Print out the tree of nodes rooted at "this"
343     //
344     // -------------------------------------------------------------------------
345     ///CLOVER:OFF
346     void printTree(boolean printHeading) {
347         if (printHeading) {
348             System.out.println( "-------------------------------------------------------------------");
349             System.out.println("    Serial       type     Parent  LeftChild  RightChild    position  value");
350         }
351         printNode(this);
352             // Only dump the definition under a variable reference if asked to.
353             // Unconditinally dump children of all other node types.
354             if (fType != varRef) {
355                 if (fLeftChild != null) {
356                     fLeftChild.printTree(false);
357                 }
358 
359                 if (fRightChild != null) {
360                     fRightChild.printTree(false);
361                 }
362             }
363     }
364     ///CLOVER:ON
365 
366 }
367