mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-06-08 02:14:42 -04:00
Simplify filter grammar
This commit is contained in:
parent
99d721c63b
commit
f48af53d72
1 changed files with 72 additions and 69 deletions
|
@ -18,60 +18,61 @@ internal static class FilterGrammar
|
||||||
private static readonly TextParser<string> UnquotedString =
|
private static readonly TextParser<string> UnquotedString =
|
||||||
Parse.OneOf(
|
Parse.OneOf(
|
||||||
EscapedCharacter,
|
EscapedCharacter,
|
||||||
Character.Matching(
|
// Avoid whitespace as it's treated as an implicit 'and' operator.
|
||||||
c =>
|
// Also avoid all special tokens used by other parsers.
|
||||||
!char.IsWhiteSpace(c) &&
|
Character.ExceptIn(' ', '(', ')', '"', '\'', '-', '~', '|', '&')
|
||||||
// Avoid all special tokens used by the grammar
|
|
||||||
c is not ('(' or ')' or '"' or '\'' or '-' or '~' or '|' or '&'),
|
|
||||||
"any character except whitespace or `(`, `)`, `\"`, `'`, `-`, `|`, `&`"
|
|
||||||
)
|
|
||||||
).AtLeastOnce().Text();
|
).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");
|
||||||
|
|
||||||
private static readonly TextParser<MessageFilter> ContainsFilter =
|
private static readonly TextParser<MessageFilter> ContainsFilter =
|
||||||
String.Select(v => (MessageFilter) new ContainsMessageFilter(v));
|
String.Select(v => (MessageFilter)new ContainsMessageFilter(v));
|
||||||
|
|
||||||
private static readonly TextParser<MessageFilter> FromFilter = Span
|
private static readonly TextParser<MessageFilter> FromFilter =
|
||||||
.EqualToIgnoreCase("from:")
|
Span
|
||||||
.IgnoreThen(String)
|
.EqualToIgnoreCase("from:")
|
||||||
.Select(v => (MessageFilter) new FromMessageFilter(v))
|
.IgnoreThen(String)
|
||||||
.Named("from:<value>");
|
.Select(v => (MessageFilter)new FromMessageFilter(v))
|
||||||
|
.Named("from:<value>");
|
||||||
|
|
||||||
private static readonly TextParser<MessageFilter> MentionsFilter = Span
|
private static readonly TextParser<MessageFilter> MentionsFilter =
|
||||||
.EqualToIgnoreCase("mentions:")
|
Span
|
||||||
.IgnoreThen(String)
|
.EqualToIgnoreCase("mentions:")
|
||||||
.Select(v => (MessageFilter) new MentionsMessageFilter(v))
|
.IgnoreThen(String)
|
||||||
.Named("mentions:<value>");
|
.Select(v => (MessageFilter)new MentionsMessageFilter(v))
|
||||||
|
.Named("mentions:<value>");
|
||||||
|
|
||||||
private static readonly TextParser<MessageFilter> ReactionFilter = Span
|
private static readonly TextParser<MessageFilter> ReactionFilter =
|
||||||
.EqualToIgnoreCase("reaction:")
|
Span
|
||||||
.IgnoreThen(String)
|
.EqualToIgnoreCase("reaction:")
|
||||||
.Select(v => (MessageFilter) new ReactionMessageFilter(v))
|
.IgnoreThen(String)
|
||||||
.Named("reaction:<value>");
|
.Select(v => (MessageFilter)new ReactionMessageFilter(v))
|
||||||
|
.Named("reaction:<value>");
|
||||||
|
|
||||||
private static readonly TextParser<MessageFilter> HasFilter = Span
|
private static readonly TextParser<MessageFilter> HasFilter =
|
||||||
.EqualToIgnoreCase("has:")
|
Span
|
||||||
.IgnoreThen(Parse.OneOf(
|
.EqualToIgnoreCase("has:")
|
||||||
Span.EqualToIgnoreCase("link").IgnoreThen(Parse.Return(MessageContentMatchKind.Link)),
|
.IgnoreThen(Parse.OneOf(
|
||||||
Span.EqualToIgnoreCase("embed").IgnoreThen(Parse.Return(MessageContentMatchKind.Embed)),
|
Span.EqualToIgnoreCase("link").IgnoreThen(Parse.Return(MessageContentMatchKind.Link)),
|
||||||
Span.EqualToIgnoreCase("file").IgnoreThen(Parse.Return(MessageContentMatchKind.File)),
|
Span.EqualToIgnoreCase("embed").IgnoreThen(Parse.Return(MessageContentMatchKind.Embed)),
|
||||||
Span.EqualToIgnoreCase("video").IgnoreThen(Parse.Return(MessageContentMatchKind.Video)),
|
Span.EqualToIgnoreCase("file").IgnoreThen(Parse.Return(MessageContentMatchKind.File)),
|
||||||
Span.EqualToIgnoreCase("image").IgnoreThen(Parse.Return(MessageContentMatchKind.Image)),
|
Span.EqualToIgnoreCase("video").IgnoreThen(Parse.Return(MessageContentMatchKind.Video)),
|
||||||
Span.EqualToIgnoreCase("sound").IgnoreThen(Parse.Return(MessageContentMatchKind.Sound)),
|
Span.EqualToIgnoreCase("image").IgnoreThen(Parse.Return(MessageContentMatchKind.Image)),
|
||||||
Span.EqualToIgnoreCase("pin").IgnoreThen(Parse.Return(MessageContentMatchKind.Pin))
|
Span.EqualToIgnoreCase("sound").IgnoreThen(Parse.Return(MessageContentMatchKind.Sound)),
|
||||||
))
|
Span.EqualToIgnoreCase("pin").IgnoreThen(Parse.Return(MessageContentMatchKind.Pin))
|
||||||
.Select(k => (MessageFilter) new HasMessageFilter(k))
|
))
|
||||||
.Named("has:<value>");
|
.Select(k => (MessageFilter)new HasMessageFilter(k))
|
||||||
|
.Named("has:<value>");
|
||||||
|
|
||||||
private static readonly TextParser<MessageFilter> PrimitiveFilter = Parse.OneOf(
|
private static readonly TextParser<MessageFilter> PrimitiveFilter =
|
||||||
FromFilter,
|
Parse.OneOf(
|
||||||
MentionsFilter,
|
FromFilter,
|
||||||
ReactionFilter,
|
MentionsFilter,
|
||||||
HasFilter,
|
ReactionFilter,
|
||||||
ContainsFilter
|
HasFilter,
|
||||||
);
|
ContainsFilter
|
||||||
|
);
|
||||||
|
|
||||||
private static readonly TextParser<MessageFilter> GroupedFilter =
|
private static readonly TextParser<MessageFilter> GroupedFilter =
|
||||||
from open in Character.EqualTo('(')
|
from open in Character.EqualTo('(')
|
||||||
|
@ -79,33 +80,35 @@ internal static class FilterGrammar
|
||||||
from close in Character.EqualTo(')')
|
from close in Character.EqualTo(')')
|
||||||
select content;
|
select content;
|
||||||
|
|
||||||
private static readonly TextParser<MessageFilter> NegatedFilter = Character
|
private static readonly TextParser<MessageFilter> NegatedFilter =
|
||||||
// Dash is annoying to use from CLI due to conflicts with options, so we provide tilde as an alias
|
Character
|
||||||
.In('-', '~')
|
// Dash is annoying to use from CLI due to conflicts with options, so we provide tilde as an alias
|
||||||
.IgnoreThen(Parse.OneOf(GroupedFilter, PrimitiveFilter))
|
.In('-', '~')
|
||||||
.Select(f => (MessageFilter) new NegatedMessageFilter(f));
|
.IgnoreThen(Parse.OneOf(GroupedFilter, PrimitiveFilter))
|
||||||
|
.Select(f => (MessageFilter)new NegatedMessageFilter(f));
|
||||||
|
|
||||||
private static readonly TextParser<MessageFilter> ChainedFilter = Parse.Chain(
|
private static readonly TextParser<MessageFilter> ChainedFilter =
|
||||||
// Operator
|
Parse.Chain(
|
||||||
Parse.OneOf(
|
// Operator
|
||||||
// Explicit operator
|
Parse.OneOf(
|
||||||
Character.In('|', '&').Token().Try(),
|
// Explicit operator
|
||||||
// Implicit operator (resolves to 'and')
|
Character.In('|', '&').Token().Try(),
|
||||||
Character.WhiteSpace.AtLeastOnce().IgnoreThen(Parse.Return(' '))
|
// Implicit operator (resolves to 'and')
|
||||||
),
|
Character.EqualTo(' ').AtLeastOnce().IgnoreThen(Parse.Return(' '))
|
||||||
// Operand
|
),
|
||||||
Parse.OneOf(
|
// Operand
|
||||||
NegatedFilter,
|
Parse.OneOf(
|
||||||
GroupedFilter,
|
NegatedFilter,
|
||||||
PrimitiveFilter
|
GroupedFilter,
|
||||||
),
|
PrimitiveFilter
|
||||||
// Reducer
|
),
|
||||||
(op, left, right) => op switch
|
// Reducer
|
||||||
{
|
(op, left, right) => op switch
|
||||||
'|' => new BinaryExpressionMessageFilter(left, right, BinaryExpressionKind.Or),
|
{
|
||||||
_ => new BinaryExpressionMessageFilter(left, right, BinaryExpressionKind.And)
|
'|' => new BinaryExpressionMessageFilter(left, right, BinaryExpressionKind.Or),
|
||||||
}
|
_ => new BinaryExpressionMessageFilter(left, right, BinaryExpressionKind.And)
|
||||||
);
|
}
|
||||||
|
);
|
||||||
|
|
||||||
public static readonly TextParser<MessageFilter> Filter =
|
public static readonly TextParser<MessageFilter> Filter =
|
||||||
ChainedFilter.Token().AtEnd();
|
ChainedFilter.Token().AtEnd();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue