Sprache парсер с настраиваемыми полями
У меня есть сервер отчетов, который должен проанализировать строку с некоторыми аргументами, управляющими содержимым отчета.
Я использую Sprache библиотеки парсера, чтобы помочь с этим. Все работает нормально, кроме одной вещи, на которой я застрял.
У меня есть временной фильтр, который может принимать одно из следующих значений: сегодня, вчера, на прошлой неделе, в прошлом месяце, нет или настраивается.
Это обычай, который приносит мне немного горя. Все остальные просто строки. Custom также имеет свойства from и to впоследствии.
private static readonly Parser<DataFilterEntity> TimeFilter =
from filter in Parse.String("today").Return(DataFilterEntity.Today)
.Or(Parse.String("yesterday").Return(DataFilterEntity.Yesterday)
.Or(Parse.String("last week").Return(DataFilterEntity.LastWeek)
.Or(Parse.String("last month").Return(DataFilterEntity.LastMonth)
.Or(Parse.String("none").Return(DataFilterEntity.None))
.Or(Parse.String("custom").Return(DataFilterEntity.Custom())))))
select filter;
Пользовательская строка - проблема. Мне нужно проанализировать "пользовательскую" строку, но затем проанализировать поля from и to DateTime, а также передать их в DataFilterEntity.Custom (from, to)
Любые идеи высоко ценится.
1 ответ
Вам нужно сначала создать парсер для DateTime, а затем парсер для вашего пользовательского типа. Вот пример "самая простая вещь, которая могла бы работать". Возможно, вы захотите сделать DateTimeParser более конкретным в значениях, которые он принимает. Я не знаю, как выглядит конструктор для вашего DataFilterEntity, поэтому я догадался:)
public static readonly Parser<DateTime> DateTimeParser =
from day in Parse.Number
from s1 in Parse.Char('/')
from month in Parse.Number
from s2 in Parse.Char('/')
from year in Parse.Number
select new DateTime(int.Parse(year), int.Parse(month), int.Parse(day));
public static readonly Parser<DataFilterEntity> CustomParser =
from a1 in Parse.String("custom").Token()
from fromDateTime in DateTimeParser.Token()
from toDateTime in DateTimeParser.Token()
select new DataFilterEntity(fromDateTime.ToShortDateString() + " -> " + toDateTime.ToShortDateString());
public static readonly Parser<DataFilterEntity> TimeFilter =
Parse.String("today").Return(DataFilterEntity.Today)
.Or(Parse.String("yesterday").Return(DataFilterEntity.Yesterday)
.Or(Parse.String("last week").Return(DataFilterEntity.LastWeek)
.Or(Parse.String("last month").Return(DataFilterEntity.LastMonth)
.Or(Parse.String("none").Return(DataFilterEntity.None))
.Or(CustomParser))));
public void TestIt()
{
var result = TimeFilter.Parse("custom 21/3/2013 10/4/2013");
Console.Out.WriteLine("result.Value = {0}", result.Value);
}