CompilerDesignIFLR1/CompilerDesignIflr1/StateMachine.cs

66 lines
2.0 KiB
C#
Raw Normal View History

2024-12-23 01:42:58 +08:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CompilerDesignIflr1;
namespace CompilerDesignIFlr1
{
internal class StateMachine
{
internal LR1Table Table;
internal LexicalAnalysis AnalysisResult;
internal LR1Creator Creator;
internal List<(LR1Unit, int)> stack = [(new LR1Unit("End","#"),0)];
internal Stack<LR1Unit> Tokens;
internal StateMachine(LR1Table table, LexicalAnalysis analysis, LR1Creator creator)
{
Table = table;
AnalysisResult = analysis;
Creator = creator;
Tokens = AnalysisResult.GetStack();
Compute();
}
internal void Compute()
{
while (true)
{
if (ComputeOnce(Tokens.Pop()))
break;
}
}
internal bool ComputeOnce(LR1Unit unit)
{
var (action, destination) = Table.Rows[stack[^1].Item2].Next(unit.Name);
switch (action)
{
case "GOTO":
stack.Add((unit, destination));
break;
case "Reduce":
var reduceUnit = Creator.UnitIndex[destination];
if (reduceUnit.CanReduce(stack.Select(x => x.Item1).ToList()))
{
stack.RemoveRange(stack.Count - reduceUnit.Grammar.Count, reduceUnit.Grammar.Count);
}
else
throw new Exception("Reduce not allow.");
Console.WriteLine(reduceUnit);
Tokens.Push(unit);
Tokens.Push(reduceUnit.Clone());
break;
case "ACC":
Console.WriteLine(Creator.UnitIndex[destination]);
return true;
default:
throw new Exception("Action is not recognized.");
}
return false;
}
}
}