Правила совместимости атрибута boost::spirit::x3, интуиция или код?
Есть ли где-нибудь документ, описывающий, как различные операции определения правила spirit::x3 влияют на совместимость атрибутов?
Я был удивлен, когда:
x3::lexeme[ x3::alpha > *(x3::alnum | x3::char_('_')) ]
не может быть перемещен в адаптированную структуру:
struct Name {
std::string value;
};
В настоящее время я избавился от первого обязательного алфавитного символа, но все же хотел бы выразить правило, определяющее, что строка имени должна начинаться с буквы. Это одна из тех ситуаций, когда мне нужно попробовать добавить eps
где-то до тех пор, пока это не сработает, или есть заявленная причина, по которой вышесказанное не может работать?
Я прошу прощения, если это было записано где-то, я не мог найти это.
1 ответ
Если вы не участвуете в разработке, у вас нет исправления для этой ошибки адаптации одноэлементной последовательности, так что, возможно, это так.
Из-за универсальности преобразования / распространения атрибутов, здесь много места для маневра, но, конечно, это просто задокументировано и в конечном итоге в коде. Другими словами: нет волшебства.
В дни Ци я бы "исправил" это, просто прописав нужное преобразование с помощью qi::as<>
или же qi::attr_cast<>
, У X3 его нет (пока), но вы можете использовать правило, чтобы имитировать его очень легко:
#include <iostream>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
struct Name {
std::string value;
};
BOOST_FUSION_ADAPT_STRUCT(Name, value)
int main() {
std::string const input = "Halleo123_1";
Name out;
bool ok = x3::parse(input.begin(), input.end(),
x3::rule<struct _, std::string>{} =
x3::alpha >> *(x3::alnum | x3::char_('_')),
out);
if (ok)
std::cout << "Parsed: " << out.value << "\n";
else
std::cout << "Parse failed\n";
}
Печать:
Parsed: Halleo123_1
Автоматизировать это
Поскольку X3 так хорошо работает с основными языковыми возможностями C++14, сократить ввод текста несложно: