77 lines
2.3 KiB
C#
77 lines
2.3 KiB
C#
namespace CanonSharp.Common.LexicalAnalyzer;
|
|
|
|
public class NondeterministicState : IEquatable<NondeterministicState>
|
|
{
|
|
public Guid Id { get; } = Guid.NewGuid();
|
|
|
|
public Dictionary<EmptyChar, HashSet<NondeterministicState>> Transactions { get; } = [];
|
|
|
|
public bool Equals(NondeterministicState? other) => other is not null && Id.Equals(other.Id);
|
|
|
|
public void AddTransaction(EmptyChar c, NondeterministicState state)
|
|
{
|
|
if (Transactions.TryGetValue(c, out HashSet<NondeterministicState>? states))
|
|
{
|
|
states.Add(state);
|
|
}
|
|
else
|
|
{
|
|
Transactions.Add(c, [state]);
|
|
}
|
|
}
|
|
|
|
public override bool Equals(object? obj) => obj is NondeterministicState other && Equals(other);
|
|
|
|
public override int GetHashCode() => Id.GetHashCode();
|
|
|
|
public HashSet<NondeterministicState> CalculateEmptyClosure()
|
|
{
|
|
HashSet<NondeterministicState> result = [];
|
|
Queue<NondeterministicState> queue = [];
|
|
queue.Enqueue(this);
|
|
|
|
while (queue.TryDequeue(out NondeterministicState? state))
|
|
{
|
|
result.Add(state);
|
|
|
|
if (!state.Transactions.TryGetValue(EmptyChar.Empty, out HashSet<NondeterministicState>? next))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
foreach (NondeterministicState s in next.Where(s => !result.Contains(s)))
|
|
{
|
|
queue.Enqueue(s);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
public class NondeterministicStateSet(HashSet<NondeterministicState> states) : IEquatable<NondeterministicStateSet>
|
|
{
|
|
private readonly HashSet<NondeterministicState> _states = states;
|
|
|
|
public bool Equals(NondeterministicStateSet? other)
|
|
{
|
|
if (other is null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return _states.Count == other._states.Count && _states.All(s => other._states.Contains(s));
|
|
}
|
|
|
|
public override bool Equals(object? obj) => obj is NondeterministicStateSet other && Equals(other);
|
|
|
|
public override int GetHashCode() => _states.Aggregate(0, (current, state) => current ^ state.GetHashCode());
|
|
}
|
|
|
|
public class NondeterministicFiniteAutomation(NondeterministicState start, HashSet<NondeterministicState> finalStates)
|
|
{
|
|
public NondeterministicState Start { get; } = start;
|
|
|
|
public HashSet<NondeterministicState> FinalStates { get; } = finalStates;
|
|
}
|