]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/common/rbbitblb.cpp
ICU-59117.0.1.tar.gz
[apple/icu.git] / icuSources / common / rbbitblb.cpp
index 44c8e9fdd986f2f9532ccc92f173bfd1e1b75474..0f1a901ffc542261bce396c0e362e1c20bfeddba 100644 (file)
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (c) 2002-2008, International Business Machines
+*   Copyright (c) 2002-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 */
@@ -78,8 +80,8 @@ void  RBBITableBuilder::build() {
     fTree = fTree->flattenVariables();
 #ifdef RBBI_DEBUG
     if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "ftree")) {
-        RBBIDebugPuts("Parse tree after flattening variable references.");
-        fTree->printTree(TRUE);
+        RBBIDebugPuts("\nParse tree after flattening variable references.");
+        RBBINode::printTree(fTree, TRUE);
     }
 #endif
 
@@ -136,8 +138,8 @@ void  RBBITableBuilder::build() {
     fTree->flattenSets();
 #ifdef RBBI_DEBUG
     if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "stree")) {
-        RBBIDebugPuts("Parse tree after flattening Unicode Set references.");
-        fTree->printTree(TRUE);
+        RBBIDebugPuts("\nParse tree after flattening Unicode Set references.");
+        RBBINode::printTree(fTree, TRUE);
     }
 #endif
 
@@ -375,6 +377,25 @@ void RBBITableBuilder::calcFollowPos(RBBINode *n) {
 
 }
 
+//-----------------------------------------------------------------------------
+//
+//    addRuleRootNodes    Recursively walk a parse tree, adding all nodes flagged
+//                        as roots of a rule to a destination vector.
+//
+//-----------------------------------------------------------------------------
+void RBBITableBuilder::addRuleRootNodes(UVector *dest, RBBINode *node) {
+    if (node == NULL || U_FAILURE(*fStatus)) {
+        return;
+    }
+    if (node->fRuleRoot) {
+        dest->addElement(node, *fStatus);
+        // Note: rules cannot nest. If we found a rule start node,
+        //       no child node can also be a start node.
+        return;
+    }
+    addRuleRootNodes(dest, node->fLeftChild);
+    addRuleRootNodes(dest, node->fRightChild);
+}
 
 //-----------------------------------------------------------------------------
 //
@@ -401,19 +422,24 @@ void RBBITableBuilder::calcChainedFollowPos(RBBINode *tree) {
         return;
     }
 
-    // Get all nodes that can be the start a match, which is FirstPosition()
-    // of the portion of the tree corresponding to user-written rules.
-    // See the tree description in bofFixup().
-    RBBINode *userRuleRoot = tree;
-    if (fRB->fSetBuilder->sawBOF()) {
-        userRuleRoot = tree->fLeftChild->fRightChild;
-    }
-    U_ASSERT(userRuleRoot != NULL);
-    UVector *matchStartNodes = userRuleRoot->fFirstPosSet;
+    // Collect all leaf nodes that can start matches for rules
+    // with inbound chaining enabled, which is the union of the 
+    // firstPosition sets from each of the rule root nodes.
+    
+    UVector ruleRootNodes(*fStatus);
+    addRuleRootNodes(&ruleRootNodes, tree);
 
+    UVector matchStartNodes(*fStatus);
+    for (int i=0; i<ruleRootNodes.size(); ++i) {
+        RBBINode *node = static_cast<RBBINode *>(ruleRootNodes.elementAt(i));
+        if (node->fChainIn) {
+            setAdd(&matchStartNodes, node->fFirstPosSet);
+        }
+    }
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
 
-    // Iteratate over all leaf nodes,
-    //
     int32_t  endNodeIx;
     int32_t  startNodeIx;
 
