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);
}
Другие вопросы по тегам