【问题标题】:Errors compiling very simple boost::spirit grammar编译非常简单的 boost::spirit 语法时出错
【发布时间】:2014-05-27 21:03:43
【问题描述】:

我一直在学习 Boost::Spirit 的教程,我正在尝试编译一个超级简单的解析器,用于将数字相加,大致基于文档中的 MiniXML example。我在 Xcode 5.1.1 中编译时遇到问题。

我把它简化了,发现即使是语法的定义也不会编译。这是它的当前状态:

语法.h:

#pragma once

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

namespace qi = boost::spirit::qi;


template <typename Iterator>
struct ExpressionGrammer : qi::grammar<Iterator, double(), ascii::space_type>
{
    qi::rule<Iterator, double(), ascii::space_type> expression;
    qi::rule<Iterator, double(), ascii::space_type> addsub;

    ExpressionGrammer()
    : ExpressionGrammer::base_type(expression)
    {
        using qi::lit;

        addsub = (expression >> '+' >> expression)[_val = _1 + _2];     
        expression = (addsub | qi::double_)[_val = _1];
    }
};

语法.cpp:

#include "Syntax.h"

// Nothing else

从解析问题“匿名结构的声明必须是定义”开始,这些错误又长又详细,但没有提供信息。第一部分我将粘贴在这里。 (注意行号不匹配,因为我省略了注释掉的代码)

In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/Syntax.cpp:9:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/Syntax.h:12:
In file included from ../../../Cinder/boost/boost/spirit/include/qi.hpp:16:
In file included from ../../../Cinder/boost/boost/spirit/home/qi.hpp:14:
In file included from ../../../Cinder/boost/boost/spirit/home/qi/action.hpp:14:
In file included from ../../../Cinder/boost/boost/spirit/home/qi/action/action.hpp:14:
In file included from ../../../Cinder/boost/boost/spirit/home/qi/meta_compiler.hpp:14:
In file included from ../../../Cinder/boost/boost/spirit/home/support/meta_compiler.hpp:19:
In file included from ../../../Cinder/boost/boost/proto/proto.hpp:12:
In file included from ../../../Cinder/boost/boost/proto/core.hpp:21:
In file included from ../../../Cinder/boost/boost/proto/fusion.hpp:22:
In file included from ../../../Cinder/boost/boost/fusion/include/intrinsic.hpp:10:
In file included from ../../../Cinder/boost/boost/fusion/sequence/intrinsic.hpp:11:
In file included from ../../../Cinder/boost/boost/fusion/sequence/intrinsic/back.hpp:11:
In file included from ../../../Cinder/boost/boost/fusion/sequence/intrinsic/end.hpp:17:
In file included from ../../../Cinder/boost/boost/fusion/sequence/intrinsic/detail/segmented_end.hpp:10:
In file included from ../../../Cinder/boost/boost/fusion/sequence/intrinsic/detail/segmented_end_impl.hpp:14:
../../../Cinder/boost/boost/fusion/container/list/cons_fwd.hpp:13:5: error: declaration of anonymous struct must be a definition
    struct nil;
    ^
../../../Cinder/boost/boost/fusion/container/list/cons_fwd.hpp:13:5: warning: declaration does not declare anything [-Wmissing-declarations]
    struct nil;
    ^~~~~~
