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 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; } } }