CompilerDesignIFLR1/CompilerDesignIflr1/LR1Unit.cs

180 lines
5.1 KiB
C#
Raw Normal View History

2024-12-27 01:25:50 +08:00
using System.Diagnostics.SymbolStore;
2024-12-20 20:20:34 +08:00
using System.Text;
namespace CompilerDesignIFlr1
{
internal class LR1Unit
{
2024-12-23 01:42:58 +08:00
internal LR1Unit() { }
2024-12-27 01:25:50 +08:00
internal static string LanguageMode = "English";
internal static Dictionary<string, string> EnglishToChinese = [];
internal static void Init(string filePath)
{
string fileContent = File.ReadAllText(filePath);
EnglishToChinese = fileContent
.Split('#')
.Select(x => x.Split(':').Select(x => x.Trim()).ToList()).Where(x=>x.Count == 2).ToList().ToDictionary(x => x[0], x => x[1]);
}
2024-12-23 01:42:58 +08:00
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<string> grammar)
{
Type = "Grammar";
Name = name;
Grammar = grammar;
}
internal LR1Unit(
int id,
string type,
string name,
HashSet<string> prospect,
int pointPosition,
List<string> grammar
)
{
Id = id;
Type = type;
Name = name;
Prospect = prospect;
PointPosition = pointPosition;
Grammar = grammar;
}
2024-12-27 01:25:50 +08:00
public LR1Unit(
int id,
string type,
string name,
int quadrupleIndex,
string value,
HashSet<string> prospect,
int pointPosition,
List<string> grammar
)
2024-12-24 16:17:20 +08:00
{
Id = id;
Type = type;
Name = name;
QuadrupleIndex = quadrupleIndex;
Value = value;
Prospect = prospect;
PointPosition = pointPosition;
Grammar = grammar;
}
internal LR1Unit Clone() =>
2024-12-27 01:25:50 +08:00
new LR1Unit(
Id,
Type,
Name,
0,
Value,
new HashSet<string>(Prospect),
PointPosition,
[.. Grammar]
);
2024-12-23 01:42:58 +08:00
internal int Id { get; set; } = -1;
internal string Type { get; set; } = "";
internal string Name { get; set; } = "";
2024-12-24 16:17:20 +08:00
internal int QuadrupleIndex { get; set; } = 0;
2024-12-23 01:42:58 +08:00
internal string Value { get; set; } = "";
internal HashSet<string> Prospect { get; set; } = [];
internal int PointPosition { get; set; } = 0;
internal List<string> Grammar { get; set; } = [];
internal string? Next() => PointPosition >= Grammar.Count ? null : Grammar[PointPosition];
internal bool ReadyToReduce() => PointPosition >= Grammar.Count;
internal bool CanReduce(List<LR1Unit> stack)
{
for (int i = 1; i <= Grammar.Count; i++)
{
if (stack[^i].Name != Grammar[^i])
return false;
}
return true;
}
public override string ToString()
{
2024-12-27 01:25:50 +08:00
string GetName(string s)
{
return LanguageMode switch
{
"Chinese" => EnglishToChinese.TryGetValue(s, out var result) ? result : s,
"English" => s,
_ => throw new Exception("Language mode is not supported.")
};
}
2024-12-23 01:42:58 +08:00
StringBuilder sb = new();
sb.Append($"{Id, 2} ");
2024-12-27 01:25:50 +08:00
sb.Append(GetName(Name)).Append(" ::= ");
2024-12-23 01:42:58 +08:00
for (int i = 0; i < Grammar.Count; i++)
{
if (PointPosition == i)
sb.Append(". ");
2024-12-27 01:25:50 +08:00
sb.Append(GetName(Grammar[i]) + " ");
2024-12-23 01:42:58 +08:00
}
if (PointPosition == Grammar.Count)
sb.Append('.');
foreach (var item in Prospect)
{
2024-12-27 01:25:50 +08:00
sb.Append(", " + GetName(item));
2024-12-23 01:42:58 +08:00
}
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;
}
2024-12-20 20:20:34 +08:00
}
}