public TableValue <TState, TSymbol> this[TableKey <TState, TSymbol> key] { get { if (!States.Contains(key.State)) { throw new ArgumentException(nameof(key.State)); } if (!Symbols.Contains(key.Symbol)) { throw new ArgumentException(nameof(key.Symbol)); } return(_table[key]); } set { if (!States.Contains(key.State)) { throw new ArgumentException(nameof(key.State)); } if (!Symbols.Contains(key.Symbol)) { throw new ArgumentException(nameof(key.Symbol)); } if (!States.Contains(value.State)) { throw new ArgumentException(nameof(value.State)); } if (!Symbols.Contains(value.Symbol)) { throw new ArgumentException(nameof(value.Symbol)); } _table[key] = value; } }
public static StatefulTable <TState, TSymbol> Load <TState, TSymbol>(XDocument document, TSymbol nullValue, StateSerializer <TState> stateSerializer, SymbolSerializer <TSymbol> symbolSerializer) { // Get symbols var symbols = new List <TSymbol>(); symbols.Add(nullValue); foreach (var element in document.Root.Elements()) { if ("symbols".Equals(element.Name.LocalName)) { for (int index = 0; index < element.Value.Length; index++) { symbols.Add(symbolSerializer.FromString($"{element.Value[index]}")); } break; } } // Get status var states = new List <TState>(); var initialState = default(TState); var finalStates = new List <TState>(); foreach (var element in document.Root.Elements()) { if ("states".Equals(element.Name.LocalName)) { foreach (var stateTag in element.Elements()) { bool isStart = false; bool isHalt = false; if ("state".Equals(stateTag.Name.LocalName)) { foreach (var attribute in stateTag.Attributes()) { if ("start".Equals(attribute.Name.LocalName)) { isStart = "yes".Equals(attribute.Value); } else if ("halt".Equals(attribute.Name.LocalName)) { isHalt = "yes".Equals(attribute.Value); } } var status = stateSerializer.FromString(stateTag.Value); states.Add(status); if (isStart) { initialState = status; } if (isHalt) { finalStates.Add(status); } } } break; } } // Create the table var table = new StatefulTable <TState, TSymbol>(states, symbols, initialState, finalStates); // Transition function foreach (var element in document.Root.Elements()) { if ("transition-function".Equals(element.Name.LocalName)) { foreach (var mappingTag in element.Elements()) { if ("mapping".Equals(mappingTag.Name.LocalName)) { var currentState = string.Empty; var currentSymbol = string.Empty; var nextState = string.Empty; var nextSymbol = string.Empty; var movement = string.Empty; foreach (var fromTag in mappingTag.Elements()) { if ("from".Equals(fromTag.Name.LocalName)) { foreach (var attribute in fromTag.Attributes()) { if ("current-state".Equals(attribute.Name.LocalName)) { currentState = attribute.Value; } else if ("current-symbol".Equals(attribute.Name.LocalName)) { currentSymbol = attribute.Value; } } break; } } foreach (var toTag in mappingTag.Elements()) { if ("to".Equals(toTag.Name.LocalName)) { foreach (var attribute in toTag.Attributes()) { if ("next-state".Equals(attribute.Name.LocalName)) { nextState = attribute.Value; } else if ("next-symbol".Equals(attribute.Name.LocalName)) { nextSymbol = attribute.Value; } else if ("movement".Equals(attribute.Name.LocalName)) { movement = attribute.Value; } } break; } } var key = new TableKey <TState, TSymbol>(stateSerializer.FromString(currentState), symbolSerializer.FromString(currentSymbol)); var value = new TableValue <TState, TSymbol>(stateSerializer.FromString(nextState), symbolSerializer.FromString(nextSymbol), GetMoveActionFromString(movement)); table[key] = value; } } break; } } return(table); }