using CanonSharp.Benchmark.Canon.Core.Enums; using CanonSharp.Benchmark.Canon.Core.Exceptions; using CanonSharp.Benchmark.Canon.Core.GrammarParser; using CanonSharp.Benchmark.Canon.Core.LexicalParser; using CanonSharp.Benchmark.Canon.Core.SyntaxNodes; namespace CanonSharp.Benchmark.Canon.Core.Abstractions; /// /// 语法分析器接口 /// public interface IGrammarParser { public ITransformer BeginTransformer { get; } public NonTerminator Begin { get; } /// /// 分析指定的词法记号流并构建对应的语法树 /// /// 输入的词法记号流 /// 语法树的根节点 /// 语法分析错误 public ProgramStruct Analyse(IEnumerable tokens) { Stack stack = []; stack.Push(new AnalyseState(BeginTransformer, SyntaxNodeBase.Create(SemanticToken.End))); using IEnumerator enumerator = tokens.GetEnumerator(); if (!enumerator.MoveNext()) { throw new InvalidOperationException("Input token list is empty"); } while (true) { AnalyseState top = stack.Peek(); // 首先尝试进行移进 if (top.State.ShiftTable.TryGetValue(enumerator.Current, out ITransformer? next)) { stack.Push(new AnalyseState(next, SyntaxNodeBase.Create(enumerator.Current))); if (enumerator.MoveNext()) { continue; } else { throw new GrammarException(stack.Peek().State); } } // 再进行归约 if (top.State.ReduceTable.TryGetValue(enumerator.Current, out ReduceInformation? information)) { if (information.Left == Begin) { // 如果是归约到起始符 // 那么就直接返回不继续进行归约 return top.Node.Convert(); } List children = []; NonTerminatorType leftType = information.Left.Type; for (int i = 0; i < information.Length; i++) { children.Add(stack.Pop().Node); } // 为了符合生成式的顺序而倒序 children.Reverse(); stack.Push(new AnalyseState(stack.Peek().State.ShiftTable[information.Left], SyntaxNodeBase.Create(leftType, children))); continue; } throw new GrammarException(stack.Peek().State, enumerator.Current); } } private record AnalyseState(ITransformer State, SyntaxNodeBase Node); }