Как стать автором
Обновить

Комментарии 9

Как обстоят дела со временем сборки? Я как то использовал spirit для разбора математических выражений с дополнительными фичами, так у меня парсер собирался минут 10 (MinGW на Windows).
Я работаю со связкой conan + cmake + ninja + clang8. Если «на холодную», то есть conan install, потом cmake, потом билд. То да, это прямо скажем небыстрый процесс, особенно, если зависимые библиотеки конан собирает на месте. Если же зависимости уже лежат готовые в ~/.conan/data, то я бы не сказал, что все так уж плохо. Вся библиотека(которая состоит из многих инструментов помимо фильтра) с тестами, которые проверяют и парсер в том числе, собирается за 2 минуты.
Если в ISPManager все архитектурные решения принимаются так, как указано здесь — то не зря я все это время их сторонился.

Это же надо, сделать отдельный DSL для запросов, чтобы на фронте (!) фильтровать данные от бекенда. Вы ему не доверяете? Или ваш бекенд не в состоянии сам отфильтровать данные?

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


GET "/user/list?where%3Dname%20EQ%20Ivan"
Такой вопрос… Вот если посмотреть на строчку:
start = (product >> '+' >> start)[qi::_val = phx::new_<OperatorNode<'+'>> (qi::_1, qi::_2)]
| product[qi::_val = qi::_1];
Здесь мы видим, что узлы дерева создаются в динамической памяти, но вот не понятно, кто их потом освобождать будет?
Если парсинг завершился успешно, то тут все нормально, корневой узел удалит своих потомков. По парсинг может отвалиться на середине, тогда корневой узел никогда не будет создан а дочерние уже созданы(вот кто их будет освобождать?).

Или же phx::new_ там у себя внутри регистрирует все указатели где-то? Чтобы в случае неудачи освободить их все(звучит вроде логично, я пытался смотреть сам в коде phx::new_, но там мясоо..)

А так, спасибо за статью. Редко такой материал здесь увидишь.

Это замечательный вопрос! Все именно так, как вы говорите. В изначальном примере создается как раз-таки raw pointer, по крайней мере, разбираясь в этом вопросе я не нашел подтверждения обратного. И никто не позаботится о них в случае каких-то форс-мажоров. Именно поэтому, я использую в своих фильтрах только shared_ptr. На нашем обожаемом stackoverflow я нашел подходящее решение для феникса Phoenix make_shared. Как раз его-то я и использую тут:


  expression = (product >> skipper >> qi::no_case["OR"] >> skipper >> expression)  
      [qi::_val = make_shared_<LogicNode<Logic::OR>>()(qi::_1, qi::_2)] |  
  product[qi::_val = qi::_1];

Очень рад, что этот материал вас порадовал)

Ну shared_ptr для моего случая слишком жирно… Хоть бы на самописную обертку его заменить — без атомарного счетчика.
field = qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9");

Интересный у вас выбор парсера для строкового идентификатора. Не лучше ли было бы:
lexeme[(alpha | '_') >> *(alnum | '_')];

Догадываюсь, что «f i e l d And f i e l d 2» он у вас разберет как «field And field2»:)
НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре, чтобы оставить комментарий