CompilerDesignIFLR1/CompilerDesignIflr1/LR1Table.cs

92 lines
3.0 KiB
C#

using System.Text;
namespace CompilerDesignIFlr1
{
internal class LR1Table
{
internal List<Row> Rows = [];
internal LR1Table(LR1Creator creator)
{
for (int i = 0; i < creator.Closures.Count; i++)
{
LR1Closure closure = creator.Closures[i];
Dictionary<string, int> @goto = [];
Dictionary<string, string> action = [];
foreach (var (by, nextIndex) in closure.Next)
{
if (creator.TokenUnit.ContainsKey(by))
action.Add(by, "s" + nextIndex);
else
@goto.Add(by, nextIndex);
}
foreach (var unit in closure.GetReduceUnits())
{
foreach (string prospect in unit.Prospect)
{
if (action.ContainsKey(prospect))
throw new Exception("Reduce,Reduce/Reduce,Shift error occurred.");
action.Add(prospect, "r" + unit.Id);
}
}
Rows.Add(new Row(i, @goto, action));
}
PrintRow();
return;
}
private void PrintRow()
{
foreach (Row row in Rows)
{
Console.WriteLine(row);
}
}
}
internal class Row
{
internal int Id;
internal Dictionary<string, int> GOTO;
internal Dictionary<string, string> ACTION;
internal Row(int id, Dictionary<string, int> @goto, Dictionary<string, string> action)
{
Id = id;
GOTO = @goto;
ACTION = action;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(Id + " \n");
sb.Append("ACTION: \n");
foreach (var (key, value) in ACTION)
sb.Append(key).Append(": ").Append(value).Append(", ");
if(GOTO.Count != 0)
sb.Append("\nGOTO: \n");
foreach (var (key, value) in GOTO)
sb.Append(key).Append(": ").Append(value).Append(", ");
sb.Append('\n');
return sb.ToString();
}
public (string, int) Next(string name)
{
if (name == "StatementList" && Id == 0)
return ("ACC", 0);
if (GOTO.TryGetValue(name, out var result))
return ("GOTO", result);
if (ACTION.TryGetValue(name, out var value))
if (value.StartsWith("s"))
return ("GOTO", int.Parse(value.Substring(1)));
else if (value.StartsWith("r"))
return ("Reduce", int.Parse(value.Substring(1)));
else
throw new Exception($"Value can't be recognized. {value}");
throw new InvalidOperationException($"Code error in state {Id}: {name} not found");
}
}
}