nfastate.java
来自「java 编译器java复杂编译器,可以编译java文件的类库」· Java 代码 · 共 2,249 行 · 第 1/5 页
JAVA
2,249 行
/* * Copyright © 2002 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * California 95054, U.S.A. All rights reserved. Sun Microsystems, Inc. has * intellectual property rights relating to technology embodied in the product * that is described in this document. In particular, and without limitation, * these intellectual property rights may include one or more of the U.S. * patents listed at http://www.sun.com/patents and one or more additional * patents or pending patent applications in the U.S. and in other countries. * U.S. Government Rights - Commercial software. Government users are subject * to the Sun Microsystems, Inc. standard license agreement and applicable * provisions of the FAR and its supplements. Use is subject to license terms. * Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered * trademarks of Sun Microsystems, Inc. in the U.S. and other countries. This * product is covered and controlled by U.S. Export Control laws and may be * subject to the export or import laws in other countries. Nuclear, missile, * chemical biological weapons or nuclear maritime end uses or end users, * whether direct or indirect, are strictly prohibited. Export or reexport * to countries subject to U.S. embargo or to entities identified on U.S. * export exclusion lists, including, but not limited to, the denied persons * and specially designated nationals lists is strictly prohibited. */package org.javacc.parser;import java.util.*;public class NfaState{ public static boolean unicodeWarningGiven = false; public static int generatedStates = 0; static int idCnt = 0; static int lohiByteCnt; static int dummyStateIndex = -1; static boolean done; static boolean mark[]; static boolean stateDone[]; static boolean nonAsciiIntersections[][] = new boolean[20][20]; static Vector allStates = new Vector(); static Vector indexedAllStates = new Vector(); static Vector nonAsciiTableForMethod = new Vector(); static Hashtable equivStatesTable = new Hashtable(); static Hashtable allNextStates = new Hashtable(); static Hashtable lohiByteTab = new Hashtable(); static Hashtable stateNameForComposite = new Hashtable(); static Hashtable compositeStateTable = new Hashtable(); static Hashtable stateBlockTable = new Hashtable(); static Hashtable stateSetsToFix = new Hashtable(); public static void ReInit() { generatedStates = 0; idCnt = 0; dummyStateIndex = -1; done = false; mark = null; stateDone = null; allStates.removeAllElements(); indexedAllStates.removeAllElements(); equivStatesTable.clear(); allNextStates.clear(); compositeStateTable.clear(); stateBlockTable.clear(); stateNameForComposite.clear(); stateSetsToFix.clear(); } long[] asciiMoves = new long[2]; char[] charMoves = null; char[] rangeMoves = null; NfaState next = null; NfaState stateForCase; Vector epsilonMoves = new Vector(); String epsilonMovesString; NfaState[] epsilonMoveArray; int id; int stateName = -1; int kind = Integer.MAX_VALUE; int lookingFor; int usefulEpsilonMoves = 0; int inNextOf; private int lexState; int nonAsciiMethod = -1; int kindToPrint = Integer.MAX_VALUE; boolean dummy = false; boolean isComposite = false; int[] compositeStates = null; boolean isFinal = false; public Vector loByteVec; public int[] nonAsciiMoveIndices; int round = 0; int onlyChar = 0; char matchSingleChar; NfaState() { id = idCnt++; allStates.addElement(this); lexState = LexGen.lexStateIndex; lookingFor = LexGen.curKind; } NfaState CreateClone() { NfaState retVal = new NfaState(); retVal.isFinal = isFinal; retVal.kind = kind; retVal.lookingFor = lookingFor; retVal.lexState = lexState; retVal.inNextOf = inNextOf; retVal.MergeMoves(this); return retVal; } static void InsertInOrder(Vector v, NfaState s) { int j; for (j = 0; j < v.size(); j++) if (((NfaState)v.elementAt(j)).id > s.id) break; else if (((NfaState)v.elementAt(j)).id == s.id) return; v.insertElementAt(s, j); } private static char[] ExpandCharArr(char[] oldArr, int incr) { char[] ret = new char[oldArr.length + incr]; System.arraycopy(oldArr, 0, ret, 0, oldArr.length); return ret; } void AddMove(NfaState newState) { if (!epsilonMoves.contains(newState)) InsertInOrder(epsilonMoves, newState); } private final void AddASCIIMove(char c) { asciiMoves[c / 64] |= (1L << (c % 64)); } void AddChar(char c) { onlyChar++; matchSingleChar = c; int i; char temp; char temp1; if ((int)c < 128) // ASCII char { AddASCIIMove(c); return; } if (charMoves == null) charMoves = new char[10]; int len = charMoves.length; if (charMoves[len - 1] != 0) { charMoves = ExpandCharArr(charMoves, 10); len += 10; } for (i = 0; i < len; i++) if (charMoves[i] == 0 || charMoves[i] > c) break; if (!unicodeWarningGiven && c > 0xff && !Options.B("JAVA_UNICODE_ESCAPE") && !Options.B("USER_CHAR_STREAM")) { unicodeWarningGiven = true; JavaCCErrors.warning(LexGen.curRE, "Non-ASCII characters used in regular expression.\n" + "Please make sure you use the correct Reader when you create the parser that can handle your character set."); } temp = charMoves[i]; charMoves[i] = c; for (i++; i < len; i++) { if (temp == 0) break; temp1 = charMoves[i]; charMoves[i] = temp; temp = temp1; } } void AddRange(char left, char right) { onlyChar = 2; int i; char tempLeft1, tempLeft2, tempRight1, tempRight2; if (left < 128) { if (right < 128) { for (; left <= right; left++) AddASCIIMove(left); return; } for (; left < 128; left++) AddASCIIMove(left); } if (!unicodeWarningGiven && (left > 0xff || right > 0xff) && !Options.B("JAVA_UNICODE_ESCAPE") && !Options.B("USER_CHAR_STREAM")) { unicodeWarningGiven = true; JavaCCErrors.warning(LexGen.curRE, "Non-ASCII characters used in regular expression.\n" + "Please make sure you use the correct Reader when you create the parser that can handle your character set."); } if (rangeMoves == null) rangeMoves = new char[20]; int len = rangeMoves.length; if (rangeMoves[len - 1] != 0) { rangeMoves = ExpandCharArr(rangeMoves, 20); len += 20; } for (i = 0; i < len; i += 2) if (rangeMoves[i] == 0 || (rangeMoves[i] > left) || ((rangeMoves[i] == left) && (rangeMoves[i + 1] > right))) break; tempLeft1 = rangeMoves[i]; tempRight1 = rangeMoves[i + 1]; rangeMoves[i] = left; rangeMoves[i + 1] = right; for (i += 2; i < len; i += 2) { if (tempLeft1 == 0) break; tempLeft2 = rangeMoves[i]; tempRight2 = rangeMoves[i + 1]; rangeMoves[i] = tempLeft1; rangeMoves[i + 1] = tempRight1; tempLeft1 = tempLeft2; tempRight1 = tempRight2; } } // From hereon down all the functions are used for code generation private static boolean EqualCharArr(char[] arr1, char[] arr2) { if (arr1 == arr2) return true; if (arr1 != null && arr2 != null && arr1.length == arr2.length) { for (int i = arr1.length; i-- > 0;) if (arr1[i] != arr2[i]) return false; return true; } return false; } private boolean closureDone = false; /** This function computes the closure and also updates the kind so that * any time there is a move to this state, it can go on epsilon to a * new state in the epsilon moves that might have a lower kind of token * number for the same length. */ private void EpsilonClosure() { int i = 0; if (closureDone || mark[id]) return; mark[id] = true; // Recursively do closure for (i = 0; i < epsilonMoves.size(); i++) ((NfaState)epsilonMoves.elementAt(i)).EpsilonClosure(); Enumeration e = epsilonMoves.elements(); while (e.hasMoreElements()) { NfaState tmp = (NfaState)e.nextElement(); for (i = 0; i < tmp.epsilonMoves.size(); i++) { NfaState tmp1 = (NfaState)tmp.epsilonMoves.elementAt(i); if (tmp1.UsefulState() && !epsilonMoves.contains(tmp1)) { InsertInOrder(epsilonMoves, tmp1); done = false; } } if (kind > tmp.kind) kind = tmp.kind; } if (HasTransitions() && !epsilonMoves.contains(this)) InsertInOrder(epsilonMoves, this); } private boolean UsefulState() { return isFinal || HasTransitions(); } public boolean HasTransitions() { return (asciiMoves[0] != 0L || asciiMoves[1] != 0L || (charMoves != null && charMoves[0] != 0) || (rangeMoves != null && rangeMoves[0] != 0)); } void MergeMoves(NfaState other) { // Warning : This function does not merge epsilon moves if (asciiMoves == other.asciiMoves) { JavaCCErrors.semantic_error("Bug in JavaCC : Please send " + "a report along with the input that caused this. Thank you."); throw new Error(); } asciiMoves[0] = asciiMoves[0] | other.asciiMoves[0]; asciiMoves[1] = asciiMoves[1] | other.asciiMoves[1]; if (other.charMoves != null) { if (charMoves == null) charMoves = other.charMoves; else { char[] tmpCharMoves = new char[charMoves.length + other.charMoves.length]; System.arraycopy(charMoves, 0, tmpCharMoves, 0, charMoves.length); charMoves = tmpCharMoves; for (int i = 0; i < other.charMoves.length; i++) AddChar(other.charMoves[i]); } } if (other.rangeMoves != null) { if (rangeMoves == null) rangeMoves = other.rangeMoves; else { char[] tmpRangeMoves = new char[rangeMoves.length + other.rangeMoves.length]; System.arraycopy(rangeMoves, 0, tmpRangeMoves, 0, rangeMoves.length); rangeMoves = tmpRangeMoves; for (int i = 0; i < other.rangeMoves.length; i += 2) AddRange(other.rangeMoves[i], other.rangeMoves[i + 1]); } } if (other.kind < kind) kind = other.kind; if (other.kindToPrint < kindToPrint) kindToPrint = other.kindToPrint; isFinal |= other.isFinal; } NfaState CreateEquivState(Vector states) { NfaState newState = ((NfaState)states.elementAt(0)).CreateClone(); newState.next = new NfaState(); InsertInOrder(newState.next.epsilonMoves, ((NfaState)states.elementAt(0)).next); for (int i = 1; i < states.size(); i++) { NfaState tmp2 = ((NfaState)states.elementAt(i)); if (tmp2.kind < newState.kind) newState.kind = tmp2.kind; newState.isFinal |= tmp2.isFinal; InsertInOrder(newState.next.epsilonMoves, tmp2.next); } return newState; } private NfaState GetEquivalentRunTimeState() { Outer : for (int i = allStates.size(); i-- > 0;) { NfaState other = (NfaState)allStates.elementAt(i); if (this != other && other.stateName != -1 && kindToPrint == other.kindToPrint && asciiMoves[0] == other.asciiMoves[0] && asciiMoves[1] == other.asciiMoves[1] && EqualCharArr(charMoves, other.charMoves) && EqualCharArr(rangeMoves, other.rangeMoves)) { if (next == other.next) return other; else if (next != null && other.next != null) { if (next.epsilonMoves.size() == other.next.epsilonMoves.size()) { for (int j = 0; j < next.epsilonMoves.size(); j++) if (next.epsilonMoves.elementAt(j) != other.next.epsilonMoves.elementAt(j)) continue Outer; return other; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?