| Index: source/common/rbbitblb.cpp
|
| diff --git a/source/common/rbbitblb.cpp b/source/common/rbbitblb.cpp
|
| index 2ce82dfed18196e95bbbea38c906e6b3e118146f..2738c7500882aae3519c7a32fd3fe61cc2e5d66b 100644
|
| --- a/source/common/rbbitblb.cpp
|
| +++ b/source/common/rbbitblb.cpp
|
| @@ -1,6 +1,8 @@
|
| +// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
| +// License & terms of use: http://www.unicode.org/copyright.html
|
| /*
|
| **********************************************************************
|
| -* Copyright (c) 2002-2009, 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;
|
| }
|
| @@ -1032,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: ");
|
| @@ -1141,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");
|
| }
|
|
|