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

📄 dfa.cs

📁 c#源代码
💻 CS
📖 第 1 页 / 共 3 页
字号:
					do {changed = MakeUnique(s);} while (changed);
					melt = new Melted(targets, s);
				}
				action.target.next = null;
				action.target.state = melt.state;
			}
		}
	}
	
	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 == Node.contextTrans) a.target.state.ctx = true;
	}
	
	public static void MakeDeterministic() {
		State state;
		bool changed;
		lastSimState = lastState.nr;
		maxStates = 2 * lastSimState; // heuristic for set size in Melted.set
		FindCtxStates();
		for (state = firstState; state != null; state = state.next)
			do {changed = MakeUnique(state);} while (changed);
		for (state = firstState; state != null; state = state.next)
			MeltStates(state);
		DeleteRedundantStates();
		CombineShifts();
	}
	
	public static void PrintStates() {
		Trace.WriteLine();
		Trace.WriteLine("---------- states ----------");
		for (State state = firstState; state != null; state = state.next) {
			bool first = true;
			if (state.endOf == null) Trace.Write("               ");
			else Trace.Write("E({0,12})", Node.Name(state.endOf.name));
			Trace.Write("{0,3}:", state.nr);
			if (state.firstAction == null) Trace.WriteLine();
			for (Action action = state.firstAction; action != null; action = action.next) {
				if (first) {Trace.Write(" "); first = false;} else Trace.Write("                    ");
				if (action.typ == Node.clas) Trace.Write(((CharClass)CharClass.classes[action.sym]).name);
				else Trace.Write("{0, 3}", Ch((char)action.sym));
				for (Target targ = action.target; targ != null; targ = targ.next)
					Trace.Write(" {0, 3}", targ.state.nr);
				if (action.tc == Node.contextTrans) Trace.WriteLine(" context"); else Trace.WriteLine();
			}
		}
		Trace.WriteLine();
		Trace.WriteLine("---------- character classes ----------");
		CharClass.WriteClasses();
	}
	
	static void GenComBody(Comment com) {
		gen.WriteLine(  "\t\t\tfor(;;) {");
		gen.Write    (  "\t\t\t\tif ({0}) ", ChCond(com.stop[0])); gen.WriteLine("{");
		if (com.stop.Length == 1) {
			gen.WriteLine("\t\t\t\t\tlevel--;");
			gen.WriteLine("\t\t\t\t\tif (level == 0) { oldEols = line - line0; NextCh(); return true; }");
			gen.WriteLine("\t\t\t\t\tNextCh();");
		} else {
			gen.WriteLine("\t\t\t\t\tNextCh();");
			gen.WriteLine("\t\t\t\t\tif ({0}) {{", ChCond(com.stop[1]));
			gen.WriteLine("\t\t\t\t\t\tlevel--;");
			gen.WriteLine("\t\t\t\t\t\tif (level == 0) { oldEols = line - line0; NextCh(); return true; }");
			gen.WriteLine("\t\t\t\t\t\tNextCh();");
			gen.WriteLine("\t\t\t\t\t}");
		}
		if (com.nested) {
			gen.Write    ("\t\t\t\t}"); gen.Write(" else if ({0}) ", ChCond(com.start[0])); gen.WriteLine("{");
			if (com.start.Length == 1)
				gen.WriteLine("\t\t\t\t\tlevel++; NextCh();");
			else {
				gen.WriteLine("\t\t\t\t\tNextCh();");
				gen.Write    ("\t\t\t\t\tif ({0}) ", ChCond(com.start[1])); gen.WriteLine("{");
				gen.WriteLine("\t\t\t\t\t\tlevel++; NextCh();");
				gen.WriteLine("\t\t\t\t\t}");
			}
		}
		gen.WriteLine(    "\t\t\t\t} else if (ch == Buffer.EOF) return false;");
		gen.WriteLine(    "\t\t\t\telse NextCh();");
		gen.WriteLine(    "\t\t\t}");
	}
	
	static void GenComment(Comment com, int i) {
		gen.WriteLine();
		gen.Write    ("\tstatic bool Comment{0}() ", i); gen.WriteLine("{");
		gen.WriteLine("\t\tint level = 1, line0 = line, lineStart0 = lineStart;");
		if (com.start.Length == 1) {
			gen.WriteLine("\t\tNextCh();");
			GenComBody(com);
		} else {
			gen.WriteLine("\t\tNextCh();");
			gen.Write    ("\t\tif ({0}) ", ChCond(com.start[1])); gen.WriteLine("{");
			gen.WriteLine("\t\t\tNextCh();");
			GenComBody(com);
			gen.WriteLine("\t\t} else {");
			gen.WriteLine("\t\t\tif (ch==EOL) {line--; lineStart = lineStart0;}");
			gen.WriteLine("\t\t\tpos = pos - 2; Buffer.Pos = pos+1; NextCh();");
			gen.WriteLine("\t\t}");
			gen.WriteLine("\t\treturn false;");
		}
		gen.WriteLine("\t}");
	}
	
	static void CopyFramePart(string stop) {
		char startCh = stop[0];
		int endOfStopString = stop.Length-1;
		int ch = fram.ReadByte();
		while (ch != EOF)
			if (ch == startCh) {
				int i = 0;
				do {
					if (i == endOfStopString) return; // stop[0..i] found
					ch = fram.ReadByte(); i++;
				} while (ch == stop[i]);
				// stop[0..i-1] found; continue with last read character
				gen.Write(stop.Substring(0, i));
			} else {
				gen.Write((char)ch); ch = fram.ReadByte();
			}
		Errors.Exception(" -- incomplete or corrupt scanner frame file");
	}
	
	static string SymName(Symbol sym) {
		if (Char.IsLetter(sym.name[0])) { // real name value is stored in Tab.literals
			foreach (DictionaryEntry e in Tab.literals)
				if ((Symbol)e.Value == sym) return (string)e.Key;
		}
		return sym.name;
	}
	
	static void GenLiterals () {
		if (ignoreCase) {
			gen.WriteLine("\t\tswitch (t.val.ToLower()) {");
		} else {
			gen.WriteLine("\t\tswitch (t.val) {");
		}
		foreach (Symbol sym in Symbol.terminals) {
			if (sym.tokenKind == Symbol.litToken) {
				string name = SymName(sym);
				if (ignoreCase) name = name.ToLower();
				// sym.name stores literals with quotes, e.g. "\"Literal\""
				gen.WriteLine("\t\t\tcase {0}: t.kind = {1}; break;", name, sym.n);
			}
		}
		gen.WriteLine("\t\t\tdefault: break;");
		gen.Write("\t\t}");
	}
	
	static void WriteState(State state) {
		Symbol endOf = state.endOf;
		gen.WriteLine("\t\t\tcase {0}:", state.nr);
		bool ctxEnd = state.ctx;
		for (Action action = state.firstAction; action != null; action = action.next) {
			if (action == state.firstAction) gen.Write("\t\t\t\tif (");
			else gen.Write("\t\t\t\telse if (");
			if (action.typ == Node.chr) gen.Write(ChCond((char)action.sym));
			else PutRange(CharClass.Set(action.sym));
			gen.Write(") {");
			if (action.tc == Node.contextTrans) {
				gen.Write("apx++; "); ctxEnd = false;
			} else if (state.ctx)
				gen.Write("apx = 0; ");
			if (ignoreCase) gen.Write("buf.Append(valCh); "); else gen.Write("buf.Append(ch); ");
			gen.Write("NextCh(); goto case {0};", action.target.state.nr);
			gen.WriteLine("}");
		}
		if (state.firstAction == null)
			gen.Write("\t\t\t\t{");
		else
			gen.Write("\t\t\t\telse {");
		if (ctxEnd) { // final context state: cut appendix
			gen.WriteLine();
			gen.WriteLine("\t\t\t\t\tbuf.Length = buf.Length - apx;");
			gen.WriteLine("\t\t\t\t\tpos = pos - apx - 1; line = t.line;");
			gen.WriteLine("\t\t\t\t\tBuffer.Pos = pos+1; NextCh();");
			gen.Write(  	"\t\t\t\t\t");
		}
		if (endOf == null) {
			gen.WriteLine("t.kind = noSym; goto done;}");
		} else {
			gen.Write("t.kind = {0}; ", endOf.n);
			if (endOf.tokenKind == Symbol.classLitToken) {
				gen.WriteLine("t.val = buf.ToString(); CheckLiteral(); return t;}");
			} else {
				gen.WriteLine("goto done;}");
			}
		}
	}
	
	static void FillStartTab(int[] startTab) {
		for (Action action = firstState.firstAction; action != null; action = action.next) {
			int targetState = action.target.state.nr;
			if (action.typ == Node.chr) startTab[action.sym] = targetState;
			else {
				BitArray s = CharClass.Set(action.sym);
				for (int i = 0; i < s.Count; i++)
					if (s[i]) startTab[i] = targetState;
			}
		}
	}
	
	static void OpenGen(bool backUp) { /* pdt */
		try {
			string fn = srcDir + "Scanner.cs"; /* pdt */
			if (File.Exists(fn) && backUp) File.Copy(fn, fn + ".old", true);
			gen = new StreamWriter(new FileStream(fn, FileMode.Create)); /* pdt */
		} catch (IOException) {
			Errors.Exception("-- Cannot generate scanner file");
		}
	}

	public static void WriteScanner() {
		int i, j;
		int[] startTab = new int[CharClass.charSetSize];
		string fr = srcDir + "Scanner.frame";  /* pdt */
		if (!File.Exists(fr)) {
			if (Tab.frameDir != null) fr = Tab.frameDir.Trim() + Path.DirectorySeparatorChar + "Scanner.frame";
			if (!File.Exists(fr)) Errors.Exception("-- Cannot find Scanner.frame");
		}
		try {
			fram = new FileStream(fr, FileMode.Open, FileAccess.Read, FileShare.Read);
		} catch (FileNotFoundException) {
			Errors.Exception("-- Cannot open Scanner.frame.");
		}
		OpenGen(true); /* pdt */
		if (dirtyDFA) MakeDeterministic();
		FillStartTab(startTab);
		CopyFramePart("-->begin");
		if (!srcName.ToLower().EndsWith("coco.atg")) {
			gen.Close(); OpenGen(false); /* pdt */
		}
		CopyFramePart("-->namespace");
		/* AW add namespace, if it exists */
		if (Tab.nsName != null && Tab.nsName.Length > 0) {
			gen.Write("namespace ");
			gen.Write(Tab.nsName);
			gen.Write(" {");
		}
		CopyFramePart("-->declarations");
		gen.WriteLine("\tconst int charSetSize = {0};", CharClass.charSetSize);
		gen.WriteLine("\tconst int maxT = {0};", Symbol.terminals.Count - 1);
		gen.WriteLine("\tconst int noSym = {0};", Tab.noSym.n);
		gen.WriteLine("\tstatic short[] start = {");
		for (i = 0; i < CharClass.charSetSize / 16; i++) {
			gen.Write("\t");
			for (j = 0; j < 16; j++)
				gen.Write("{0,3},", startTab[16*i+j]);
			gen.WriteLine();
		}
		gen.WriteLine("\t  -1};");                                   /* pdt */
		if (ignoreCase)
			gen.Write("\tstatic char valCh;       // current input character (for token.val)");
		CopyFramePart("-->initialization");
		gen.WriteLine("\t\tignore = new BitArray(charSetSize+1);");  /* pdt */
		gen.Write("\t\t");
		if (Tab.ignored == null) gen.Write("ignore[' '] = true;");
		else {
			j = 0;
			for (i = 0; i < Tab.ignored.Count; i++)
				if (Tab.ignored[i]) {
					gen.Write("ignore[{0}] = true; ", i);
					if (++j % 4 == 0) { gen.WriteLine(); gen.Write("\t\t"); }
				}
		} 
		CopyFramePart("-->casing");
		if (ignoreCase) {
			gen.WriteLine("\t\tvalCh = ch;");
			gen.Write    ("\t\tif (ch != Buffer.EOF) ch = char.ToLower(ch);");
		}
		CopyFramePart("-->comments");
		Comment com = Comment.first; i = 0;
		while (com != null) {
			GenComment(com, i);
			com = com.next; i++;
		}
		CopyFramePart("-->literals"); GenLiterals();
		CopyFramePart("-->scan1");
		if (Comment.first!=null) {
			gen.Write("\t\tif (");
			com = Comment.first; i = 0;
			while (com != null) {
				gen.Write(ChCond(com.start[0]));
				gen.Write(" && Comment{0}()", i);
				if (com.next != null) gen.Write(" ||");
				com = com.next; i++;
			}
			gen.Write(") return NextToken();");
		}
		if (hasCtxMoves) { gen.WriteLine(); gen.Write("\t\tint apx = 0;"); } /* pdt */
		CopyFramePart("-->scan2");
		if (ignoreCase) gen.Write("\t\tbuf.Append(valCh); NextCh();"); 
		else gen.Write("\t\tbuf.Append(ch); NextCh();");
		CopyFramePart("-->scan3");
		for (State state = firstState.next; state != null; state = state.next)
			WriteState(state);
		CopyFramePart("$$$");
		/* AW 12-20-02 close namespace, if it exists */
		if (Tab.nsName != null && Tab.nsName.Length > 0) gen.Write("}");
		gen.Close();
	}
	
	public static void Init (string file, string dir) {
		srcName = file;
		srcDir = dir;
		firstState = null; lastState = null; State.lastNr = -1;
		firstState = NewState();
		Melted.first = null; Comment.first = null;
		ignoreCase = false;
		dirtyDFA = false;
		hasCtxMoves = false;
	}
	
} // end DFA

} // end namespace

⌨️ 快捷键说明

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