global
解析中に、セマンティック アクションでのみ設定する必要があるいくつかの属性があります (それらは解析対象のデータから派生したものであり、変数と依存関係を回避したいBOOST_FUSION_ADAPT_STRUCT
だけでなく、複数のコードで再利用できるようにコードを汎用にする必要があるため)種類)。渡された複数の変数を使用するqi::phrase_parse
と、コンパイル エラーのリストが非常に長くなります。私はひどく助けが必要です:-)
#define BOOST_RESULT_OF_USE_DECLTYPE
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/function.hpp>
#include <boost/phoenix/fusion.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>
#include <climits>
namespace qi = boost::spirit::qi;
namespace ph = boost::phoenix;
namespace ascii = boost::spirit::ascii;
int main( int argc, char**argv )
{
bool rc;
std::string input("");
//Test case 1 works fine
{
auto iter( input.begin() );
auto last( input.end() );
int val1=33;
rc = qi::phrase_parse( iter, last, qi::eps[ qi::_val=11 ] ,
ascii::space, val1 ) && iter==last;
if( rc )
std::cout << "val1=" << val1 << std::endl;
}
//Test case 2 does not compile
{
auto iter( input.begin() );
auto last( input.end() );
int val1=33;
int val2=0;
rc = qi::phrase_parse( iter, last,
qi::eps[ ph::at_c<0>(qi::_val)=1,ph::at_c<1>(qi::_val)=2 ],
ascii::space, val1,val2 ) && iter==last;
if( rc )
std::cout << "val1=" << val1 <<
" val2=" << val2 << std::endl;
}
//Test case 3 works fine
{
auto iter( input.begin() );
auto last( input.end() );
int val1=33;
int val2=0;
rc = qi::phrase_parse( iter, last,
qi::attr(1)>>qi::attr(2),
ascii::space, val1,val2 ) && iter==last;
if( rc )
std::cout << "val1=" << val1 <<
" val2=" << val2 << std::endl;
}
return 0;
}
「カスタマイズされた」 my_phrase_parsecv_and_he
を取得しましたが、実行したい完全なテスト ケースでコンパイルが中断されます。
template<typename T,typename R>
void testParser( R rule )
{
for ( const auto input : std::vector< std::string >{ "5 1.0 2.0 3.0 4.0 5.0", "1 1.0", "0" , "", "2 3 ab" } )
{
bool rc;
T maxValue;
T minValue;
auto iter( input.begin() );
auto last( input.end() );
std::vector< T > v;
rc = my_phrase_parse( iter, last,
qi::eps[
ph::at_c<0>(qi::_val)=std::numeric_limits<T>::max(),
ph::at_c<1>(qi::_val)=std::numeric_limits<T>::min()
]
>> -( qi::omit[ qi::int_]
>> *rule[ ph::if_(ph::at_c<0>(qi::_val)>qi::_1)[ ph::at_c<0>(qi::_val)=qi::_1 ],
ph::if_(ph::at_c<1>(qi::_val)<qi::_1)[ ph::at_c<1>(qi::_val)=qi::_1 ]
] )
,ascii::space, minValue, maxValue,v ) && iter==last;
std::cout << ( rc ? "ok :`" : "err:`" ) << input << "` -> ";
if( rc )
{
std::cout << "min=" << minValue << " max=" << maxValue << "\t";
std::copy( v.begin(), v.end(), std::ostream_iterator<T>( std::cout," " ));
}
else
std::cout << *iter;
std::cout << std::endl;
}
}
...
testParser<double>( qi::double_ );