mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2026-02-15 00:03:38 -07:00
Refactor message filter grammar and add ~ as an alias for - in negated filters for better UX when using CLI
This commit is contained in:
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…
Reference in a new issue