Парсинг запроса пользователя

Тогда я смог найти хорошее решение.

Это ValidatedField класс.

template
struct ValidatedType : Type {
    friend InBitStream &operator>>(InBitStream &stream, ValidatedType &v)
    {
        stream >> static_cast(v);
        Validator::validate(v);
        return stream;
    }
};

Это просто создает тег для проверенного типа. Оператор потока >> отправляется с его использованием. Тип шаблона Type используется для представления встроенного типа, а тип Validator используется как functor. Валидатор должен предоставлять статическую функцию validate(Type &const).

В реализации потокового оператора аргумент v должен быть передан в Type &, чтобы правильно вызвать ту же операцию для «оформленного» типа.

Вот как это используется:

   struct XTag {
    };
    enum class XEnum {
        A = 1, B = 2, C = 3, D = 4,
    };
    using XE = utils::BitAwareEnum<4, XEnum, XTag>;
    struct XValidator {
        static void validate(XE const &x)
        {
            if (x.underlyingValue() <= 0 || x.underlyingValue() > 4) {
                throw utils::InBitStream::IllegalValueException("Illegal XE value");
            }
        }
    };
    using X = utils::ValidatedType;
    X x;

Что мне нравится в этом решении: - У меня есть «дерево» декорированных типов, функциональные возможности которого могут быть «подключены» по мере необходимости

Что мне не нравится в этом решении: - Структура XValidator как-то многословна, я бы предпочел иметь более читаемый способ ее реализации. Мне нужно помнить, что функция validate() должна быть объявлена ​​статической.

Не стесняйтесь комментировать с улучшениями или альтернативными решениями.

Для смелых, проект с открытым исходным кодом здесь: https://gitlab.com/ffuga/gutils


Обновление:

Действительно как @Incomputable отметил, что это основанный на политике дизайн .

Переставляя код, как в примере на странице википедии, я исправил «статическую» проблему.

Это довольно определенный код:

template
struct ValidatedType : Type, Validator {
    using Validator::validate;
    friend InBitStream &operator>>(InBitStream &stream, ValidatedType &v)
    {
        stream >> static_cast(v);
        v.validate(v);
        return stream;
    }
};

Использование:

   struct XValidator {
        void validate(XE const &x)
        {
            if (x.underlyingValue() <= 0 || x.underlyingValue() > 4) {
                throw utils::InBitStream::IllegalValueException("Illegal XE value");
            }
        }
    };

5
задан Joel Martinez 9 December 2008 в 04:40
поделиться

8 ответов

Вы описываете язык программирования. Предоставленный это - маленький язык (часто названный небольшим языком или Предметно-ориентированным языком (DSL)). Если Вы никогда не слышали термин синтаксический анализатор с рекурсивным спуском, Вы - вероятно, совет и использование более обеспеченного следующего Paul выпадающих полей некоторого описания.

Однако снова я должен был бы согласиться с ним, что, если Вы хотите сделать это, Antlr является способом пойти. Существуют учебные руководства на сайте, который мог бы помочь Вам начать. В основном необходимо будет описать как синтаксис с помощью нотации Формы Бэкуса-Наура.

Вы затем выполните Antlr по своему grammer, и он генерирует Ваш синтаксический анализатор. Можно затем подать вход из учебника в Абстрактное синтаксическое дерево. Можно затем использовать то Дерево для генерации запроса. Это не столь трудно, как все это звучит, но существует немного к нему.

Если Вы действительно в это и/или хотите расширить крылья программирования немного, Вы могли читать больше по теме с Книгой Дракона, иначе Компиляторами: Принципы, Методы и инструменты.

Удача мой друг.

4
ответ дан 13 December 2019 в 22:18
поделиться

Для очень простого языка я пошел бы с regexps. Основное преимущество там - Вы, не должны иметь дело ни с какой генерацией кода. Отладка сопоставления с образцом является в основном нолем, все же.

Если бы Ваш язык умеренно сложен (Вы не возражали бы указывать всю вещь в единственном файле грамматики), я пойду с Coco/R - это быстро, просто в использовании, и делает чрезвычайно debuggable код.

Для более сложного языка моим текущим фаворитом является Antlr v3. Поддерживает многофайловые грамматики (через оператор 'импорта'), который очень хорош. Сгенерированный код debuggable, но берет немного привыкающее к тому, прежде чем отладку можно было считать 'легкой'.

3
ответ дан 13 December 2019 в 22:18
поделиться

Дерево выражений является хорошей идеей. Существует много хороших общих синтаксических анализаторов и парсеров-генераторов там, открытого исходного кода, а также коммерческие, который может преобразовать корректные строки запроса в деревья выражений.

1
ответ дан 13 December 2019 в 22:18
поделиться

Я был в этой ситуации прежде. После большого обсуждения мы решили, что контекстно-зависимый выпадает, было лучшее решение, чем просто текстовое поле.

Например, имейте 4, выпадает, но последние 3 отключены. Затем когда пользователь выбирает опцию сначала, она заполняет и включает другим. Таким образом, они выбрали бы, "просматривают все" затем "между" и затем возможно, выталкивают текстовое поле или календарь для последних двух.

Вот пример, это отчасти похоже на то, о чем я говорю

2
ответ дан 13 December 2019 в 22:18
поделиться

Используйте Осло, это специально разработано для этого...

1
ответ дан 13 December 2019 в 22:18
поделиться

Я не знаю, поможет ли это Вам, но что мы сделали был: мы дали предопределенный criterias пользователя как для выбора даты, мы дали им два календарных всплывающих окна так, чтобы они могли выбрать от, и до диапазона дат... мы не сделали его обязательным.. так использование фильтра даты для применения только, когда пользователь указывает даты... так же, можно также дать пользователям предопределенный выбор критериев... другой затем, что дерево выражений, кажется, хорошее обходное решение для этого.

0
ответ дан 13 December 2019 в 22:18
поделиться

Попытка проанализировать тот материал была бы аварией, и в конечном счете очень ограничивающий пользователем, таким образом расстроив их более затем помощь им. Я предложил бы использовать предопределенный Запрос clasues с некоторым инструментом конструктора запросов, который имеет все доступные варианты в выпадающей форме. У Вас могут быть различные булевы операторы для различных Типов данных (больше, чем, меньше, чем для числового, как не как для строк и т.д.), однако я думаю, что это сделало бы чертову партию большим смыслом, чем фактическая попытка проанализировать, что может ввести пользователь.

-1
ответ дан 13 December 2019 в 22:18
поделиться

ЗОЛОТОЙ Парсер-генератор имеет полезный UI для разработки и тестирования Вашей грамматики, довольно хороших учебных руководств и документации, и прост в использовании от C#.

0
ответ дан 13 December 2019 в 22:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: