From 7de5ce8f285ffb9f09828ad73fccd7d460d20760 Mon Sep 17 00:00:00 2001 From: Ichirinko <1621543655@qq.com> Date: Mon, 11 Mar 2024 22:22:53 +0800 Subject: [PATCH] =?UTF-8?q?add:=E5=A2=9E=E5=8A=A0=E4=BA=86=E5=8C=85?= =?UTF-8?q?=E5=90=AB=E7=A9=BA=E4=BA=A7=E7=94=9F=E5=BC=8F=E7=9A=84=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=94=A8=E4=BE=8B=20(#2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加了包含空产生式的测试用例 Co-authored-by: jackfiled Reviewed-on: https://git.rrricardo.top/PostGuard/Canon/pulls/2 Co-authored-by: Ichirinko <1621543655@qq.com> Co-committed-by: Ichirinko <1621543655@qq.com> --- .../SimpleGrammarWithEmptyTests.cs | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 Canon.Tests/GrammarParserTests/SimpleGrammarWithEmptyTests.cs diff --git a/Canon.Tests/GrammarParserTests/SimpleGrammarWithEmptyTests.cs b/Canon.Tests/GrammarParserTests/SimpleGrammarWithEmptyTests.cs new file mode 100644 index 0000000..bbf58a1 --- /dev/null +++ b/Canon.Tests/GrammarParserTests/SimpleGrammarWithEmptyTests.cs @@ -0,0 +1,129 @@ +using Canon.Core.Enums; +using Canon.Core.GrammarParser; +using Xunit.Abstractions; + +namespace Canon.Tests.GrammarParserTests; + +public class SimpleGrammarWithEmptyTests(ITestOutputHelper testOutputHelper) +{ + /// + /// 带有空产生式的简单语法(课后题4.18) + /// S -> A + /// A -> BA | ε + /// B -> aB | b + /// 为了方便测试指定 + /// A ProgramStruct + /// B ProgramBody + /// a Identifier + /// b Identifier + /// + // private readonly ITestOutputHelper _testOutputHelper; + + private readonly ITestOutputHelper _testOutputHelper = testOutputHelper; + + private static readonly Dictionary>> s_simpleGrammar = new() + { + { + new NonTerminator(NonTerminatorType.StartNonTerminator), [ + [new NonTerminator(NonTerminatorType.ProgramStruct)] + ] + }, + { + new NonTerminator(NonTerminatorType.ProgramStruct), [ + [ + new NonTerminator(NonTerminatorType.ProgramBody), + new NonTerminator(NonTerminatorType.ProgramStruct) + ], + [] + ] + }, + { + new NonTerminator(NonTerminatorType.ProgramBody), [ + [ + Terminator.IdentifierTerminator, + new NonTerminator(NonTerminatorType.ProgramBody) + ], + [Terminator.IdentifierTerminator] + ] + } + }; + + [Fact] + public void FirstSetTest() + { + GrammarBuilder builder = new() + { + Generators = s_simpleGrammar, Begin = new NonTerminator(NonTerminatorType.StartNonTerminator) + }; + + builder.Build(); + + Assert.Contains(builder.FirstSet, pair => + pair.Key == new NonTerminator(NonTerminatorType.StartNonTerminator)); + Assert.Contains(builder.FirstSet, pair => + pair.Key == new NonTerminator(NonTerminatorType.ProgramStruct)); + Assert.Contains(builder.FirstSet, pair => + pair.Key == new NonTerminator(NonTerminatorType.ProgramBody)); + + foreach (HashSet terminators in builder.FirstSet.Values) + { + Assert.Single(terminators); + Assert.Contains(Terminator.IdentifierTerminator, terminators); + } + } + + [Fact] + public void StatsTest() + { + GrammarBuilder builder = new() + { + Generators = s_simpleGrammar, Begin = new NonTerminator(NonTerminatorType.StartNonTerminator) + }; + + Grammar grammar = builder.Build(); + + Assert.Equal(6, builder.Automation.Count); + + Assert.Contains(new NonTerminator(NonTerminatorType.ProgramStruct), grammar.BeginState.Transformer.Keys); + Assert.Contains(new NonTerminator(NonTerminatorType.ProgramBody), grammar.BeginState.Transformer.Keys); + Assert.Contains(Terminator.IdentifierTerminator, grammar.BeginState.Transformer.Keys); + Assert.Equal(7, grammar.BeginState.Expressions.Count); + _testOutputHelper.WriteLine("--- 0 ---"); + _testOutputHelper.WriteLine(grammar.BeginState.ToString()); + + LrState state1 = + grammar.BeginState.Transformer[new NonTerminator(NonTerminatorType.ProgramStruct)]; + Assert.Single(state1.Expressions); + _testOutputHelper.WriteLine("--- 1 ---"); + _testOutputHelper.WriteLine(state1.ToString()); + + LrState state2 = + grammar.BeginState.Transformer[new NonTerminator(NonTerminatorType.ProgramBody)]; + Assert.Contains(new NonTerminator(NonTerminatorType.ProgramStruct), state2.Transformer.Keys); + Assert.Contains(new NonTerminator(NonTerminatorType.ProgramBody), state2.Transformer.Keys); + Assert.Contains(Terminator.IdentifierTerminator, state2.Transformer.Keys); + Assert.Equal(7, state2.Expressions.Count); + _testOutputHelper.WriteLine("--- 2 ---"); + _testOutputHelper.WriteLine(state2.ToString()); + + LrState state3 = + grammar.BeginState.Transformer[Terminator.IdentifierTerminator]; + Assert.Contains(new NonTerminator(NonTerminatorType.ProgramBody), state3.Transformer.Keys); + Assert.Contains(Terminator.IdentifierTerminator, state3.Transformer.Keys); + Assert.Equal(8, state3.Expressions.Count); + _testOutputHelper.WriteLine("--- 3 ---"); + _testOutputHelper.WriteLine(state3.ToString()); + + LrState state4 = state2.Transformer[new NonTerminator(NonTerminatorType.ProgramStruct)]; + Assert.Empty(state4.Transformer); + Assert.Single(state4.Expressions); + _testOutputHelper.WriteLine("--- 4 ---"); + _testOutputHelper.WriteLine(state4.ToString()); + + LrState state5 = state3.Transformer[new NonTerminator(NonTerminatorType.ProgramBody)]; + Assert.Empty(state5.Transformer); + Assert.Equal(2, state5.Expressions.Count); + _testOutputHelper.WriteLine("--- 5 ---"); + _testOutputHelper.WriteLine(state5.ToString()); + } +}