📄 dfacontentmodel.java
字号:
} leafIndex = fLeafSorter[sorterIndex++]; } /* Optimization(Jan, 2001) */ // // If this new set is not empty, then see if its in the list // of states to do. If not, then add it. // if (!newSet.isEmpty()) { // // Search the 'states to do' list to see if this new // state set is already in there. // /* Optimization(Jan, 2001) */ Integer stateObj = (Integer)stateTable.get(newSet); int stateIndex = (stateObj == null ? curState : stateObj.intValue()); /* Optimization(Jan, 2001) */ // If we did not find it, then add it if (stateIndex == curState) { // // Put this new state into the states to do and init // a new entry at the same index in the transition // table. // statesToDo[curState] = newSet; fTransTable[curState] = makeDefStateList(); /* Optimization(Jan, 2001) */ stateTable.put(newSet, new Integer(curState)); /* Optimization(Jan, 2001) */ // We now have a new state to do so bump the count curState++; // // Null out the new set to indicate we adopted it. // This will cause the creation of a new set on the // next time around the loop. // newSet = null; } // // Now set this state in the transition table's entry // for this element (using its index), with the DFA // state we will move to from the current state when we // see this input element. // transEntry[elemIndex] = stateIndex; // Expand the arrays if we're full if (curState == curArraySize) { // // Yikes, we overflowed the initial array size, so // we've got to expand all of these arrays. So adjust // up the size by 50% and allocate new arrays. // final int newSize = (int)(curArraySize * 1.5); CMStateSet[] newToDo = new CMStateSet[newSize]; boolean[] newFinalFlags = new boolean[newSize]; int[][] newTransTable = new int[newSize][]; // Copy over all of the existing content for (int expIndex = 0; expIndex < curArraySize; expIndex++) { newToDo[expIndex] = statesToDo[expIndex]; newFinalFlags[expIndex] = fFinalStateFlags[expIndex]; newTransTable[expIndex] = fTransTable[expIndex]; } // Store the new array size curArraySize = newSize; statesToDo = newToDo; fFinalStateFlags = newFinalFlags; fTransTable = newTransTable; } } } } // Check to see if we can set the fEmptyContentIsValid flag. fEmptyContentIsValid = ((CMBinOp)fHeadNode).getLeft().isNullable(); // // And now we can say bye bye to the temp representation since we've // built the DFA. // if (DEBUG_VALIDATE_CONTENT) dumpTree(fHeadNode, 0); fHeadNode = null; fLeafList = null; fFollowList = null; } /** * Calculates the follow list of the current node. * * @param nodeCur The curent node. * * @exception CMException Thrown if follow list cannot be calculated. */ private void calcFollowList(CMNode nodeCur) { // Recurse as required if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_CHOICE) { // Recurse only calcFollowList(((CMBinOp)nodeCur).getLeft()); calcFollowList(((CMBinOp)nodeCur).getRight()); } else if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_SEQ) { // Recurse first calcFollowList(((CMBinOp)nodeCur).getLeft()); calcFollowList(((CMBinOp)nodeCur).getRight()); // // Now handle our level. We use our left child's last pos // set and our right child's first pos set, so go ahead and // get them ahead of time. // final CMStateSet last = ((CMBinOp)nodeCur).getLeft().lastPos(); final CMStateSet first = ((CMBinOp)nodeCur).getRight().firstPos(); // // Now, for every position which is in our left child's last set // add all of the states in our right child's first set to the // follow set for that position. // for (int index = 0; index < fLeafCount; index++) { if (last.getBit(index)) fFollowList[index].union(first); } } /*** else if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE) { // Recurse first calcFollowList(((CMUniOp)nodeCur).getChild()); // // Now handle our level. We use our own first and last position // sets, so get them up front. // final CMStateSet first = nodeCur.firstPos(); final CMStateSet last = nodeCur.lastPos(); // // For every position which is in our last position set, add all // of our first position states to the follow set for that // position. // for (int index = 0; index < fLeafCount; index++) { if (last.getBit(index)) fFollowList[index].union(first); } } else if ((nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) || (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE)) { throw new RuntimeException("ImplementationMessages.VAL_NIICM"); } /***/ else if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE || nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) { // Recurse first calcFollowList(((CMUniOp)nodeCur).getChild()); // // Now handle our level. We use our own first and last position // sets, so get them up front. // final CMStateSet first = nodeCur.firstPos(); final CMStateSet last = nodeCur.lastPos(); // // For every position which is in our last position set, add all // of our first position states to the follow set for that // position. // for (int index = 0; index < fLeafCount; index++) { if (last.getBit(index)) fFollowList[index].union(first); } } else if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE) { // Recurse only calcFollowList(((CMUniOp)nodeCur).getChild()); } /***/ } /** * Dumps the tree of the current node to standard output. * * @param nodeCur The current node. * @param level The maximum levels to output. * * @exception CMException Thrown on error. */ private void dumpTree(CMNode nodeCur, int level) { for (int index = 0; index < level; index++) System.out.print(" "); int type = nodeCur.type(); if ((type == XMLContentSpec.CONTENTSPECNODE_CHOICE) || (type == XMLContentSpec.CONTENTSPECNODE_SEQ)) { if (type == XMLContentSpec.CONTENTSPECNODE_CHOICE) System.out.print("Choice Node "); else System.out.print("Seq Node "); if (nodeCur.isNullable()) System.out.print("Nullable "); System.out.print("firstPos="); System.out.print(nodeCur.firstPos().toString()); System.out.print(" lastPos="); System.out.println(nodeCur.lastPos().toString()); dumpTree(((CMBinOp)nodeCur).getLeft(), level+1); dumpTree(((CMBinOp)nodeCur).getRight(), level+1); } else if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE) { System.out.print("Rep Node "); if (nodeCur.isNullable()) System.out.print("Nullable "); System.out.print("firstPos="); System.out.print(nodeCur.firstPos().toString()); System.out.print(" lastPos="); System.out.println(nodeCur.lastPos().toString()); dumpTree(((CMUniOp)nodeCur).getChild(), level+1); } else if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_LEAF) { System.out.print ( "Leaf: (pos=" + ((CMLeaf)nodeCur).getPosition() + "), " + ((CMLeaf)nodeCur).getElement() + "(elemIndex=" + ((CMLeaf)nodeCur).getElement() + ") " ); if (nodeCur.isNullable()) System.out.print(" Nullable "); System.out.print("firstPos="); System.out.print(nodeCur.firstPos().toString()); System.out.print(" lastPos="); System.out.println(nodeCur.lastPos().toString()); } else { throw new RuntimeException("ImplementationMessages.VAL_NIICM"); } } /** * -1 is used to represent bad transitions in the transition table * entry for each state. So each entry is initialized to an all -1 * array. This method creates a new entry and initializes it. */ private int[] makeDefStateList() { int[] retArray = new int[fElemMapSize]; for (int index = 0; index < fElemMapSize; index++) retArray[index] = -1; return retArray; } /** Post tree build initialization. */ private int postTreeBuildInit(CMNode nodeCur, int curIndex) { // Set the maximum states on this node nodeCur.setMaxStates(fLeafCount); // Recurse as required if ((nodeCur.type() & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY || (nodeCur.type() & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL || (nodeCur.type() & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) { // REVISIT: Don't waste these structures. QName qname = new QName(null, null, null, ((CMAny)nodeCur).getURI()); fLeafList[curIndex] = new CMLeaf(qname, ((CMAny)nodeCur).getPosition()); fLeafListType[curIndex] = nodeCur.type(); curIndex++; } else if ((nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_CHOICE) || (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_SEQ)) { curIndex = postTreeBuildInit(((CMBinOp)nodeCur).getLeft(), curIndex); curIndex = postTreeBuildInit(((CMBinOp)nodeCur).getRight(), curIndex); } else if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE || nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE || nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE) { curIndex = postTreeBuildInit(((CMUniOp)nodeCur).getChild(), curIndex); } else if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_LEAF) { // // Put this node in the leaf list at the current index if its // a non-epsilon leaf. // final QName node = ((CMLeaf)nodeCur).getElement(); if (node.localpart != fEpsilonString) { fLeafList[curIndex] = (CMLeaf)nodeCur; fLeafListType[curIndex] = XMLContentSpec.CONTENTSPECNODE_LEAF; curIndex++; } } else { throw new RuntimeException("ImplementationMessages.VAL_NIICM: type="+nodeCur.type()); } return curIndex; }} // class DFAContentModel
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -