Я новичок в Boost Spirit. В идеале я бы хотел, чтобы в моей грамматике было два значения одновременно, используя Phoenix. Урезанная версия того, что я пытаюсь заставить работать, будет кортежем, в котором оба целых числа равны.
Мне бы хотелось, чтобы строка «14,14, тест» была проанализирована, но «14,12, тест» не удалось, так как 14 не равно 12. Я бы хотел, чтобы напечатанный ниже код напечатал:
Good: (14 14 test)
Fail
В настоящее время оба ввода пройдут, поскольку я разрешаю и qi :: int_ анализировать второе значение без каких-либо проверок.
#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/spirit/include/qi_matches.hpp>
#include <string>
#include <vector>
#include <algorithm>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
int main(){
std::vector<std::string> test_inputs = {"14,14,test","14,12,test"};
std::for_each(test_inputs.begin(),test_inputs.end(),[](const std::string& input){
boost::fusion::vector<int,int,std::string> result;
int i(0);
auto res = qi::parse(input.begin(),input.end(),
//works but also parses "14,12,test"
qi::int_[phx::ref(i) = qi::_1] >> qi::lit(",") >> qi::int_ >> qi::lit(",") >> +qi::char_,
//Fails to compile
//qi::int_[phx::ref(i) = qi::_1] >> qi::lit(",") >> qi::int_(phx::val(i)) >> qi::lit(",") >> +qi::char_,
//qi::int_[phx::ref(i) = qi::_1] >> qi::lit(",") >> qi::int_(phx::ref(i)) >> qi::lit(",") >> +qi::char_,
result);
if(res){
std::cout << "Good: " << result << std::endl;
}
else{
std::cout << "Fail" << std::endl;
}
});
}
Я могу использовать phoenix :: ref для захвата первого значения, но я не могу понять, как проверить мой второй синтаксический анализатор qi :: int_ на значение i. Я пробовал использовать phoenix :: val и phoenix :: ref без компиляции. В идеале я хотел бы захватить значение во втором int и подумал, что парсер int_ возьмет ленивый литерал из Phoenix.
Спасибо за любую помощь в этом вопросе.
phx::ref
, который вы отметили как не компилируемый, работает, если вы определяетеBOOST_SPIRIT_USE_PHOENIX_V3
при использовании g ++ 4.8.1 и boost 1.54. Я бы рекомендовал всегда использовать это определение, оно решает множество проблем. - person llonesmiz   schedule 05.09.2013