使用继承属性提升Spirit解析器 - 简单示例将无法编译

时间:2013-12-07 10:26:47

标签: c++ boost boost-spirit

我正在尝试使用boost :: spirit为类C语言编写一个解析器,它使用继承的属性来传输有关变量范围的信息。例如,“namespace a {var b}”会将“a”作为属性传递给“var b”的解析器。

我无法使用继承属性来获取基本解析器来编译此代码:

#ifndef CPARSER_DEF_HPP
#define CPARSER_DEF_HPP

#include <string>

#include <boost/spirit/include/qi.hpp>

namespace encoding = boost::spirit::ascii;
using boost::spirit::unused_type;
using boost::spirit::qi::rule;

template <typename Iterator>
struct cparser : boost::spirit::qi::grammar<
                    Iterator,
                    std::string(std::string),
                    encoding::space_type
                    >
{
    rule<Iterator, std::string(std::string), encoding::space_type> start;
    rule<Iterator, std::string(std::string), encoding::space_type> sym_list;

    cparser() :
        cparser::base_type(start)
    {
        sym_list         = encoding::string(boost::spirit::qi::_r1);
        start            = sym_list(boost::spirit::qi::_r1);
    }

};

#endif

此解析器在main()中使用cparser<std::string::const_iterator> parser进行实例化。

我相信这个解析器应该接受std :: string作为其继承属性,解析匹配此字符串的输入,然后将该字符串作为合成属性返回。这个示例代码没有编译,我无法弄清楚原因。我一直在使用GCC和Clang编译,启用了C ++ 11。任何一个编译器的输出都是巨大的(大约1000行),我无法理解它。使用boost::spirit::qi::_r1时是否存在问题?规则声明中std::string(std::string)存在问题?

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:5)

我试图构建一个示例here。我不确定我是否遇到了同样的问题(因为你没有提供重现它们的方法)但我认为有两个不同的问题:第一个,非常常见,是PhoenixV2无法使用“现代编译器”自Boost 1.52发生突破性变化以来,BOOST_RESULT_OF_USE_DECLTYPE成为默认值。 有两种方法可以解决这个问题(至少使用coliru使用的clang版本)或者通过定义BOOST_SPIRIT_USE_PHOENIX_V3来使用V3(这是我推荐的,我认为它应该是默认值)或者返回result_of协议通过定义BOOST_RESULT_OF_USE_TR1来预期V2的行为。第二个问题,其中我并不熟悉,所以请稍等一下,或者只是等待“更有经验的人”的回答,是因为你似乎无法直接将字符串文字作为继承属性传递,你需要将它们作为一个字符串传递(使用phx :: val(“foo”)似乎也可以工作)。

简短版本:定义BOOST_SPIRIT_USE_PHOENIX_V3并将您继承的属性作为std :: string传递,而不是作为字符串文字传递。