C++11 如何定义此boost spirit规则的AST?
我有一个更复杂的规则,但这个规则足以解决这个问题(我希望)。考虑规则:C++11 如何定义此boost spirit规则的AST?,c++11,boost-spirit,C++11,Boost Spirit,我有一个更复杂的规则,但这个规则足以解决这个问题(我希望)。考虑规则: result = double_ >> *(char_ > int_); 其中,结果是根据命名空间ast中的结构结果声明的: qi::rule<Iterator, ast::result(), qi::space_type> result; 除了 BOOST_FUSION_ADAPT_STRUCT( ast::result, (double, first), (ast::seco
result = double_ >> *(char_ > int_);
其中,结果是根据命名空间ast中的结构结果声明的:
qi::rule<Iterator, ast::result(), qi::space_type> result;
除了
BOOST_FUSION_ADAPT_STRUCT(
ast::result,
(double, first),
(ast::second_type, second)
)
但这给了我编译错误:
error: no matching function for call to 'std::pair<char, int>::pair(const char&)'
错误:调用'std::pair::pair(const char&')没有匹配的函数
这个规则很简单,创建结果将存储在其中的AST结构也应该很简单。。。但是怎么做呢
以下是我尝试的完整测试程序:
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <iostream>
#include <string>
#include <vector>
namespace ast
{
using second_type = std::vector<std::pair<char, int>>;
struct result
{
double first;
second_type second;
friend std::ostream& operator<<(std::ostream& os, result const& result);
};
std::ostream& operator<<(std::ostream& os, second_type::value_type val)
{
return os << val.first << ' ' << val.second;
}
std::ostream& operator<<(std::ostream& os, result const& result)
{
os << result.first;
for (auto& i : result.second)
os << ' ' << i;
return os;
}
} // namespace ast
BOOST_FUSION_ADAPT_STRUCT(
ast::result,
(double, first),
(ast::second_type, second)
)
namespace client
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
template <typename Iterator>
class test_grammar : public qi::grammar<Iterator, ast::result(), qi::space_type>
{
private:
qi::rule<Iterator, ast::result(), qi::space_type> result;
public:
test_grammar() : test_grammar::base_type(result, "result_grammar")
{
using qi::double_;
using qi::char_;
using qi::int_;
result = double_ >> *(char_ > int_);
}
};
} // namespace client
int main()
{
std::string const input{"3.4 a 5 b 6 c 7"};
using iterator_type = std::string::const_iterator;
using test_grammar = client::test_grammar<iterator_type>;
namespace qi = boost::spirit::qi;
test_grammar program;
iterator_type iter{input.begin()};
iterator_type const end{input.end()};
ast::result out;
bool r = qi::phrase_parse(iter, end, program, qi::space, out);
if (!r || iter != end)
{
std::cerr << "Parsing failed." << std::endl;
return 1;
}
std::cout << "Parsed: " << out << std::endl;
}
#包括
#包括
#包括
#包括
#包括
#包括
名称空间ast
{
使用第二种类型=std::vector;
结构结果
{
双优先;
第二类;
friend std::ostream&operator我做了以下更改:
#include <boost/fusion/tuple.hpp>
using second_type = std::vector<boost::fusion::tuple<char, int>>;
std::ostream& operator<<(std::ostream& os, second_type::value_type val)
{
return os << boost::fusion::get<0>(val) << ' ' << boost::fusion::get<1>(val);
}
#包括
使用第二种类型=std::vector;
std::ostream&operatorsirgue更改了AST以适应默认的合成属性。代价是,确实使AST复杂化了
但是,您可以通过调整std::pair
来利用属性兼容性规则。事实上,这非常简单,只需包含1个标头:
#include <boost/fusion/include/std_pair.hpp>
如果你想走这条路,你最好包括Fusion的io.hpp
:谢谢!你基本上说的和sehe是一样的,也就是说,std::pair不受支持(不包括头)。如果不是因为文档简单地说明std::pair确实有效,而不提及标题,我会尝试完全这样做。我认为这是spirit文档的一个普遍问题;它似乎完全忽略了一个事实,即除非包含正确的标题,否则事情不会起作用,而从不谈论(那些标题)标题:/。
#include <boost/fusion/include/std_pair.hpp>
Parsed: 3.4 a 5 b 6 c 7