3

私はブーストスピリットにまったく慣れていません。理想的には、Phoenix を使用して文法の 2 つの値を同時に確認したいと考えています。私が機能させようとしているものの単純化されたバージョンは、両方の int が等しいタプルになります。

「14,14,test」の文字列を解析したいのですが、「14,12,test」は 14 が 12 と等しくないため失敗します。以下のコードを出力したいと思います。

Good: (14 14 test)
Fail

現在、qi::int_ がチェックなしで 2 番目の値を解析することを許可しているため、両方の入力が渡されます。

#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 を使用して最初の値を取得できますが、2 番目の qi::int_ パーサーで i の値をテストする方法がわかりません。私は phoenix::val と phoenix::ref を使ってみましたが、うまくコンパイルできませんでした。理想的には、2 番目の int の値を取得したいと考えており、int_ パーサーは Phoenix から遅延リテラルを受け取ると考えていました。

これに関するすべての助けに感謝します。

4

1 に答える 1

5

最も簡単な修正はi、最初の qi::int_ から取得した値を 2 番目の qi::int_ に渡すことです。

qi::int_[phx::ref(i) = qi::_1] >> qi::lit(",") >> qi::int_(phx::ref(i)) >> qi::lit(",") >> +qi::char_,

パラメータを指定した qi::_int は、指定された値を想定しています。

考慮すべきもう 1 つの代替手段は、ルール ローカル変数の使用です。あなたはこれを行うことができます:

typedef boost::fusion::vector<int,int,std::string> result_t;
result_t result;
qi::rule<std::string::const_iterator, result_t(),
     boost::spirit::qi::locals<int> > r;
r %= qi::int_[qi::_a = qi::_1] >> qi::lit(",") >> qi::int_(qi::_a) >> qi::lit(",") >> +qi::char_;

次に、ルールの代わりに「r」を使用します。qi::parse を使用してルールを直接実行するつもりなら、これは意味がありません。

于 2013-09-05T18:57:14.463 に答える