При попытке разобрать текст в boost :: option, значение варианта не изменяется.
Сами парсеры, кажется, работают нормально, поэтому я предполагаю, что я делаю что-то не так с кодом варианта.
Я использую boost 1.46.1 и , следующий код компилируется в Visual Studio 2008.
1-е обновление
hkaiser отметил, что аргументы шаблона правила и грамматики должны быть не Variant
, а Variant()
.
Это немного "дальше", так как теперь у меня ошибка компиляции в boost_1_46_1\boost\variant\variant.hpp(1304)
. Комментарий гласит:
// NOTE TO USER :
// Compile error here indicates that the given type is not
// unambiguously convertible to one of the variant's types
// (or that no conversion exists).
Так что, очевидно, атрибут выражения (qi::double_ | +qi::char_)
не boost::variant<double, std::string>
. Но что тогда?
2-е обновление
Использование typedef boost::variant<double, std::vector<char>> Variant;
работает для парсера. Однако это не так просто использовать, как std :: string ...
#include <boost/spirit/include/qi.hpp>
#include <boost/variant.hpp>
int main()
{
namespace qi = boost::spirit::qi;
typedef std::string::const_iterator Iterator;
const std::string a("foo"), b("0.5");
// This works
{
std::string stringResult;
Iterator itA = a.begin();
const bool isStringParsed =
qi::parse(itA, a.end(), +qi::char_, stringResult);
double doubleResult = -1;
Iterator itB = b.begin();
const bool isDoubleParsed =
qi::parse(itB, b.end(), qi::double_, doubleResult);
std::cout
<< "A Parsed? " << isStringParsed <<
", Value? " << stringResult << "\n"
<< "B Parsed? " << isDoubleParsed <<
", Value? " << doubleResult << std::endl;
// Output:
// A Parsed? 1, Value? foo
// B Parsed? 1, Value? 0.5
}
// This also works now
{
typedef boost::variant<double, std::vector<char>> Variant; // vector<char>, not string!
struct variant_grammar : qi::grammar<Iterator, Variant()> // "Variant()", not "Variant"!
{
qi::rule<Iterator, Variant()> m_rule; // "Variant()", not "Variant"!
variant_grammar() : variant_grammar::base_type(m_rule)
{
m_rule %= (qi::double_ | +qi::char_);
}
};
variant_grammar varGrammar;
Variant varA(-1), varB(-1);
Iterator itA = a.begin();
const bool isVarAParsed = qi::parse(itA, a.end(), varGrammar, varA);
Iterator itB = b.begin();
const bool isVarBParsed = qi::parse(itB, b.end(), varGrammar, varB);
// std::vector<char> cannot be put into std::cout but
// needs to be converted to a std::string (or char*) first.
// The conversion I came up with is very ugly but it's not the point
// of this question anyway, so I omitted it.
// You'll have to believe me here, when I'm saying it works..
// Output:
// A (variant): Parsed? 1, Value? foo, Remaining text = ''
// B (variant): Parsed? 1, Value? 0.5, Remaining text = ''
}
return 0;
}