From 563121c5f55b3ae207c70d5310e11fdcfc56a858 Mon Sep 17 00:00:00 2001 From: Pavel Zhur Date: Wed, 9 Oct 2024 12:09:58 +0300 Subject: [PATCH] multiple parantheses support --- .../ChordParserTests.cs | 2 ++ .../Models/Enums/ChordParseError.cs | 1 + .../Parsers/ChordParser.cs | 26 +++++++++---------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/HarmonyDB.Theory/HarmonyDB.Theory.Chords.Tests/ChordParserTests.cs b/HarmonyDB.Theory/HarmonyDB.Theory.Chords.Tests/ChordParserTests.cs index ed09f822..ae478ea4 100644 --- a/HarmonyDB.Theory/HarmonyDB.Theory.Chords.Tests/ChordParserTests.cs +++ b/HarmonyDB.Theory/HarmonyDB.Theory.Chords.Tests/ChordParserTests.cs @@ -34,6 +34,8 @@ public void ParseChordType(string input, (List<(ChordTypeToken token, bool fromP ["ab()()", (List<(string, bool)>)[("ab()()", false)]], ["ab(cd)", (List<(string, bool)>)[("ab", false), ("cd", true)]], ["ab(c,d)", (List<(string, bool)>)[("ab", false), ("c", true), ("d", true)]], + ["ab(c,d)(e)f(g)h", (List<(string, bool)>)[("ab", false), ("c", true), ("d", true), ("e", true), ("f", false), ("g", true), ("h", false)]], + ["ab(c,d,)", (List<(string, bool)>)[("ab", false), ("c", true), ("d", true)]], ["ab(c,d,)", (List<(string, bool)>)[("ab", false), ("c", true), ("d", true)]], ["ab(c,,d)", (List<(string, bool)>)[("ab", false), ("c", true), ("d", true)]], ["(c,,d)", (List<(string, bool)>)[("c", true), ("d", true)]], diff --git a/HarmonyDB.Theory/HarmonyDB.Theory.Chords/Models/Enums/ChordParseError.cs b/HarmonyDB.Theory/HarmonyDB.Theory.Chords/Models/Enums/ChordParseError.cs index 4fecd4fe..b7bd2e3e 100644 --- a/HarmonyDB.Theory/HarmonyDB.Theory.Chords/Models/Enums/ChordParseError.cs +++ b/HarmonyDB.Theory/HarmonyDB.Theory.Chords/Models/Enums/ChordParseError.cs @@ -14,4 +14,5 @@ public enum ChordParseError DuplicateAdditions, EachExtensionTypeExpectedUnique, MaxOneMajExtensionExpected, + EmptyBrackets, } \ No newline at end of file diff --git a/HarmonyDB.Theory/HarmonyDB.Theory.Chords/Parsers/ChordParser.cs b/HarmonyDB.Theory/HarmonyDB.Theory.Chords/Parsers/ChordParser.cs index 65059b93..77b0355b 100644 --- a/HarmonyDB.Theory/HarmonyDB.Theory.Chords/Parsers/ChordParser.cs +++ b/HarmonyDB.Theory/HarmonyDB.Theory.Chords/Parsers/ChordParser.cs @@ -242,24 +242,22 @@ internal static (List<(ChordTypeToken token, bool fromParentheses, MatchAmbiguit internal static (List<(string fragment, bool fromParentheses)>? fragments, ChordParseError? error) TryUnwrapParentheses(string input, ChordTypeParsingOptions options) { - var match = Regex.Match(input, "^([^\\(\\)]*)\\(([^\\(\\)]+)\\)([^\\(\\)]*)$"); - - List<(string input, bool fromParentheses)> inputs; - if (!match.Success) + var match1 = Regex.Match(input, @"^((?[^\(\)]*)|\((?[^\(\)]+)\))*$"); + if (!match1.Success) { - inputs = [(input, false)]; - } - else - { - inputs = match.Groups[2].Value.Split(',').Select(x => (x, true)) - .Prepend((match.Groups[1].Value, false)) - .Append((match.Groups[3].Value, false)) - .ToList(); + return ([(input, false)], null); } - inputs = inputs.Where(x => x.input != string.Empty).ToList(); + var inputs = match1.Groups["in"].Captures.Select(c => (c, fromParentheses: true)) + .Concat(match1.Groups["notin"].Captures.Select(c => (c, fromParentheses: false))) + .Where(c => c.c.Length > 0) + .OrderBy(c => c.c.Index) + .Select(c => (c.c.Value, c.fromParentheses)) + .SelectMany(c => !c.fromParentheses ? c.Once() : c.Value.Split(',').Select(x => (Value: x, fromParentheses: true))) + .Where(c => c.Value != string.Empty) + .ToList(); - var trimmed = inputs.Select(x => x with { input = x.input.Trim() }).Where(x => x.input != string.Empty).ToList(); + var trimmed = inputs.Select(x => x with { Value = x.Value.Trim() }).Where(x => x.Value != string.Empty).ToList(); if (!options.TrimWhitespaceFragments && (trimmed.Count != inputs.Count || trimmed.Zip(inputs).Any(x => x.First != x.Second))) { return new(null, ChordParseError.WhitespaceFragments);