具有继承属性的增强精神解析器 - 简单示例无法编译



我正在尝试为具有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::字符串作为它的继承属性,解析与这个字符串匹配的输入,然后将这个字符串作为合成属性返回。这个示例代码没有编译,我不知道为什么。我一直在用GCC和Clang编译,并启用了C++11。两个编译器的输出都很大(大约1000行),我无法理解。boost::spirit::qi::_r1的使用有问题吗?规则声明中的std::string(std::string)有问题吗?

提前感谢您的帮助。

我试图在这里构造一个示例。我不确定我是否遇到过与您相同的问题(因为您没有提供复制它们的方法),但我认为有两个不同的问题:第一个非常常见的问题是PhoenixV2无法与"现代编译器"一起使用,因为Boost 1.52中的突破性更改使BOOST_RESULT_OF_USE_DECLTYPE成为默认值。有两种方法可以解决这个问题(至少对于coliru使用的clang版本),要么通过定义BOOST_SPIRIT_USE_PHOENIX_V3来使用V3(这是我建议的,我认为应该是默认的),要么将协议的结果返回到V2通过定义BOOST_RESULT_OF_USE_TR1所期望的行为。第二个问题,我不太熟悉,所以对此持保留态度,或者只是等待更有经验的"某人"的回答,就是你似乎不能直接将字符串文本作为继承属性传递,你需要将它们作为字符串传递(使用phx::val("foo")似乎也有效)。

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

最新更新