⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dfa.java

📁 cocorj09-一个Java语言分析器
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
			break;
		}
		case Tab.iter: {
			FindTrans(Math.abs(n.next), false, mark); FindTrans(n.p1, false, mark);
			break;
		}
		case Tab.alt: {
			FindTrans(n.p1, false, mark); FindTrans(n.p2, false, mark);
			break;
		}
	}
}

static void ConvertToStates(int p, int sp) {
	curGraph = p; curSy = sp;
	if (Tab.DelGraph(curGraph)) Parser.SemError(20);
	NumberNodes(curGraph, firstState);
	FindTrans(curGraph, true, new BitSet(512));
}

static int MatchedDFA(String s, int sp) {
		State state, to;
		Action a;
		int i, matchedSp, len = s.length() - 1;
		// s has quotes
		state = firstState;
		for (i=1; i<len; i++) { // try to match s against existing DFA
			a = state.TheAction(s.charAt(i));
			if (a==null) break;
			state = a.target.state;
		}
		for (;i<len; i++) { // make new DFA for s[i..len-1]
			to = NewState();
			NewTransition(state, to, Tab.chr, s.charAt(i), Tab.normTrans);
			state = to;
		}
		matchedSp = state.endOf;
		if (state.endOf==Tab.noSym) state.endOf = sp;
		return matchedSp;
	}

	private static void SplitActions(State state, Action a, Action b) {
		Action c; BitSet seta, setb, setc;
		seta = a.Symbols(); setb = b.Symbols();
		if (seta.equals(setb)) {
			a.AddTargets(b);
			state.DetachAction(b);
		} else if (Sets.Includes(seta, setb)) {
			setc = (BitSet) seta.clone(); Sets.Differ(setc, setb);
			b.AddTargets(a);
			a.ShiftWith(setc);
		} else if (Sets.Includes(setb, seta)) {
			setc = (BitSet) setb.clone(); Sets.Differ(setc, seta);
			a.AddTargets(b);
			b.ShiftWith(setc);
		} else {
			setc = (BitSet) seta.clone(); setc.and(setb);
			Sets.Differ(seta, setc);
			Sets.Differ(setb, setc);
			a.ShiftWith(seta);
			b.ShiftWith(setb);
			c = new Action(0, 0, 0);
			c.AddTargets(a);
			c.AddTargets(b);
			c.ShiftWith(setc);
			state.AddAction(c);
		}
	}

	private static boolean Overlap(Action a, Action b) {
		BitSet seta, setb;
		if (a.typ==Tab.chr)
			if (b.typ==Tab.chr) return a.sym==b.sym;
			else {setb = Tab.Class(b.sym); return setb.get(a.sym);}
		else {
			seta = Tab.Class(a.sym);
			if (b.typ==Tab.chr) return seta.get(b.sym);
			else {setb = Tab.Class(b.sym); return !Sets.Different(seta, setb);}
		}
	}

	private static boolean MakeUnique(State state) { // return true if actions were split
		boolean changed = false;
		for (Action a=state.firstAction; a!=null; a=a.next)
			for (Action b=a.next; b!=null; b=b.next)
				if (Overlap(a, b)) {SplitActions(state, a, b); changed = true;}
		return changed;
	}

	private static boolean MeltStates(State state) {
		boolean changed, correct = true;
		StateSet states;
		State s;
		Target targ;
		Melted melt;
		for (Action action=state.firstAction; action!=null; action=action.next) {
			if (action.target.next != null) {
				states = action.GetTargetStates();
				correct = correct && states.correct;
				melt = Melted.StateWithSet(states.set);
				if (melt==null) {
					s = NewState(); s.endOf = states.endOf; s.ctx = states.ctx;
					for (targ=action.target; targ!=null; targ=targ.next)
						s.MeltWith(targ.state);
					do {changed = MakeUnique(s);} while (changed);
					melt = new Melted(states.set, s);
				}
				action.target.next = null;
				action.target.state = melt.state;
			}
		}
		return correct;
	}

	private static void FindCtxStates() {
		for (State state=firstState; state!=null; state=state.next)
			for (Action a=state.firstAction; a!=null; a=a.next)
				if (a.tc==Tab.contextTrans) a.target.state.ctx = true;
	}

	static boolean MakeDeterministic() {
		State state;
		boolean changed, correct;
		lastSimState = lastState.nr;
		FindCtxStates();
		for (state=firstState; state!=null; state=state.next)
			do {changed = MakeUnique(state);} while (changed);
		correct = true;
		for (state=firstState; state!=null; state=state.next)
			correct = MeltStates(state) && correct;
		DeleteRedundantStates();
		CombineShifts();
		return correct;
	}

	static void PrintStates() {
		Action action; Target targ;
		BitSet set;
		boolean first;
		Trace.println("\n---------- states ----------");
		for (State state=firstState; state!=null; state=state.next) {
			first = true;
			if (state.endOf==Tab.noSym) Trace.print("     ");
			else Trace.print("E(" + Int(state.endOf, 2) + ")");
			Trace.print(Int(state.nr, 3) + ":");
			if (state.firstAction==null) Trace.println();
			for (action=state.firstAction; action!=null; action=action.next) {
				if (first) {Trace.print(" "); first = false;} else Trace.print("          ");
				if (action.typ==Tab.clas) Trace.print(Tab.ClassName(action.sym));
				else Trace.print(Ch((char)action.sym));
				for (targ=action.target; targ!=null; targ=targ.next)
					Trace.print(" " + targ.state.nr);
				if (action.tc==Tab.contextTrans) Trace.println(" context"); else Trace.println();
			}
		}
		Trace.println("\n---------- character classes ----------");
		for (int i=0; i<=Tab.maxC; i++) {
			set = Tab.Class(i);
			Trace.println(Tab.ClassName(i) + ": " + set.toString());
		}
	}

	private static void GenComBody(Comment com) {
		gen.println("\t\t\t\tfor(;;) {");
		gen.println("\t\t\t\t\tif (" + ChCond(com.stop.charAt(0)) + ") {");
		if (com.stop.length()==1) {
			gen.println("\t\t\t\t\t\tlevel--;");
			gen.println("\t\t\t\t\t\tif (level == 0) {NextCh(); return true;}");
			gen.println("\t\t\t\t\t\tNextCh();");
		} else {
			gen.println("\t\t\t\t\t\tNextCh();");
			gen.println("\t\t\t\t\t\tif (" + ChCond(com.stop.charAt(1)) + ") {");
			gen.println("\t\t\t\t\t\t\tlevel--;");
			gen.println("\t\t\t\t\t\t\tif (level == 0) {NextCh(); return true;}");
			gen.println("\t\t\t\t\t\t\tNextCh();");
			gen.println("\t\t\t\t\t\t}");
		}
		if (com.nested) {
			gen.println("\t\t\t\t\t} else if (" + ChCond(com.start.charAt(0)) + ") {");
			if (com.start.length()==1)
				gen.println("\t\t\t\t\t\tlevel++; NextCh();");
			else {
				gen.println("\t\t\t\t\t\tNextCh();");
				gen.println("\t\t\t\t\t\tif (" + ChCond(com.start.charAt(1)) + ") {");
				gen.println("\t\t\t\t\t\t\tlevel++; NextCh();");
				gen.println("\t\t\t\t\t\t}");
			}
		}
		gen.println("\t\t\t\t\t} else if (ch == EOF) return false;");
		gen.println("\t\t\t\t\telse NextCh();");
		gen.println("\t\t\t\t}");
	}

	private static void GenComment(Comment com) {
		gen.println("\t\tif (" + ChCond(com.start.charAt(0)) + ") {");
		if (com.start.length()==1) {
			gen.println("\t\t\tNextCh();");
			GenComBody(com);
		} else {
			gen.println("\t\t\tNextCh();");
			gen.println("\t\t\tif (" + ChCond(com.start.charAt(1)) + ") {");
			gen.println("\t\t\t\tNextCh();");
			GenComBody(com);
			gen.println("\t\t\t} else {");
			gen.println("\t\t\t\tif (ch == CR || ch == LF) {line--; lineStart = lineStart0;}");
			gen.println("\t\t\t\tpos = pos - 2; Buffer.Set(pos+1); NextCh();");
			gen.println("\t\t\t}");
		}
		gen.println("\t\t}");
	}

	private static void CopyFramePart(String stop) {
		int ch, i;
		int last = 0;
		int startCh = stop.charAt(0);
		int high = stop.length() - 1;
		try {
			ch = fram.read();
			while (ch!=EOF)
				if (ch==startCh) {
					i = 0;
					do {
						if (i==high) return; // stop[0..i] found
						ch = fram.read(); i++;
					} while (ch==stop.charAt(i));
					// stop[0..i-1] found; continue with last read character
					gen.print(stop.substring(0, i));
				} else if (ch==LF) { if (last!=CR) gen.println(); last = ch; ch = fram.read();
				} else if (ch==CR) { gen.println(); last = ch; ch = fram.read();
				} else {
					gen.print((char)ch); last = ch; ch = fram.read();
				}
		} catch (IOException e) {
			Scanner.err.Exception("-- error reading Scanner.frame");
		}
	}

	private static void PrintTermName(int n) {
		if (Tab.sy[n].symName == null) gen.print(n);
		else gen.print("SYM." + Tab.sy[n].symName);
	}

	private static void GenLiterals(boolean ignoreCase) {
		int i, j, k;
		char ch;
		Symbol sym;
		String[] key = new String[Tab.maxTerminals];
		int[] knr = new int[Tab.maxTerminals];
		// sort literal list (don't consider eofSy)
		k = 0;
		for (i=1; i<=Tab.maxT; i++) {
			sym = Tab.Sym(i);
			if (sym.struct==Tab.litToken) {
				for (j=k-1; j>=0 && sym.name.compareTo(key[j]) < 0; j--) {
					key[j+1] = key[j]; knr[j+1] = knr[j];
				}
				key[j+1] = sym.name; knr[j+1] = i; k++;
			}
		}
		// print switch statement
		i = 0;
		if (ignoreCase) gen.println("\t\tt.val = buf.toString().toUpperCase();");
		else gen.println("\t\tt.val = buf.toString();");
		gen.println("\t\tswitch (t.val.charAt(0)) {");
		while (i < k) {
			ch = key[i].charAt(1); // key[i, 0] is quote
			gen.println("\t\t\tcase " + Ch(ch) + ": {");
			j = i;
			do {
				if (i==j) gen.print("\t\t\t\tif ");
				else gen.print("\t\t\t\telse if ");
				gen.print("(t.val.equals(" + key[i] + ")) t.kind = ");
				PrintTermName(knr[i]);
				gen.println(";");
				i++;
			} while (i<k && key[i].charAt(1)==ch);
			gen.println("\t\t\t\tbreak;}");
		}
		gen.print("\t\t}");
	}

	private static void WriteState(State state) {
		Action action;
		Symbol sym;
		boolean ctxEnd;
		int endOf = state.endOf;
		if (endOf > Tab.maxT)
			endOf = Tab.maxT + Tab.maxSymbols - endOf; // pragmas have been moved
		gen.println("\t\t\t\tcase " + state.nr + ":");
		ctxEnd = state.ctx;
		for (action=state.firstAction; action!=null; action=action.next) {
			if (action==state.firstAction) gen.print("\t\t\t\t\tif (");
			else gen.print("\t\t\t\t\telse if (");
			if (action.typ==Tab.chr) gen.print(ChCond((char)action.sym));
			else {PutRange(Tab.Class(action.sym));}
			gen.print(") {");
			if (action.target.state != state)
				gen.print("state = " + action.target.state.nr + "; ");
			if (action.tc == Tab.contextTrans) {
				gen.print("apx++; "); ctxEnd = false;
			} else if (state.ctx)
				gen.print("apx = 0; ");
			gen.println("break;}");
		}
		if (state.firstAction != null) gen.print("\t\t\t\t\telse ");
		if (endOf==Tab.noSym)
			gen.println("{t.kind = noSym; break loop;}");
		else { // final state
			if (state.firstAction==null)
				gen.print("\t\t\t\t\t{");
			else
				gen.print("{");
			sym = Tab.Sym(endOf);
			if (ctxEnd) { // final context state: cut appendix
				gen.println("pos = pos - apx - 1;");
				gen.println("\t\t\t\t\tbuf.setLength(buf.length() - apx);");
				gen.println("\t\t\t\t\tline = t.line; Buffer.Set(pos+1); NextCh();");
				gen.print("\t\t\t\t\t");
			}
			gen.print("t.kind = ");
			PrintTermName(endOf);
			gen.print("; ");
			if (sym.struct==Tab.classLitToken)
				gen.print("CheckLiteral(buf); ");
			gen.println("break loop;}");
		}
	}

	private static void FillStartTab(int[] startTab) {
		int targetState, max, i;
		BitSet s;
		startTab[0] = State.lastNr + 1; // eof
		for (Action action= firstState.firstAction; action!=null; action=action.next) {
			targetState = action.target.state.nr;
			if (action.typ==Tab.chr) startTab[action.sym] = targetState;
			else {
				s = Tab.Class(action.sym); max = s.size();
				for (i=0; i<=max; i++)
					if (s.get(i)) startTab[i] = targetState;
			}
		}
	}

	static void WriteScanner(boolean ignoreCase) {
		int i, j, max;
		int[] startTab = new int[128];
		Comment com;
		Symbol root = Tab.Sym(Tab.gramSy);

// Portability - Use the following for Java 1.0
//		try {fram = new BufferedInputStream(new FileInputStream("Scanner.frame"));}
// Portability - Use the following for Java 1.1
//		try {fram = new BufferedReader(new FileReader("Scanner.frame"));}

		try {fram = new BufferedReader(new FileReader("Scanner.frame"));}

		catch (IOException e) {
			Scanner.err.Exception("-- cannot open Scanner.frame. " +
			"Must be in application directory.");
		}
		try {

// Portability - Use the following for Java 1.0
//			gen = new PrintStream(new BufferedOutputStream(new FileOutputStream(srcDir + "Scanner.java")));
// Portability - Use the following for Java 1.1
//			gen = new PrintWriter(new BufferedWriter(new FileWriter(srcDir + "Scanner.java")));

			gen = new PrintWriter(new BufferedWriter(new FileWriter(srcDir + "Scanner.java")));

		} catch (IOException e) {
			Scanner.err.Exception("-- cannot generate scanner file");
		}
		FillStartTab(startTab);
		gen.println("package " + root.name + ";");
		CopyFramePart("-->declarations");
		gen.println("\tprivate static final int noSym = " + Tab.maxT + ";");
		gen.println("\tprivate static final int[] start = {");
		for (i=0; i<8; i++) {
			gen.print("\t");
			for (j=0; j<16; j++)
				gen.print(Int(startTab[16*i+j], 3) + ",");
			gen.println();
		}
		gen.println("\t  0};");
		CopyFramePart("-->initialization");
		gen.print("\t\t");
		max = Tab.ignored.size(); j = 0;
		for (i=0; i<=max; i++)
			if (Tab.ignored.get(i)) {
				gen.print("ignore.set(" + i + "); ");
				if (++j % 4 == 0) {gen.println(); gen.print("\t\t");}
			}
		CopyFramePart("-->scan0");
		if (ignoreCase) gen.print("\t\tch = Character.toUpperCase(strCh);");
		else gen.print("\t\tch = strCh;");
		CopyFramePart("-->comment");
		for (com=Comment.first; com!=null; com=com.next) GenComment(com);
		CopyFramePart("-->literals"); GenLiterals(ignoreCase);
		CopyFramePart("-->scan1");
		if (Comment.first!=null) {
			gen.print("\t\tif ((");
			for (com=Comment.first; com!=null; com=com.next) {
				gen.print(ChCond(com.start.charAt(0)));
				if (com.next != null) gen.print(" || ");
			}
			gen.print(") && Comment()) return Scan();");
		}
		CopyFramePart("-->scan2");
		for (State state=firstState.next; state!=null; state=state.next)
			WriteState(state);
		gen.println("\t\t\t\tcase "+(State.lastNr+1)+":");
		gen.print("\t\t\t\t\t{t.kind = ");
		PrintTermName(0); gen.print("; break loop;}");
		CopyFramePart("-->scan3");
		if (ignoreCase) gen.print("\t\tt.val = t.str.toUpperCase();");
		else gen.print("\t\tt.val = t.str;");
		CopyFramePart("$$$");
		gen.flush();
	}

	static void Init(String dir) {
		srcDir = dir;
		firstState = null; lastState = null; State.lastNr = -1;
		firstState = NewState();
		Melted.first = null; Comment.first = null;
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -