66 lines
2.0 KiB
C#
66 lines
2.0 KiB
C#
|
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;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|