../../../Cinder/boost/boost/fusion/container/list/cons_fwd.hpp:15:44: error: expected a type
    template <typename Car, typename Cdr = nil>
                                           ^
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/Syntax.cpp:1:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/SpiritTest_Prefix.pch:8:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/../../../Cinder/include/cinder/app/AppBasic.h:27:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/../../../Cinder/include/cinder/app/App.h:27:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/../../../Cinder/include/cinder/app/Renderer.h:32:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/ApplicationServices.framework/Headers/ApplicationServices.h:23:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/CoreServices.framework/Headers/CoreServices.h:19:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CoreFoundation.h:38:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CFBase.h:68:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/MacTypes.h:90:17: note: expanded from macro 'nil'
    #define nil NULL
                ^
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/Syntax.cpp:1:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/SpiritTest_Prefix.pch:6:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/../../../Cinder/include/cinder/Cinder.h:92:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/chrono:280:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/type_traits:203:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/cstddef:44:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/5.1/include/stddef.h:72:18: note: expanded from macro 'NULL'
#    define NULL __null
                 ^
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/Syntax.cpp:9:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/Syntax.h:12:
In file included from ../../../Cinder/boost/boost/spirit/include/qi.hpp:16:
In file included from ../../../Cinder/boost/boost/spirit/home/qi.hpp:14:
In file included from ../../../Cinder/boost/boost/spirit/home/qi/action.hpp:14:
In file included from ../../../Cinder/boost/boost/spirit/home/qi/action/action.hpp:14:
In file included from ../../../Cinder/boost/boost/spirit/home/qi/meta_compiler.hpp:14:
In file included from ../../../Cinder/boost/boost/spirit/home/support/meta_compiler.hpp:19:
In file included from ../../../Cinder/boost/boost/proto/proto.hpp:12:
In file included from ../../../Cinder/boost/boost/proto/core.hpp:21:
In file included from ../../../Cinder/boost/boost/proto/fusion.hpp:22:
In file included from ../../../Cinder/boost/boost/fusion/include/intrinsic.hpp:10:
In file included from ../../../Cinder/boost/boost/fusion/sequence/intrinsic.hpp:11:
In file included from ../../../Cinder/boost/boost/fusion/sequence/intrinsic/back.hpp:11:
In file included from ../../../Cinder/boost/boost/fusion/sequence/intrinsic/end.hpp:17:
In file included from ../../../Cinder/boost/boost/fusion/sequence/intrinsic/detail/segmented_end.hpp:10:
In file included from ../../../Cinder/boost/boost/fusion/sequence/intrinsic/detail/segmented_end_impl.hpp:14:
../../../Cinder/boost/boost/fusion/container/list/cons_fwd.hpp:15:44: error: expected ',' or '>' in template-parameter-list
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/Syntax.cpp:1:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/SpiritTest_Prefix.pch:8:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/../../../Cinder/include/cinder/app/AppBasic.h:27:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/../../../Cinder/include/cinder/app/App.h:27:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/../../../Cinder/include/cinder/app/Renderer.h:32:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/ApplicationServices.framework/Headers/ApplicationServices.h:23:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/CoreServices.framework/Headers/CoreServices.h:19:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CoreFoundation.h:38:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CFBase.h:68:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/MacTypes.h:90:17: note: expanded from macro 'nil'
    #define nil NULL
                ^
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/Syntax.cpp:1:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/SpiritTest_Prefix.pch:6:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/../../../Cinder/include/cinder/Cinder.h:92:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/chrono:280:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/type_traits:203:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/cstddef:44:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/5.1/include/stddef.h:72:18: note: expanded from macro 'NULL'
#    define NULL __null
                 ^
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/Syntax.cpp:9:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/Syntax.h:12:
In file included from ../../../Cinder/boost/boost/spirit/include/qi.hpp:16:
In file included from ../../../Cinder/boost/boost/spirit/home/qi.hpp:14:
In file included from ../../../Cinder/boost/boost/spirit/home/qi/action.hpp:14:
In file included from ../../../Cinder/boost/boost/spirit/home/qi/action/action.hpp:14:
In file included from ../../../Cinder/boost/boost/spirit/home/qi/meta_compiler.hpp:14:
In file included from ../../../Cinder/boost/boost/spirit/home/support/meta_compiler.hpp:19:
In file included from ../../../Cinder/boost/boost/proto/proto.hpp:12:
In file included from ../../../Cinder/boost/boost/proto/core.hpp:21:
In file included from ../../../Cinder/boost/boost/proto/fusion.hpp:22:
In file included from ../../../Cinder/boost/boost/fusion/include/intrinsic.hpp:10:
In file included from ../../../Cinder/boost/boost/fusion/sequence/intrinsic.hpp:11:
In file included from ../../../Cinder/boost/boost/fusion/sequence/intrinsic/back.hpp:11:
In file included from ../../../Cinder/boost/boost/fusion/sequence/intrinsic/end.hpp:17:
In file included from ../../../Cinder/boost/boost/fusion/sequence/intrinsic/detail/segmented_end.hpp:11:
In file included from ../../../Cinder/boost/boost/fusion/iterator/segmented_iterator.hpp:10:
In file included from ../../../Cinder/boost/boost/fusion/iterator/detail/segmented_iterator.hpp:18:
../../../Cinder/boost/boost/fusion/iterator/detail/segmented_equal_to.hpp:16:5: error: declaration of anonymous struct must be a definition
    struct nil;
    ^
