xsdfacm.java
来自「JAVA 所有包」· Java 代码 · 共 970 行 · 第 1/3 页
JAVA
970 行
// 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; } } } } // // 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; fLeafListType = null; fElemMapId = null; } /** * Calculates the follow list of the current node. * * @param nodeCur The curent node. * * @exception RuntimeException Thrown if follow list cannot be calculated. */ private void calcFollowList(CMNode nodeCur) { // Recurse as required if (nodeCur.type() == XSModelGroupImpl.MODELGROUP_CHOICE) { // Recurse only calcFollowList(((XSCMBinOp)nodeCur).getLeft()); calcFollowList(((XSCMBinOp)nodeCur).getRight()); } else if (nodeCur.type() == XSModelGroupImpl.MODELGROUP_SEQUENCE) { // Recurse first calcFollowList(((XSCMBinOp)nodeCur).getLeft()); calcFollowList(((XSCMBinOp)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 = ((XSCMBinOp)nodeCur).getLeft().lastPos(); final CMStateSet first = ((XSCMBinOp)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() == XSParticleDecl.PARTICLE_ZERO_OR_MORE || nodeCur.type() == XSParticleDecl.PARTICLE_ONE_OR_MORE) { // Recurse first calcFollowList(((XSCMUniOp)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() == XSParticleDecl.PARTICLE_ZERO_OR_ONE) { // Recurse only calcFollowList(((XSCMUniOp)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 RuntimeException Thrown on error. */ private void dumpTree(CMNode nodeCur, int level) { for (int index = 0; index < level; index++) System.out.print(" "); int type = nodeCur.type(); switch(type ) { case XSModelGroupImpl.MODELGROUP_CHOICE: case XSModelGroupImpl.MODELGROUP_SEQUENCE: { if (type == XSModelGroupImpl.MODELGROUP_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(((XSCMBinOp)nodeCur).getLeft(), level+1); dumpTree(((XSCMBinOp)nodeCur).getRight(), level+1); break; } case XSParticleDecl.PARTICLE_ZERO_OR_MORE: case XSParticleDecl.PARTICLE_ONE_OR_MORE: case XSParticleDecl.PARTICLE_ZERO_OR_ONE: { 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(((XSCMUniOp)nodeCur).getChild(), level+1); break; } case XSParticleDecl.PARTICLE_ELEMENT: { System.out.print ( "Leaf: (pos=" + ((XSCMLeaf)nodeCur).getPosition() + "), " + "(elemIndex=" + ((XSCMLeaf)nodeCur).getLeaf() + ") " ); 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()); break; } case XSParticleDecl.PARTICLE_WILDCARD: System.out.print("Any Node: "); System.out.print("firstPos="); System.out.print(nodeCur.firstPos().toString()); System.out.print(" lastPos="); System.out.println(nodeCur.lastPos().toString()); break; default: { 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 void postTreeBuildInit(CMNode nodeCur) throws RuntimeException { // Set the maximum states on this node nodeCur.setMaxStates(fLeafCount); XSCMLeaf leaf = null; int pos = 0; // Recurse as required if (nodeCur.type() == XSParticleDecl.PARTICLE_WILDCARD) { leaf = (XSCMLeaf)nodeCur; pos = leaf.getPosition(); fLeafList[pos] = leaf; fLeafListType[pos] = XSParticleDecl.PARTICLE_WILDCARD; } else if ((nodeCur.type() == XSModelGroupImpl.MODELGROUP_CHOICE) || (nodeCur.type() == XSModelGroupImpl.MODELGROUP_SEQUENCE)) { postTreeBuildInit(((XSCMBinOp)nodeCur).getLeft()); postTreeBuildInit(((XSCMBinOp)nodeCur).getRight()); } else if (nodeCur.type() == XSParticleDecl.PARTICLE_ZERO_OR_MORE || nodeCur.type() == XSParticleDecl.PARTICLE_ONE_OR_MORE || nodeCur.type() == XSParticleDecl.PARTICLE_ZERO_OR_ONE) { postTreeBuildInit(((XSCMUniOp)nodeCur).getChild()); } else if (nodeCur.type() == XSParticleDecl.PARTICLE_ELEMENT) { // Put this node in the leaf list at the current index if its // a non-epsilon leaf. leaf = (XSCMLeaf)nodeCur; pos = leaf.getPosition(); fLeafList[pos] = leaf; fLeafListType[pos] = XSParticleDecl.PARTICLE_ELEMENT; } else { throw new RuntimeException("ImplementationMessages.VAL_NIICM"); } } /** * check whether this content violates UPA constraint. * * @param subGroupHandler the substitution group handler * @return true if this content model contains other or list wildcard */ public boolean checkUniqueParticleAttribution(SubstitutionGroupHandler subGroupHandler) throws XMLSchemaException { // Unique Particle Attribution // store the conflict results between any two elements in fElemMap // 0: not compared; -1: no conflict; 1: conflict // initialize the conflict table (all 0 initially) byte conflictTable[][] = new byte[fElemMapSize][fElemMapSize]; // for each state, check whether it has overlap transitions for (int i = 0; i < fTransTable.length && fTransTable[i] != null; i++) { for (int j = 0; j < fElemMapSize; j++) { for (int k = j+1; k < fElemMapSize; k++) { if (fTransTable[i][j] != -1 && fTransTable[i][k] != -1) { if (conflictTable[j][k] == 0) { conflictTable[j][k] = XSConstraints.overlapUPA (fElemMap[j],fElemMap[k], subGroupHandler) ? (byte)1 : (byte)-1; } } } } } // report all errors for (int i = 0; i < fElemMapSize; i++) { for (int j = 0; j < fElemMapSize; j++) { if (conflictTable[i][j] == 1) { //errors.newError("cos-nonambig", new Object[]{fElemMap[i].toString(), // fElemMap[j].toString()}); // REVISIT: do we want to report all errors? or just one? throw new XMLSchemaException("cos-nonambig", new Object[]{fElemMap[i].toString(), fElemMap[j].toString()}); } } } // if there is a other or list wildcard, we need to check this CM // again, if this grammar is cached. for (int i = 0; i < fElemMapSize; i++) { if (fElemMapType[i] == XSParticleDecl.PARTICLE_WILDCARD) { XSWildcardDecl wildcard = (XSWildcardDecl)fElemMap[i]; if (wildcard.fType == XSWildcardDecl.NSCONSTRAINT_LIST || wildcard.fType == XSWildcardDecl.NSCONSTRAINT_NOT) { return true; } } } return false; } /** * Check which elements are valid to appear at this point. This method also * works if the state is in error, in which case it returns what should * have been seen. * * @param state the current state * @return a Vector whose entries are instances of * either XSWildcardDecl or XSElementDecl. */ public Vector whatCanGoHere(int[] state) { int curState = state[0]; if (curState < 0) curState = state[1]; Vector ret = new Vector(); for (int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++) { if (fTransTable[curState][elemIndex] != -1) ret.addElement(fElemMap[elemIndex]); } return ret; } } // class DFAContentModel
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?