以前に解析した値に基づいてルールを定義したいと思います。つまり、入力文字列の構造はD <double number>
orI <integer number>
です。最初に読み取った文字が か かどうかをローカルのブール変数に保持しD
ますI
。完全なコードは次のとおりです。
#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;
}
出力は次のとおりですdouble Pass!
。ステートメントを認識せif
ず、解析された数値を出力しません!
注: 上記の例を解析する簡単な方法が他にもあることはわかっています。解析する必要がある実際の文字列は非常に複雑に見えますが、この例は私が達成したいことを示しています。一般的な目標は、ローカル変数を使用し、それらの変数に基づいて他のルールを定義することです。
私は 4.6.1 と Boost 1.55 のバージョンを使用しました。