1

I am using spiri::qi to parse a text and pushing what I parse into a vector<string>, for the most part its fine since they are mostly names and addresses, but there are also some numbers that I am parsing with double_, but once I push it to the vector it considers it a character code, like '\x3' in lieu of 3.0. I don’t want to make use of variant since its too much work for just a few cases. Is there anyway I can convert the result of double_ to string before pushing it?

sehe
  • 374,641
  • 47
  • 450
  • 633
nihil
  • 85
  • 1
  • 8

2 Answers2

3

Use raw[double_] (or even more exactly as_string[raw[double_]]).

The first works like any rule that has attribute compatibility with a container of characters. The latter atomically exposes a std::string (there's one for std::wstring as well).

BONUS

To complete Jonathan Mee's suggestion to "just use the language" (paraphrasing... :)) you can, see the last demo grammar below:

Live On Coliru

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace qi = boost::spirit::qi;
namespace px = boost::phoenix;

int main() {

    using It = std::string::const_iterator;
    auto to_string_f = [](auto v) { return std::to_string(v); };
    px::function<decltype(to_string_f)> to_string_ { to_string_f };

    for (std::string const input : { "3.14", "+inf", "NaN", "-INF", "99e-3" })
    {
        for (auto const& grammar : std::vector<qi::rule<It, std::string()>> {
                //qi::double_,  // results in strange binary interpretations, indeed
                qi::raw[ qi::double_ ], 
                qi::as_string [ qi::raw[ qi::double_ ] ], 
                qi::double_ [ qi::_val = to_string_(qi::_1) ], 
            })
        {
            auto f = input.begin(), l = input.end();
            std::string result;
            if (qi::parse(f, l, grammar, result))
                std::cout << input << "\t->\t" << result << "\n";
            else
                std::cout << "FAILED for '" << input << "'\n";
        }
    }
}

Printing

3.14    ->  3.14
3.14    ->  3.14
3.14    ->  3.140000
+inf    ->  +inf
+inf    ->  +inf
+inf    ->  inf
NaN ->  NaN
NaN ->  NaN
NaN ->  nan
-INF    ->  -INF
-INF    ->  -INF
-INF    ->  -inf
99e-3   ->  99e-3
99e-3   ->  99e-3
99e-3   ->  0.099000

Note that std::to_string doesn't result in the literal input, so it might not roundtrip faithfully for your purposes.

sehe
  • 374,641
  • 47
  • 450
  • 633
  • Added a demo [Live On Coliru](http://coliru.stacked-crooked.com/a/3c3a3dc73fd90557) – sehe Dec 21 '15 at 16:31
0

If your question is just:

Anyway I can convert the result of double_ to string before pushing it?

Then yeah you can convert any number back into a string using to_string.

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • That's not really answering the question in context, since I bet you can't show how to use `to_string` from within a Qi grammar rule. – sehe Dec 21 '15 at 16:13
  • @sehe I had taken the phrase "the result of `double_` to `string`" to mean that he had already extracted the value into a variable. But I've given you a +1 cause you're right, doing it directly in the grammar vastly simplifies the problem. – Jonathan Mee Dec 21 '15 at 16:22
  • Just completed a sample that also shows how `std::to_string` could in fact be used (not though that doing that might loose some information from the input, because the representation will be whatever `std::to_string` chooses, not the actual input). – sehe Dec 21 '15 at 16:33
  • @sehe Nice I'd give you another +1 but, you've already got mine :) – Jonathan Mee Dec 21 '15 at 16:47