Simplify filter grammar

This commit is contained in:
Oleksii Holub 2022-08-25 21:07:02 +03:00
parent 99d721c63b
commit f48af53d72

View file

@ -18,13 +18,9 @@ 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 =
@ -33,25 +29,29 @@ internal static class FilterGrammar
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 =
Span
.EqualToIgnoreCase("from:") .EqualToIgnoreCase("from:")
.IgnoreThen(String) .IgnoreThen(String)
.Select(v => (MessageFilter)new FromMessageFilter(v)) .Select(v => (MessageFilter)new FromMessageFilter(v))
.Named("from:<value>"); .Named("from:<value>");
private static readonly TextParser<MessageFilter> MentionsFilter = Span private static readonly TextParser<MessageFilter> MentionsFilter =
Span
.EqualToIgnoreCase("mentions:") .EqualToIgnoreCase("mentions:")
.IgnoreThen(String) .IgnoreThen(String)
.Select(v => (MessageFilter)new MentionsMessageFilter(v)) .Select(v => (MessageFilter)new MentionsMessageFilter(v))
.Named("mentions:<value>"); .Named("mentions:<value>");
private static readonly TextParser<MessageFilter> ReactionFilter = Span private static readonly TextParser<MessageFilter> ReactionFilter =
Span
.EqualToIgnoreCase("reaction:") .EqualToIgnoreCase("reaction:")
.IgnoreThen(String) .IgnoreThen(String)
.Select(v => (MessageFilter)new ReactionMessageFilter(v)) .Select(v => (MessageFilter)new ReactionMessageFilter(v))
.Named("reaction:<value>"); .Named("reaction:<value>");
private static readonly TextParser<MessageFilter> HasFilter = Span private static readonly TextParser<MessageFilter> HasFilter =
Span
.EqualToIgnoreCase("has:") .EqualToIgnoreCase("has:")
.IgnoreThen(Parse.OneOf( .IgnoreThen(Parse.OneOf(
Span.EqualToIgnoreCase("link").IgnoreThen(Parse.Return(MessageContentMatchKind.Link)), Span.EqualToIgnoreCase("link").IgnoreThen(Parse.Return(MessageContentMatchKind.Link)),
@ -65,7 +65,8 @@ 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> PrimitiveFilter = Parse.OneOf( private static readonly TextParser<MessageFilter> PrimitiveFilter =
Parse.OneOf(
FromFilter, FromFilter,
MentionsFilter, MentionsFilter,
ReactionFilter, ReactionFilter,
@ -79,19 +80,21 @@ 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 =
Character
// Dash is annoying to use from CLI due to conflicts with options, so we provide tilde as an alias // Dash is annoying to use from CLI due to conflicts with options, so we provide tilde as an alias
.In('-', '~') .In('-', '~')
.IgnoreThen(Parse.OneOf(GroupedFilter, PrimitiveFilter)) .IgnoreThen(Parse.OneOf(GroupedFilter, PrimitiveFilter))
.Select(f => (MessageFilter)new NegatedMessageFilter(f)); .Select(f => (MessageFilter)new NegatedMessageFilter(f));
private static readonly TextParser<MessageFilter> ChainedFilter = Parse.Chain( private static readonly TextParser<MessageFilter> ChainedFilter =
Parse.Chain(
// Operator // 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.EqualTo(' ').AtLeastOnce().IgnoreThen(Parse.Return(' '))
), ),
// Operand // Operand
Parse.OneOf( Parse.OneOf(