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("}"); }