Refactor message filter grammar and add `~` as an alias for `-` in negated filters for better UX when using CLI

pull/925/head
Oleksii Holub 2 years ago
parent 6c039ebfa6
commit 11414b5937

@ -15,16 +15,17 @@ internal static class FilterGrammar
from close in Character.EqualTo(open) from close in Character.EqualTo(open)
select value; select value;
private static readonly TextParser<char> FreeCharacter = private static readonly TextParser<string> UnquotedString =
Character.Matching(c => Parse.OneOf(
EscapedCharacter,
Character.Matching(
c =>
!char.IsWhiteSpace(c) && !char.IsWhiteSpace(c) &&
// Avoid all special tokens used by the grammar // Avoid all special tokens used by the grammar
c is not ('(' or ')' or '"' or '\'' or '-' or '|' or '&'), c is not ('(' or ')' or '"' or '\'' or '-' or '~' or '|' or '&'),
"any character except whitespace or `(`, `)`, `\"`, `'`, `-`, `|`, `&`" "any character except whitespace or `(`, `)`, `\"`, `'`, `-`, `|`, `&`"
); )
).AtLeastOnce().Text();
private static readonly TextParser<string> UnquotedString =
Parse.OneOf(EscapedCharacter, FreeCharacter).AtLeastOnce().Text();
private static readonly TextParser<string> String = private static readonly TextParser<string> String =
Parse.OneOf(QuotedString, UnquotedString).Named("text string"); Parse.OneOf(QuotedString, UnquotedString).Named("text string");
@ -64,19 +65,7 @@ internal static class FilterGrammar
.Select(k => (MessageFilter) new HasMessageFilter(k)) .Select(k => (MessageFilter) new HasMessageFilter(k))
.Named("has:<value>"); .Named("has:<value>");
private static readonly TextParser<MessageFilter> NegatedFilter = Character private static readonly TextParser<MessageFilter> PrimitiveFilter = Parse.OneOf(
.EqualTo('-')
.IgnoreThen(Parse.Ref(() => StandaloneFilter!))
.Select(f => (MessageFilter) new NegatedMessageFilter(f));
private static readonly TextParser<MessageFilter> GroupedFilter =
from open in Character.EqualTo('(')
from content in Parse.Ref(() => BinaryExpressionFilter!).Token()
from close in Character.EqualTo(')')
select content;
private static readonly TextParser<MessageFilter> StandaloneFilter = Parse.OneOf(
GroupedFilter,
FromFilter, FromFilter,
MentionsFilter, MentionsFilter,
ReactionFilter, ReactionFilter,
@ -84,19 +73,33 @@ internal static class FilterGrammar
ContainsFilter ContainsFilter
); );
private static readonly TextParser<MessageFilter> UnaryExpressionFilter = Parse.OneOf( private static readonly TextParser<MessageFilter> GroupedFilter =
NegatedFilter, from open in Character.EqualTo('(')
StandaloneFilter from content in Parse.Ref(() => ChainedFilter!).Token()
); from close in Character.EqualTo(')')
select content;
private static readonly TextParser<MessageFilter> BinaryExpressionFilter = Parse.Chain( private static readonly TextParser<MessageFilter> NegatedFilter = Character
// Dash is annoying to use from CLI due to conflicts with options, so we provide tilde as an alias
.In('-', '~')
.IgnoreThen(Parse.OneOf(GroupedFilter, PrimitiveFilter))
.Select(f => (MessageFilter) new NegatedMessageFilter(f));
private static readonly TextParser<MessageFilter> ChainedFilter = Parse.Chain(
// Operator
Parse.OneOf( Parse.OneOf(
// Explicit operator // Explicit operator
Character.In('|', '&').Token().Try(), Character.In('|', '&').Token().Try(),
// Implicit operator (resolves to 'and') // Implicit operator (resolves to 'and')
Character.WhiteSpace.AtLeastOnce().IgnoreThen(Parse.Return(' ')) Character.WhiteSpace.AtLeastOnce().IgnoreThen(Parse.Return(' '))
), ),
UnaryExpressionFilter, // Operand
Parse.OneOf(
NegatedFilter,
GroupedFilter,
PrimitiveFilter
),
// Reducer
(op, left, right) => op switch (op, left, right) => op switch
{ {
'|' => new BinaryExpressionMessageFilter(left, right, BinaryExpressionKind.Or), '|' => new BinaryExpressionMessageFilter(left, right, BinaryExpressionKind.Or),
@ -105,5 +108,5 @@ internal static class FilterGrammar
); );
public static readonly TextParser<MessageFilter> Filter = public static readonly TextParser<MessageFilter> Filter =
BinaryExpressionFilter.Token().AtEnd(); ChainedFilter.Token().AtEnd();
} }
Loading…
Cancel
Save