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 SemanticAnalysis SemanticAnalysis; internal StateMachine(LR1Table table, LexicalAnalysis analysis, LR1Creator creator, SemanticAnalysis semanticAnalysis) { Table = table; AnalysisResult = analysis; Creator = creator; Tokens = AnalysisResult.GetStack(); SemanticAnalysis = semanticAnalysis; 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)); SemanticAnalysis.ShiftAnalysis(unit); break; case "Reduce": var reduceUnit = Creator.UnitIndex[destination]; if (reduceUnit.CanReduce(_Stack.Select(x => x.Item1).ToList())) { var vals = _Stack.Skip(_Stack.Count - reduceUnit.Grammar.Count).Take(reduceUnit.Grammar.Count).Select(x=>x.Item1) .ToList(); reduceUnit = SemanticAnalysis.Analysis(vals, reduceUnit.Clone()); _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); break; case "ACC": Console.WriteLine(Creator.UnitIndex[destination]); return true; default: throw new Exception("Action is not recognized."); } return false; } } }