@@ -455,8 +481,8 @@ void RBBITableBuilder::calcChainedFollowPos(RBBINode *tree) {
         // Now iterate over the nodes that can start a match, looking for ones
         //   with the same char class as our ending node.
         RBBINode *startNode;
-        for (startNodeIx = 0; startNodeIx<matchStartNodes->size(); startNodeIx++) {
-            startNode = (RBBINode *)matchStartNodes->elementAt(startNodeIx);
+        for (startNodeIx = 0; startNodeIx<matchStartNodes.size(); startNodeIx++) {
+            startNode = (RBBINode *)matchStartNodes.elementAt(startNodeIx);
             if (startNode->fType != RBBINode::leafChar) {
                 continue;
             }
@@ -955,74 +981,56 @@ void RBBITableBuilder::setAdd(UVector *dest, UVector *source) {
     int32_t destOriginalSize = dest->size();
     int32_t sourceSize       = source->size();
     int32_t di           = 0;
-    void *(destS[16]), *(sourceS[16]);  // Handle small cases without malloc
-    void **destH = 0, **sourceH = 0;
-    void **destBuff, **sourceBuff;
+    MaybeStackArray<void *, 16> destArray, sourceArray;  // Handle small cases without malloc
+    void **destPtr, **sourcePtr;
     void **destLim, **sourceLim;
 
-    if (destOriginalSize > (int32_t)(sizeof(destS)/sizeof(destS[0]))) {
-        destH = (void **)uprv_malloc(sizeof(void *) * destOriginalSize);
-        destBuff = destH;
-    }
-    else {
-        destBuff = destS;
-    }
-    if (destBuff == 0) {
-        return;
+    if (destOriginalSize > destArray.getCapacity()) {
+        if (destArray.resize(destOriginalSize) == NULL) {
+            return;
+        }
     }
-    destLim = destBuff + destOriginalSize;
+    destPtr = destArray.getAlias();
+    destLim = destPtr + destOriginalSize;  // destArray.getArrayLimit()?
 
-    if (sourceSize > (int32_t)(sizeof(sourceS)/sizeof(sourceS[0]))) {
-        sourceH = (void **)uprv_malloc(sizeof(void *) * sourceSize);
-        sourceBuff = sourceH;
-    }
-    else {
-        sourceBuff = sourceS;
-    }
-    if (sourceBuff == 0) {
-        if (destH) {
-            uprv_free(destH);
+    if (sourceSize > sourceArray.getCapacity()) {
+        if (sourceArray.resize(sourceSize) == NULL) {
+            return;
         }
-        return;
     }
-    sourceLim = sourceBuff + sourceSize;
+    sourcePtr = sourceArray.getAlias();
+    sourceLim = sourcePtr + sourceSize;  // sourceArray.getArrayLimit()?
 
     // Avoid multiple "get element" calls by getting the contents into arrays
-    (void) dest->toArray(destBuff);
-    (void) source->toArray(sourceBuff);
+    (void) dest->toArray(destPtr);
+    (void) source->toArray(sourcePtr);
 
     dest->setSize(sourceSize+destOriginalSize, *fStatus);
 
-    while (sourceBuff < sourceLim && destBuff < destLim) {
-        if (*destBuff == *sourceBuff) {
-            dest->setElementAt(*sourceBuff++, di++);
-            destBuff++;
+    while (sourcePtr < sourceLim && destPtr < destLim) {
+        if (*destPtr == *sourcePtr) {
+            dest->setElementAt(*sourcePtr++, di++);
+            destPtr++;
         }
         // This check is required for machines with segmented memory, like i5/OS.
         // Direct pointer comparison is not recommended.
-        else if (uprv_memcmp(destBuff, sourceBuff, sizeof(void *)) < 0) {
-            dest->setElementAt(*destBuff++, di++);
+        else if (uprv_memcmp(destPtr, sourcePtr, sizeof(void *)) < 0) {
+            dest->setElementAt(*destPtr++, di++);
         }
-        else { /* *sourceBuff < *destBuff */
-            dest->setElementAt(*sourceBuff++, di++);
+        else { /* *sourcePtr < *destPtr */
+            dest->setElementAt(*sourcePtr++, di++);
         }
     }
 
     // At most one of these two cleanup loops will execute
-    while (destBuff < destLim) {
-        dest->setElementAt(*destBuff++, di++);
+    while (destPtr < destLim) {
+        dest->setElementAt(*destPtr++, di++);
     }
-    while (sourceBuff < sourceLim) {
-        dest->setElementAt(*sourceBuff++, di++);
+    while (sourcePtr < sourceLim) {
+        dest->setElementAt(*sourcePtr++, di++);
     }
 
     dest->setSize(di, *fStatus);
-    if (destH) {
-        uprv_free(destH);
-    }
-    if (sourceH) {
-        uprv_free(sourceH);
-    }
 }
 
 
@@ -1050,7 +1058,9 @@ void RBBITableBuilder::printPosSets(RBBINode *n) {
     if (n==NULL) {
         return;
     }
-    n->printNode();
+    printf("\n");
+    RBBINode::printNodeHeader();
+    RBBINode::printNode(n);
     RBBIDebugPrintf("         Nullable:  %s\n", n->fNullable?"TRUE":"FALSE");
 
     RBBIDebugPrintf("         firstpos:  ");
@@ -1159,8 +1169,8 @@ void RBBITableBuilder::exportTable(void *where) {
 void RBBITableBuilder::printSet(UVector *s) {
     int32_t  i;
     for (i=0; i<s->size(); i++) {
-        void *v = s->elementAt(i);
-        RBBIDebugPrintf("%10p", v);
+        const RBBINode *v = static_cast<const RBBINode *>(s->elementAt(i));
+        RBBIDebugPrintf("%5d", v==NULL? -1 : v->fSerialNum);
     }
     RBBIDebugPrintf("\n");
 }