using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CompilerDesignIFlr1 { internal class LR1Unit { internal LR1Unit() { } internal LR1Unit(string name, string grammar) { Type = "Token"; Name = name; Grammar = [grammar]; } internal LR1Unit(string name, string value, string grammar) { Type = "Token"; Name = name; Grammar = [grammar]; Value = value; } internal LR1Unit(string name, List grammar) { Type = "Grammar"; Name = name; Grammar = grammar; } internal LR1Unit( int id, string type, string name, HashSet prospect, int pointPosition, List grammar ) { Id = id; Type = type; Name = name; Prospect = prospect; PointPosition = pointPosition; Grammar = grammar; } public LR1Unit(int id, string type, string name, int quadrupleIndex, string value, HashSet prospect, int pointPosition, List grammar) { Id = id; Type = type; Name = name; QuadrupleIndex = quadrupleIndex; Value = value; Prospect = prospect; PointPosition = pointPosition; Grammar = grammar; } internal LR1Unit Clone() => new LR1Unit(Id, Type, Name, 0, Value,new HashSet(Prospect), PointPosition, [.. Grammar]); internal int Id { get; set; } = -1; internal string Type { get; set; } = ""; internal string Name { get; set; } = ""; internal int QuadrupleIndex { get; set; } = 0; internal string Value { get; set; } = ""; internal HashSet Prospect { get; set; } = []; internal int PointPosition { get; set; } = 0; internal List Grammar { get; set; } = []; internal string? Next() => PointPosition >= Grammar.Count ? null : Grammar[PointPosition]; internal bool ReadyToReduce() => PointPosition >= Grammar.Count; internal bool CanReduce(List stack) { for (int i = 1; i <= Grammar.Count; i++) { if (stack[^i].Name != Grammar[^i]) return false; } return true; } public override string ToString() { StringBuilder sb = new(); //if (Grammar.Count == 0) // return "."; sb.Append($"{Id, 2} "); sb.Append(Name).Append(" ::= "); for (int i = 0; i < Grammar.Count; i++) { if (PointPosition == i) sb.Append(". "); sb.Append(Grammar[i] + " "); } if (PointPosition == Grammar.Count) sb.Append('.'); foreach (var item in Prospect) { sb.Append(", " + item); } return sb.ToString(); } public override bool Equals(object? obj) { if (obj is not LR1Unit other) return false; return Type == other.Type && Name == other.Name && Id == other.Id && PointPosition == other.PointPosition && Grammar.SequenceEqual(other.Grammar) && Prospect.SetEquals(other.Prospect); } public override int GetHashCode() { HashCode hash = new HashCode(); hash.Add(Type); hash.Add(Name); hash.Add(PointPosition); foreach (var item in Grammar) hash.Add(item); foreach (var item in Prospect) hash.Add(item); return hash.ToHashCode(); } internal bool Nullable() => Grammar.Count == 0; internal LR1Unit ToNext() { var unit = Clone(); unit.PointPosition++; return unit; } } }