简体   繁体   English

具有继承属性的Boost Spirit解析器-简单示例无法编译

[英]Boost Spirit parser with inherited attributes - simple example won't compile

I'm trying to write a parser for a C-like language with boost::spirit that uses inherited attributes to transfer information about variable scope. 我正在尝试使用boost :: spirit为类C语言编写一个解析器,该解析器使用继承的属性来传递有关变量范围的信息。 For instance, "namespace a { var b }" would pass "a" as an attribute to the parser for "var b". 例如,“名称空间a {var b}”会将“ a”作为属性传递给“ var b”的解析器。

I'm having trouble getting a basic parser using inherited attributes to compile this code: 我在使用继承的属性来编译此代码的基本解析器方面遇到麻烦:

#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

This parser is instantiated in main() with cparser<std::string::const_iterator> parser . 该解析器在main()中使用cparser<std::string::const_iterator> parser实例化。

I believe this parser should accept a std::string as its inherited attribute, parse input matching this string, then return the string as a synthesised attribute. 我相信此解析器应接受std :: string作为其继承属性,解析与该字符串匹配的输入,然后将字符串作为综合属性返回。 This example code does not compile, and I cannot figure out why. 此示例代码无法编译,我无法弄清楚原因。 I have been compiling with GCC and Clang with C++11 enabled. 我一直在启用C ++ 11的情况下使用GCC和Clang进行编译。 The output from either compiler is huge (approx. 1000 lines), and I cannot make any sense of it. 任何一个编译器的输出都是巨大的(大约1000行),我对此毫无意义。 Is there a problem with the use of boost::spirit::qi::_r1 ? 使用boost::spirit::qi::_r1是否有问题? A problem with std::string(std::string) in the rule declarations? 规则声明中的std::string(std::string)有问题吗?

Thanks in advance for your help. 在此先感谢您的帮助。

I've tried to construct an example here . 我试图在这里构造一个例子。 I'm not sure I've faced the same issues you have(since you didn't provide a way to reproduce them) but I think there were two different problems: The first one, very common, is that PhoenixV2 does not work with "modern compilers" since the breaking change in Boost 1.52 that made BOOST_RESULT_OF_USE_DECLTYPE the default. 我不确定我是否遇到过同样的问题(因为您没有提供重现这些问题的方法),但是我认为存在两个不同的问题:第一个,非常普遍,是PhoenixV2无法使用自从Boost 1.52中的重大更改以来,“现代编译器”已将BOOST_RESULT_OF_USE_DECLTYPE为默认值。 There are two ways to solve this (at least with the clang version that coliru uses) either use V3 by defining BOOST_SPIRIT_USE_PHOENIX_V3 (this is what I would recommend, and I think it should be the default) or return the result_of protocol to the behaviour V2 expects by defining BOOST_RESULT_OF_USE_TR1 . 有两种方法可以解决此问题(至少使用coliru使用的clang版本),或者通过定义BOOST_SPIRIT_USE_PHOENIX_V3使用V3(这是我的建议,我认为应该是默认值),或者将result_of协议返回到行为V2通过定义BOOST_RESULT_OF_USE_TR1期望。 The second problem, of which I'm not as familiarized so take this with a grain of salt or simply wait for an answer from "someone" more experienced, is that it seems that you can't pass string literals directly as an inherited attribute, you need to pass them as a string (using phx::val("foo") also seems to work). 第二个问题是我似乎不太熟悉,因此不妨一salt而就,或者只是等待经验丰富的“某人”的回答,这似乎是您不能直接将字符串文字作为继承的属性传递,您需要将它们作为字符串传递(使用phx :: val(“ foo”)似乎也可以)。

Short version: Define BOOST_SPIRIT_USE_PHOENIX_V3 and pass your inherited attributes as a std::string not as a string literal. 简短版本:定义BOOST_SPIRIT_USE_PHOENIX_V3并将继承的属性作为std :: string而不是字符串文字传递。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM