public void ParseDeclaration(DfaState dfa) { _varibalesTree = new VariableTreeItem("root"); dfa.ForEachNR((state) => { _varibalesTree.AddVariables(state); }); }
private void SerializeStates(XmlWriter writer, Dictionary <IMark, int> marks) { int countStates = 0; if (start != null) { start.ForEachNR((state) => { state.Index = countStates++; }); } writer.WriteStartElement("States"); start.ForEachNR( (state) => { writer.WriteStartElement("State"); writer.WriteAttributeString("id", state.Index.ToString()); writer.WriteStartElement("Transitions"); for (int i = 0; i <= 255; i++) { var next = state.GetTransited((byte)i); if (next != null) { writer.WriteStartElement("Transition"); writer.WriteAttributeString("char", i.ToString()); writer.WriteAttributeString("stateId", next.Index.ToString()); writer.WriteEndElement(); } } writer.WriteEndElement(); writer.WriteStartElement("Marks"); foreach (var mark in state.AllMarks) { writer.WriteElementString("Id", marks[mark].ToString()); } writer.WriteEndElement(); writer.WriteEndElement(); }); writer.WriteEndElement(); }
public static DfaState Intersect(DfaState dfa1, DfaState dfa2) { var list1 = new List <DfaState>(); var list2 = new List <DfaState>(); dfa1.ForEachNR((state) => { list1.Add(state); }); dfa2.ForEachNR((state) => { list2.Add(state); }); var states = new DfaState[list1.Count, list2.Count]; for (int i = 0; i < list1.Count; i++) { for (int j = 0; j < list2.Count; j++) { list1[i].Index = i; list2[j].Index = j; var ids = new List <int>(); ids.AddRange(list1[i].NfaIds); ids.AddRange(list2[j].NfaIds); states[i, j] = new DfaState(ids.ToArray()); } } for (int i = 0; i < list1.Count; i++) { for (int j = 0; j < list2.Count; j++) { var state = states[i, j]; for (int ch = 0; ch <= 255; ch++) { byte key = (byte)ch; var node1 = list1[i].Transition[key]; var node2 = list2[j].Transition[key]; if (node1 != null && node2 != null) { state.AddTransition(key, states[node1.Index, node2.Index]); } } } } var result = states[0, 0]; //result.Minimize4(false); return(result); }
public static DfaState Intersect(DfaState dfa1, DfaState dfa2) { var list1 = new List<DfaState>(); var list2 = new List<DfaState>(); dfa1.ForEachNR((state) => { list1.Add(state); }); dfa2.ForEachNR((state) => { list2.Add(state); }); var states = new DfaState[list1.Count, list2.Count]; for (int i = 0; i < list1.Count; i++) for (int j = 0; j < list2.Count; j++) { list1[i].Index = i; list2[j].Index = j; var ids = new List<int>(); ids.AddRange(list1[i].NfaIds); ids.AddRange(list2[j].NfaIds); states[i, j] = new DfaState(ids.ToArray()); } for (int i = 0; i < list1.Count; i++) for (int j = 0; j < list2.Count; j++) { var state = states[i, j]; for (int ch = 0; ch <= 255; ch++) { byte key = (byte)ch; var node1 = list1[i].Transition[key]; var node2 = list2[j].Transition[key]; if (node1 != null && node2 != null) state.AddTransition(key, states[node1.Index, node2.Index]); } } var result = states[0, 0]; //result.Minimize4(false); return result; }
private void GenerateSwitch(DfaState dfa, int errorState, SwitchMode mode) { _main.WriteLine("switch(state)"); _main.WriteLine("{"); dfa.ForEachNR((state) => { _main.WriteLine("case State{0}:", state.Index); if (mode == SwitchMode.ActionJump || mode == SwitchMode.ActionOnly) { foreach (var nfa1 in state.AllMarks) { if (nfa1.Mark == Marks.ResetRange) { var name = GetVarname(nfa1.Name, ""); // #1 Do NOT use SetDefaultValue, it clears bytes too -> wrong! // #1 Should to create special method for this // #2 Ok for IndexArray optimimized _main.WriteLine("{0}." + GetSetDefauleValueCall() + ";", name); } if (nfa1.Mark == Marks.ResetRangeIfInvalid) { var name = GetVarname(nfa1.Name, ""); _main.WriteLine("if({0}.End <0) {0}.Begin = int.MinValue;", name); } if (nfa1.Mark == Marks.Custom) { var name = GetVarname(nfa1.Name, ""); _main.WriteLine(nfa1.Value.Replace("Var", name)); } } foreach (var nfa1 in state.AllMarks)//.NfaStates) { if (nfa1.Mark == Marks.Count) _main.WriteLine("{0}++;", GetVarname(nfa1.Name, "Count.")); } foreach (var mark in state.AllMarks) { if (mark.Mark == Marks.ContinueRange) { var ifv = GetCountComparation(RemoveExtraInfo(mark.Name)); if (ifv != "") ifv += " && "; _main.WriteLine("if({1}{0}.End == i-1) {0}.End = i;", GetVarname(mark.Name, ""), ifv); } } foreach (var nfa1 in state.AllMarks)//.NfaStates) { switch (nfa1.Mark) { case Marks.BeginRange: case Marks.EndRange: case Marks.EndRangeIfInvalid: var varName = GetVarname(nfa1.Name, "") + ((nfa1.Mark == Marks.BeginRange) ? ".Begin" : ".End"); var condition = GetCountComparation(RemoveExtraInfo(nfa1.Name)); if (nfa1.Mark != Marks.EndRange) { if (condition != "") condition += " && "; condition = varName + " < 0"; } if (condition != "") _main.Write("if({0})", condition); _main.Write("{0} = i", varName); if (nfa1.Offset != 0) _main.Write("{0} {1}", (nfa1.Offset > 0) ? "+" : "-", Math.Abs(nfa1.Offset)); _main.WriteLine(";"); break; case Marks.BoolEx: _main.WriteLine("boolExPosition = i;"); goto case Marks.Bool; case Marks.Bool: _main.WriteLine("{0} = true;", GetVarname(nfa1.Name, "")); break; case Marks.BoolExNot: _main.WriteLine("if(boolExPosition == i-1) {0} = false;", GetVarname(nfa1.Name, "")); break; case Marks.Final: _main.WriteLine("Final = true;"); break; } } //if (mode == SwitchMode.ActionJump || mode == SwitchMode.ActionOnly) //{ if (state.HasMarks) { foreach (var decimal1 in state.Decimals) _main.WriteLine("{0} = ({0} << 1) * 5 + bytes[i - 1] - 48;", GetVarname(decimal1.Name, "")); foreach (var hex1 in state.Hexes) _main.WriteLine("{0} = ({0} << 4) + AsciiCodeToHex[bytes[i - 1]];", GetVarname(hex1.Name, "")); } //} if (state.Consts.Count > 0) { foreach (var pair in state.ConstNameValues) { var ifv = GetCountComparation(RemoveExtraInfo(pair.Key)); if (ifv != "") _main.Write("if(" + ifv + ") "); _main.WriteLine("{0} = {1}s.{2};", AddCountPrefix(RemoveExtraInfo(pair.Key)), RemoveBrackets(VariableInfo.GetShortName(pair.Key)), pair.Value); } } } if (state.IsFinal) { if (mode == SwitchMode.JumpOnly) { _main.WriteLine("state = table{0}[bytes[i]];", state.Index); _main.WriteLine("break;"); } else { _main.WriteLine("goto exit1;"); } } else { if (mode == SwitchMode.ActionJump || mode == SwitchMode.JumpOnly) _main.WriteLine("state = table{0}[bytes[i]];", state.Index); _main.WriteLine("break;"); } }); // ForEach state _main.WriteLine("case State{0}:", errorState); if (mode == SwitchMode.ActionJump || mode == SwitchMode.ActionOnly) _main.WriteLine("i--;"); _main.WriteLine("Error = true;"); _main.WriteLine("goto exit1;"); _main.WriteLine("}"); }
private void GenerateTables(DfaState dfa, int errorState) { if (dfa != null) { _main.WriteLine("#region States Tables"); dfa.ForEachNR((state) => { _main.WriteLine("private static int[] table{0};", state.Index); int next; DfaState nextState; for (int i = 0; i <= byte.MaxValue; i++) { next = errorState; nextState = state.Transition[i]; if (nextState != null) next = nextState.Index; _table.Write((Int32)next); } }); _main.WriteLine("#endregion"); } else _main.WriteLine("// NO TABLES"); }
public void Generate(string filename, string classname, string namespace1, DfaState dfa, bool writeDfaFile) { using (_main = File.CreateText(filename + ".cs")) using (_table = new BinaryWriter((writeDfaFile) ? new DeflateStream( new BufferedStream(File.Create(namespace1 + ".dfa"), 65536), CompressionMode.Compress) : Stream.Null)) { if (dfa != null) ParseDeclaration(dfa); WriteIfOptimizedStatement(); _main.WriteLine("using System;"); _main.WriteLine("using System.Text;"); _main.WriteLine("using System.IO;"); _main.WriteLine("using System.IO.Compression;"); _main.WriteLine("using Base.Message;"); if (_optimized == OptimizationMode.IndexedArray) _main.WriteLine("using System.Threading;"); _main.WriteLine(); _main.WriteLine("namespace {0}", namespace1); _main.WriteLine("{"); GenerateEnums(_varibalesTree, new List<string>()); GenerateGlobalStructs(_varibalesTree, new List<string>()); _main.WriteLine("public partial class {0}", classname); if (_optimized == OptimizationMode.IndexedArray) _main.WriteLine(":IDisposable"); _main.WriteLine("{"); if (_optimized == OptimizationMode.SingleStatic) { _main.WriteLine("[ThreadStatic]"); _main.WriteLine("public static byte[] Bytes;"); _main.WriteLine("/// <summary>"); _main.WriteLine("/// ATT: must be call each time when thread get control for optimized version"); _main.WriteLine("/// </summary>"); _main.WriteLine("public void SetArray(byte[] bytes)"); _main.WriteLine("{"); _main.WriteLine("Bytes=bytes;"); _main.WriteLine("}"); } else if (_optimized == OptimizationMode.IndexedArray) { _main.WriteLine("internal static byte[][] bytes = new byte[32][];"); _main.WriteLine("private int index;"); _main.WriteLine("public void SetArray(byte[] bytes1)"); _main.WriteLine("{"); _main.WriteLine("lock (sync)"); _main.WriteLine("bytes[index]=bytes1;"); _main.WriteLine("}"); _main.WriteLine("public {0}()", classname); _main.WriteLine("{"); _main.WriteLine("AcquireArraySlot();"); _main.WriteLine("}"); _main.WriteLine("~{0}()", classname); _main.WriteLine("{"); _main.WriteLine("ReleaseArraySlot();"); _main.WriteLine("}"); _main.WriteLine("public void Dispose()"); _main.WriteLine("{"); _main.WriteLine("ReleaseArraySlot();"); _main.WriteLine("GC.SuppressFinalize(this);"); _main.WriteLine("index=-1;"); _main.WriteLine("}"); } _main.WriteLine("public bool Final;"); _main.WriteLine("public bool IsFinal { get { return Final; }}"); _main.WriteLine("public bool Error;"); _main.WriteLine("public bool IsError { get { return Error; }}"); _main.WriteLine("private int state;"); _main.WriteLine("private int boolExPosition;"); GenerateVariables(_varibalesTree, true); int countStates = 0; if (dfa != null) dfa.ForEachNR((state) => { state.Index = countStates++; }); else countStates = 1; GenerateStateConsts(countStates + 1); GenerateTables(dfa, countStates); GenerateLoadFunction3(countStates, dfa == null, namespace1, classname); GenerateParseMethod(dfa, countStates); GenerateGetHexDigitFunction(); _main.WriteLine("}"); _main.WriteLine("}"); _main.WriteLine("#endif"); _main.Flush(); _table.Flush(); } }
public static int Minimize5(this DfaState start, bool showProgress) { var startTime = DateTime.Now; if (showProgress) { Console.WriteLine("Minimize DFA v.5"); } var states = new List <DfaState>(3000000); start.ForEachNR((state) => { states.Add(state); }); var sets = new IntSet(states); if (showProgress) { Console.WriteLine("Create list: {0}", DateTime.Now - startTime); } if (showProgress) { Console.Write("Proccessing marks...\r"); } var startTime2 = DateTime.Now; foreach (var state in sets.GetSet(0)) { if (state.Value.AllMarks.Count > 0) { for (int i = 1; i < sets.Count; i++) { var state2 = sets.GetFirst(i); if (state.Value.IsSame(state2)) { sets.MoveToSet(state, state2.SetId); break; } } if (state.Value.SetId == 0) { sets.MoveToNewSet(state); } } } sets.RemoveEmpty(); if (showProgress) { Console.WriteLine("Marks: {0}\t\t", DateTime.Now - startTime2); Console.WriteLine("Splitted by marks to {0} sets", sets.Count); } for (int oldCount = -1; oldCount < sets.Count;) { oldCount = sets.Count; for (int i = 0; i < sets.Count; i++) { DfaState first = sets.GetFirst(i); bool splitted = false; foreach (var state in sets.GetSet(i)) { if (IsTransitedToSameSets4(first, state.Value) == false) { state.Value.NewSetId = sets.NewSetId; splitted = true; } } if (splitted) { foreach (var state in sets.GetSet(i)) { sets.MoveToSet(state, state.Value.NewSetId); } Console.Write("{0}\r", sets.Count); } } } if (showProgress) { Console.Write("Create MiniDFA\r"); } CreateMiniDfa4(start, states, sets); if (showProgress) { Console.WriteLine("Done ({0}, {1})\t\t\t\t", sets.Count, DateTime.Now - startTime); } return(sets.Count); }