using CanonSharp.Combinator; using CanonSharp.Combinator.Abstractions; using CanonSharp.Combinator.Extensions; using CanonSharp.Tests.Utils; using static CanonSharp.Combinator.ParserBuilder; namespace CanonSharp.Tests.CombinatorsTests; public class CombinatorParserTests : ParserTestsBase { [Fact] public void ChoiceTest() { Parser parser = Choice(Token('a'), Token('b'), Token('c')); ValidateSuccessfulResult(parser, 'a', "abc"); ValidateSuccessfulResult(parser, 'b', "bcd"); ValidateSuccessfulResult(parser, 'c', "cde"); parser = Choice([Token('a'), Token('b'), Token('c')]); ValidateSuccessfulResult(parser, 'a', "abc"); ValidateSuccessfulResult(parser, 'b', "bcd"); ValidateSuccessfulResult(parser, 'c', "cde"); } [Fact] public void SequenceTest() { Parser> parser = Sequence(Token('a'), Token('b'), Token('c')); ValidateSuccessfulResult(parser, ['a', 'b', 'c'], "abc"); parser = Sequence([Token('a'), Token('b'), Token('c')]); ValidateSuccessfulResult(parser, ['a', 'b', 'c'], "abc"); } [Fact] public void LeftRightTest() { Parser parser = Token('a').Left(Token('b')); ValidateSuccessfulResult(parser, 'a', "ab"); parser = Token('a').Right(Token('b')); ValidateSuccessfulResult(parser, 'b', "ab"); } [Fact] public void ManyTest() { Parser> parser = Token('a').Many(); ValidateSuccessfulResult(parser, [], "bbb"); ValidateSuccessfulResult(parser, ['a', 'a', 'a'], "aaa"); parser = Token('a').Many1(); ValidateSuccessfulResult(parser, ['a', 'a'], "aa"); ValidateFailedResult(parser, "bbb"); } [Fact] public void SkipManyTest() { Parser parser = Token('a').SkipMany().Right(Token('b')); ValidateSuccessfulResult(parser, 'b', "aaaab"); ValidateSuccessfulResult(parser, 'b', "bbbb"); parser = Token('a').SkipMany1().Right(Token('b')); ValidateSuccessfulResult(parser, 'b', "aaaaaab"); ValidateFailedResult(parser, "bb"); } [Fact] public void ChainTest() { // 等效于Many1 // 但是不返回中间结果 Parser parser = Token('a').Chain(Token); ValidateSuccessfulResult(parser, 'a', "aa"); ValidateFailedResult(parser, "bb"); parser = Token('_').Chain(x => x == '_' ? Satisfy(char.IsLetter) : Satisfy(char.IsDigit)); ValidateSuccessfulResult(parser, '1', "_a1"); ValidateSuccessfulResult(parser, '_', "_123"); } [Fact] public void ManyTillTest() { Parser> parser = Token('a').ManyTill(Token('b').LookAhead()); ValidateSuccessfulResult(parser, ['a', 'a', 'a'], "aaab"); ValidateSuccessfulResult(parser, [], "b"); parser = Token('a').Many1Till(Token('b').LookAhead()); ValidateSuccessfulResult(parser, ['a', 'a'], "aab"); ValidateFailedResult(parser, "bb"); } [Fact] public void SkipTillTest() { Parser parser = Token('a').SkipTill(Token('b')); ValidateSuccessfulResult(parser, 'b', "aaab"); ValidateSuccessfulResult(parser, 'b', "b"); parser = Token('a').Skip1Till(Token('b')); ValidateSuccessfulResult(parser, 'b', "aaab"); ValidateFailedResult(parser, "b"); } [Fact] public void TakeTillTest() { Parser> parser = TakeTill(Token('b').LookAhead()); ValidateSuccessfulResult(parser, ['a', 'a'], "aab"); ValidateSuccessfulResult(parser, [], "b"); parser = Take1Till(Token('b').LookAhead()); ValidateSuccessfulResult(parser, ['a', 'a'], "aab"); ValidateFailedResult(parser, "b"); } [Fact] public void MatchTest() { Parser parser = Token('b').Match(); ValidateSuccessfulResult(parser, 'b', "asdfasdfasdfasdfb"); ValidateSuccessfulResult(parser, 'b', "b"); } [Fact] public void QuoteTest() { Parser> parser = Any().Quote(Token('['), Token(']')); ValidateSuccessfulResult(parser, ['1', '2', '3'], "[123]"); parser = Any().Quote(Token('\'')); ValidateSuccessfulResult(parser, ['1', '2', '3'], "'123'"); } [Fact] public void SeparatedByTest() { Parser> parser = Token('a').SeparatedBy(Token(',')); ValidateSuccessfulResult(parser, ['a', 'a', 'a'], "a,a,a"); ValidateSuccessfulResult(parser, ['a'], "a"); ValidateSuccessfulResult(parser, [], ""); parser = Token('a').SeparatedBy1(Token(',')); ValidateSuccessfulResult(parser, ['a', 'a', 'a'], "a,a,a"); ValidateSuccessfulResult(parser, ['a'], "a"); ValidateFailedResult(parser, ""); } [Fact] public void EndByTest() { Parser> parser = Satisfy(char.IsLetter).EndBy(Token('.')); ValidateSuccessfulResult(parser, ['a', 'b', 'c'], "abc."); ValidateSuccessfulResult(parser, [], "."); parser = Satisfy(char.IsLetter).EndBy1(Token('.')); ValidateSuccessfulResult(parser, ['a', 'b', 'c'], "abc."); ValidateFailedResult(parser, "."); } [Fact] public void SeparatedOrEndByTest() { Parser> parser = Satisfy(char.IsLetter).SeparatedOrEndBy1(Token(',')); ValidateSuccessfulResult(parser, ['a', 'b', 'c'], "a,b,c,"); ValidateSuccessfulResult(parser, ['a', 'b', 'c'], "a,b,c"); ValidateFailedResult(parser, ""); parser = Satisfy(char.IsLetter).SeparatedOrEndBy(Token(',')); ValidateSuccessfulResult(parser, ['a', 'b', 'c'], "a,b,c,"); ValidateSuccessfulResult(parser, ['a', 'b', 'c'], "a,b,c"); ValidateSuccessfulResult(parser, [], ""); } }