/// <summary> /// Loads grammar from the binary reader. /// </summary> private void Load(LoadContext context) { string headerString = context.ReadHeaderString(); // Trace.WriteLine(headerString, "Reading header"); Match headerMatch = FileHeader.Match(headerString); if (!headerMatch.Success) { throw new FileLoadException("The File Header is invalid or unsupported: "+headerString); } switch (headerMatch.Groups["version"].Value) { case "1.0": fileVersion = CgtVersion.V1_0; break; case "5.0": fileVersion = CgtVersion.V5_0; break; default: throw new FileLoadException(string.Format("The file format version {0} is not unsupported", headerMatch.Groups["version"].Value)); } while (context.HasMoreData()) { CgtRecordType recordType = context.ReadNextRecord(); /// Trace.WriteLine(recordType, "Reading record"); switch (recordType) { case CgtRecordType.Parameters: ReadHeader(context); break; case CgtRecordType.Property: ReadProperty(context); break; case CgtRecordType.Groups: ReadGroup(context); break; case CgtRecordType.TableCountsEnhanced: ReadTableCounts(context, true); break; case CgtRecordType.TableCounts: ReadTableCounts(context, false); break; case CgtRecordType.Initial: ReadInitialStates(context); break; case CgtRecordType.Symbols: ReadSymbol(context); break; case CgtRecordType.Charsets: ReadCharset(context); break; case CgtRecordType.PackedCharsets: if (fileVersion == CgtVersion.V1_0) { ReadPackedCharset(context); } else { ReadRangeCharset(context); } break; case CgtRecordType.Rules: ReadRule(context); break; case CgtRecordType.DfaStates: ReadDfaState(context); break; case CgtRecordType.LRStates: ReadLRState(context); break; default: throw new FileLoadException("Invalid record type"); } } dfaInitialState = dfaStateTable[context.DfaInitialStateIndex]; startSymbol = symbolTable[context.StartSymbolIndex]; lalrInitialState = lalrStateTable[context.LrInitialState]; FixupGroups(context); }
/// <summary> /// Gets the state transition origin states. /// </summary> /// <param name="state">The state to get the transitions origin vectors for.</param> /// <returns></returns> internal ReadOnlyCollection<DfaState> GetStateOrigins(DfaState state) { if (state == null) { throw new ArgumentNullException("state"); } InitializeStateOriginLookup(); ReadOnlyCollection<DfaState> result; if (!stateOrigins.TryGetValue(state, out result)) { throw new ArgumentException("The state is not valid", "state"); } return result; }
private void InitializeStateOriginLookup() { lock (sync) { if (stateOrigins == null) { Dictionary<DfaState, List<DfaState>> stateOriginTemp = new Dictionary<DfaState, List<DfaState>>(dfaStateTable.Length); foreach (DfaState state in dfaStateTable) { foreach (DfaState transitionState in state.GetTransitionStates()) { List<DfaState> originList; if (!stateOriginTemp.TryGetValue(transitionState, out originList)) { originList = new List<DfaState>(); stateOriginTemp.Add(transitionState, originList); } originList.Add(state); } } stateOrigins = new Dictionary<DfaState, ReadOnlyCollection<DfaState>>(dfaStateTable.Length); foreach (DfaState state in dfaStateTable) { DfaState[] origins; List<DfaState> originList; if (stateOriginTemp.TryGetValue(state, out originList)) { origins = originList.ToArray(); } else { origins = new DfaState[0]; } stateOrigins.Add(state, Array.AsReadOnly(origins)); } } } }
public bool IsAllowedDfaState(DfaState state) { return true; }
/// <summary> /// Reads table record counts and initializes tables. /// </summary> /// <param name="context"></param> private void ReadTableCounts(LoadContext context, bool readGroups) { // Initialize tables symbolTable = new Symbol[context.ReadIntegerEntry()]; charSetTable = new DfaCharset[context.ReadIntegerEntry()]; ruleTable = new Rule[context.ReadIntegerEntry()]; for (int i = 0; i < ruleTable.Length; i++) { ruleTable[i] = new Rule(this, i); } dfaStateTable = new DfaState[context.ReadIntegerEntry()]; for (int i = 0; i < dfaStateTable.Length; i++) { dfaStateTable[i] = new DfaState(this, i); } lalrStateTable = new LalrState[context.ReadIntegerEntry()]; for (int i = 0; i < lalrStateTable.Length; i++) { lalrStateTable[i] = new LalrState(this, i); } groupTable = new Group[readGroups ? context.ReadIntegerEntry() : 0]; }
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("}"); }
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); GenerateParseMethod(dfa, countStates); GenerateGetHexDigitFunction(); _main.WriteLine("}"); _main.WriteLine("}"); _main.WriteLine("#endif"); _main.Flush(); _table.Flush(); } }
public override DfaState <T> GetNextState(DfaState <T> state, char ch) => state.GetNextState(ch);
private void GenerateParseMethod(DfaState dfa, int errorState) { _main.WriteLine("partial void OnBeforeParse();"); _main.WriteLine("partial void OnAfterParse();"); _main.WriteLine("#region int Parse(..)"); _main.WriteLine("public bool ParseAll(ArraySegment<byte> data)"); _main.WriteLine("{"); _main.WriteLine("int parsed;"); _main.WriteLine("return ParseAll(data.Array, data.Offset, data.Count, out parsed);"); _main.WriteLine("}"); _main.WriteLine("public bool ParseAll(ArraySegment<byte> data, out int parsed)"); _main.WriteLine("{"); _main.WriteLine("return ParseAll(data.Array, data.Offset, data.Count, out parsed);"); _main.WriteLine("}"); _main.WriteLine("public bool ParseAll(byte[] bytes, int offset, int length, out int parsed)"); _main.WriteLine("{"); _main.WriteLine("parsed = 0;"); _main.WriteLine("do"); _main.WriteLine("{"); _main.WriteLine("Final = false;"); _main.WriteLine("parsed += Parse(bytes, offset + parsed, length - parsed);"); _main.WriteLine("} while (parsed < length && IsFinal);"); _main.WriteLine("return IsFinal;"); _main.WriteLine("}"); _main.WriteLine("public int Parse(ArraySegment<byte> data)"); _main.WriteLine("{"); _main.WriteLine("return Parse(data.Array, data.Offset, data.Count);"); _main.WriteLine("}"); _main.WriteLine("public int Parse(byte[] bytes, int offset, int length)"); _main.WriteLine("{"); _main.WriteLine("OnBeforeParse();"); if (dfa != null) { _main.WriteLine("int i = offset;"); GenerateSwitch(dfa, errorState, SwitchMode.JumpOnly); //_main.WriteLine("if (state == State{0})", errorState); //_main.WriteLine("goto exit1;"); _main.WriteLine("i++;"); _main.WriteLine("int end = offset + length;"); _main.WriteLine("for( ; i < end; i++)"); _main.WriteLine("{"); GenerateSwitch(dfa, errorState, SwitchMode.ActionJump); _main.WriteLine("}"); GenerateSwitch(dfa, errorState, SwitchMode.ActionOnly); _main.WriteLine("exit1: ;"); _main.WriteLine("OnAfterParse();"); _main.WriteLine("return i - offset;"); } else { _main.WriteLine("OnAfterParse();"); _main.WriteLine("return 0;"); } _main.WriteLine("}"); _main.WriteLine("#endregion"); }
public override bool IsAccepting(DfaState <T> state) => state.IsAccepting;
public override T GetMatch(DfaState <T> state) => state.Match;
public override bool HasIncomingEpsilon(DfaState <T> target) => false;
protected override int GetStateNumber(DfaState <T> state) => state.StateNumber;
public DfaContext(DfaState <T> startState, bool useStateNumbers) : base(useStateNumbers) { StartStates = new[] { startState }; }
public DfaTransition(Atom terminal, DfaState target) { Terminal = terminal; Target = target; }
public void Retarget(DfaState newTarget) { Target = newTarget; }