правило spirit x3 не может синтезировать атрибут типа boost:: iterator range в синтаксическом анализаторе последовательностей
В простом тесте парсера Live On Coliru ,
std::string str("x123x");
boost::iterator_range<boost::range_iterator<decltype(str)>::type> attr;
if( x3::parse( boost::begin(str), boost::end(str), x3::lit('x') >> x3::raw[+x3::digit] >> x3::lit('x'), attr ) ) {
std::cout<<"Match! attr = "<<attr<<std::endl;
} else {
std::cout<<"Not match!"<<std::endl;
}
Синтаксический анализатор
x3::lit('x') >> x3::raw[+x3::digit] >> x3::lit('x')
Предполагается синтезировать атрибут типа boost::iterator_range<Iterator>
. Но он не может компилироваться. Если мы удалим один из двух x3::lit('x')
, он компилируется. Тот же код компилируется с ци, хотя живут на Колиру.
1 ответ:
Интересно. На самом деле он компилирует:
#include <iostream> #include <boost/spirit/home/x3.hpp> namespace x3 = boost::spirit::x3; int main() { std::string const str("x123x"); boost::iterator_range<std::string::const_iterator> attr; if(x3::parse(boost::begin(str), boost::end(str), x3::raw[+x3::digit], attr)) { std::cout<<"Match! attr = "<<attr<<std::endl; } else { std::cout<<"Not match!"<<std::endl; } }
То, что заставляет его ломаться, - это окружающий контекст:
// simple (ok): x3::parse(boost::begin(str), boost::end(str), x3::raw[+x3::digit], attr); // ok: parse(boost::begin(str), boost::end(str), x3::eps >> x3::raw[+x3::digit], attr); parse(boost::begin(str), boost::end(str), x3::raw[+x3::digit] >> x3::eps, attr); // breaks: parse(boost::begin(str), boost::end(str), x3::eps >> x3::raw[+x3::digit] >> x3::eps, attr);
Я предполагаю, что каким-то образом метапрограммирование ошибочно трактует
iterator_range
как последовательность слияния в таком случае. Конечно, я думаю, что это ошибка.Вы должны сообщить об этом выше по течению.
К сожалению, я не нашел "гомеопатического" решения проблемы.