../../../Cinder/boost/boost/fusion/iterator/detail/segmented_equal_to.hpp:16:5: warning: declaration does not declare anything [-Wmissing-declarations]
    struct nil;
    ^~~~~~
../../../Cinder/boost/boost/fusion/iterator/detail/segmented_equal_to.hpp:35:43: error: expected unqualified-id
        struct segmented_equal_to<fusion::nil, fusion::nil>
                                          ^
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/Syntax.cpp:1:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/SpiritTest_Prefix.pch:8:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/../../../Cinder/include/cinder/app/AppBasic.h:27:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/../../../Cinder/include/cinder/app/App.h:27:
In file included from /Users/timmb/Documents/Programming/demos/SpiritTest/xcode/../../../Cinder/include/cinder/app/Renderer.h:32:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/ApplicationServices.framework/Headers/ApplicationServices.h:23:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/CoreServices.framework/Headers/CoreServices.h:19:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CoreFoundation.h:38:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CFBase.h:68:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/MacTypes.h:90:17: note: expanded from macro 'nil'
    #define nil NULL

谁能发现我做错了什么?

(顺便说一下,由于需要外部库,我使用的是 Boost 1.53。)

【问题讨论】:

  • 您显示的错误转储似乎表明您有一个邪恶的定义#define nil NULL,当包含在任何 boost 标头之前时,它将造成严重破坏。只是不要在 C++ 中为这些东西使用定义(具体来说,它看起来像是在 MacTypes.h 中。哦,好吧,谷歌会知道的)

标签: c++ parsing boost boost-spirit boost-spirit-qi


【解决方案1】:

你好像漏掉了一些

  • 包括(用于语义动作)

    #include <boost/spirit/include/phoenix.hpp>
    
  • 命名空间别名

    namespace ascii = boost::spirit::ascii;
    
  • 使用语句/限定符

        using qi::_val;
        using qi::_1;
        using qi::_2;
    

Live On Coliru

还要注意[_val = _1] 是多余的(自动属性传播实现相同)。

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

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

template <typename Iterator>
struct ExpressionGrammer : qi::grammar<Iterator, double(), ascii::space_type>
{
    qi::rule<Iterator, double(), ascii::space_type> expression;
    qi::rule<Iterator, double(), ascii::space_type> addsub;

    ExpressionGrammer()
    : ExpressionGrammer::base_type(expression)
    {
        using qi::lit;
        using qi::_val;
        using qi::_1;
        using qi::_2;

        addsub = (expression >> '+' >> expression)[_val = _1 + _2];     
        expression = (addsub | qi::double_)[_val = _1];
    }
};

int main()
{
    ExpressionGrammer<char*> g;
}

【讨论】:

  • 就是这样,您的评论还有一个附加要求:MacTypes.h 将 Nilnil 定义为 NULL,它位于“匿名结构声明必须是定义错误”,因为 Boost Fusion 有一个 struct nil;。尽管我的 cpp 文件不包含除 Boost 之外的任何头文件,但我正在使用的框架中的 Xcode 设置似乎自动包含 MacTypes.h。通过在 Boost 包含之前添加 #undef nil#undef Nil 来修复它。谢谢!
  • 显然我不会拼写“语法”。
  • 根据svn.boost.org/trac/boost/ticket/5010nil 结构的问题在 Boost 1.55 中得到修复。
  • 虽然这显然不是一个提升问题。让宏随机替换源文件中的标记是悲伤的秘诀。我很欣赏将这个实例用于流行库的提升,但实际上 lobobjc/MacTypes.h 应该是固定的(例如 windows.h 现在可以在不定义 minmax 的情况下使用)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-28
  • 2013-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-23
相关资源
最近更新 更多