Steigern Sie den Geist mit lokalen Variablen

Ich möchte eine Regel definieren, die auf einem zuvor analysierten Wert basiert, d.h. e. Die Eingabezeichenfolge hat die folgende Struktur:D <double number> oderI <integer number>. Ich behalte in einer lokalen booleschen Variablen, ob das erste gelesene Zeichen istD oderI. Der vollständige Code lautet:

#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>

namespace qi = boost::spirit::qi;
namespace spirit = boost::spirit;
namespace ascii = boost::spirit::ascii;
using boost::phoenix::ref;

template <typename Iterator>
struct x_grammar : public qi::grammar<Iterator, std::string(), ascii::space_type>
{
public:
    x_grammar() : x_grammar::base_type(start_rule, "x_grammar")
    {
        using namespace qi;
        bool is_int = false;
        start_rule = lit("I")[ref(is_int) = true] | lit("D")[ref(is_int) = false] > digit_rule;
        if(ref(is_int)()) {
            digit_rule = int_[std::cout << "int " << _1 << ".\n"];
        } else {
            digit_rule = double_[std::cout << "double " << _1 << ".\n"];
        }
    }
private:
    qi::rule<Iterator, std::string(), ascii::space_type> start_rule;
    qi::rule<Iterator, std::string(), ascii::space_type> digit_rule;
};

int main()
{
    typedef std::string::const_iterator iter;
    std::string storage("I 5");
    iter it_begin(storage.begin());
    iter it_end(storage.end());
    std::string read_data;
    using boost::spirit::ascii::space;
    x_grammar<iter> g;
    try {
        bool r = qi::phrase_parse(it_begin, it_end, g, space, read_data);
        if(r) {
            std::cout << "Pass!\n";
        } else {
            std::cout << "Fail!\n";
        }
    } catch (const qi::expectation_failure<iter>& x) {
        std::cout << "Fail!\n";
    }
    return 0;
}                                                                                                                                                    

Die Ausgabe ist:double Pass! !! Es erkennt weder dieif Anweisung, noch druckt die analysierte Zahl!

Hinweis: Ich weiß, dass es andere einfache Möglichkeiten gibt, das obige Beispiel zu analysieren. Die eigentliche Zeichenfolge, die ich analysieren muss, sieht ziemlich kompliziert aus, und dieses Beispiel zeigt nur, was ich erreichen möchte. Das allgemeine Ziel besteht darin, lokale Variablen zu verwenden und andere Regeln basierend auf diesen Variablen zu definieren.

Ich habe 4.6.1 und Boost 1.55 Versionen verwendet.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage