using System; using System.Collections.Generic; using System.Linq; namespace Implab.Automaton.RegularExpressions { public class RegularDFADefinition : DFATable { readonly Dictionary m_tags = new Dictionary(); readonly IAlphabet m_alphabet; public RegularDFADefinition(IAlphabet alphabet) { Safe.ArgumentNotNull(alphabet, "aplhabet"); m_alphabet = alphabet; } public IAlphabet InputAlphabet { get { return m_alphabet; } } protected override DFAStateDescriptior[] ConstructTransitionTable() { if (InputAlphabet.Count != m_alphabet.Count) throw new InvalidOperationException("The alphabet doesn't match the transition table"); return base.ConstructTransitionTable(); } public void MarkFinalState(int s, TTag[] tags) { MarkFinalState(s); SetStateTag(s, tags); } public void SetStateTag(int s, TTag[] tags) { Safe.ArgumentNotNull(tags, "tags"); m_tags[s] = tags; } public TTag[] GetStateTag(int s) { TTag[] tags; return m_tags.TryGetValue(s, out tags) ? tags : new TTag[0]; } /// /// Optimize the specified alphabet. /// /// Пустой алфавит, который будет зполнен в процессе оптимизации. public RegularDFADefinition Optimize(IAlphabetBuilder alphabet) { Safe.ArgumentNotNull(alphabet, "alphabet"); var dfaTable = new RegularDFADefinition(alphabet); var states = new DummyAlphabet(StateCount); var map = new MapAlphabet(); Optimize(dfaTable, InputAlphabet, alphabet, states, map); foreach (var g in m_tags.Where(x => x.Key < StateCount).GroupBy(x => map.Translate(x.Key), x => x.Value )) dfaTable.SetStateTag(g.Key, g.SelectMany(x => x).ToArray()); return dfaTable; } } }