2016-01-24 24 views
2

我想用boost精神编译一个非常简单的语法,但现在我得到这个编译错误,花了一个小时后,试图找出原因,希望有人从社区立即看到问题是或可能是什么。这是源代码Viper.h:宏'BOOST_FUSION_ADAPT_STRUCT_FILLER_0'的实际参数太多

#pragma once 

#include <string> 
#include <vector> 

#define BOOST_SPIRIT_UNICODE 
#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/phoenix_core.hpp> 
#include <boost/fusion/adapted/boost_tuple.hpp> 

namespace nsunic = boost::spirit::unicode; 
namespace nsqi = boost::spirit::qi; 


namespace viper 
{ 

    struct identifier 
    { 
     std::wstring name; 
    }; 

    struct identifier2 
    { 
     std::wstring name; 
    }; 

    struct function 
    { 
     boost::variant<identifier, identifier2> func; 
    }; 

    struct program 
    { 
     std::vector<function> functions; 
    }; 
} 
BOOST_FUSION_ADAPT_STRUCT(
    viper::identifier, 
    (std::wstring, name) 
) 

BOOST_FUSION_ADAPT_STRUCT(
    viper::identifier2, 
    (std::wstring, name) 
) 

BOOST_FUSION_ADAPT_STRUCT(
    viper::function, 
    (boost::variant<viper::identifier,viper::identifier2>, func) 
) 

BOOST_FUSION_ADAPT_STRUCT(
    viper::program, 
    (std::vector<viper::function>, functions) 
) 

namespace viper 
{ 

    template<typename Iterator> struct function_parser : nsqi::grammar<Iterator, program(), nsqi::space_type> 
    { 
     function_parser() : function_parser::base_type(program) 
     { 
      identifier %= 
       nsqi::eps 
       >> (char_('a') > *(nsqi::alnum | nsqi::char_('_'))); 

      identifier2 %= 
       nsqi::eps 
       >> (char_('b') > *(nsqi::alnum | nsqi::char_('_'))); 

      function %= 
       identifier | identifier2; 

      program %= 
       nsqi::eps 
       >> +function; 
     } 

     nsqi::rule<Iterator, identifier()> identifier; 
     nsqi::rule<Iterator, identifier2()> identifier2; 
     nsqi::rule<Iterator, function(), nsqi::space_type> function; 
     nsqi::rule<Iterator, program(), nsqi::space_type> program; 
    }; 

    std::wstring render(const program& f) 
    { 
     std::wostringstream s; 

     const auto functions_count = f.functions.size(); 
     for(auto j=0; j<functions_count; ++j) 
     { 
      if(j>0) 
      { 
       s << L","; 
      } 
      s << f.functions[j].name; 
     } 
     return s.str(); 
    } 

    template<typename Iterator> std::wstring parse(Iterator first, Iterator last) 
    { 
     using nsqi::phrase_parse; 

     program f; 
     function_parser<Iterator> fp; 

     auto b = phrase_parse(first, last, fp, nsqi::space, f); 
     if(b) 
     { 
      return render(f); 
     } 
     return std::wstring(L"FAIL"); 
    } 

} 

编译器的输出是这样的:

1>------ Build started: Project: Viper.Notepad, Configuration: Debug Win32 ------ 
1>Build started 24-Jan-16 17:40:29. 
1>InitializeBuildStatus: 
1> Touching "Debug\Viper.Notepad.unsuccessfulbuild". 
1>ClCompile: 
1> All outputs are up-to-date. 
1> Viper.Notepad.cpp 
1>c:\users\srzmtl\local_copies\visual studio\visual studio 2010\viper\viper\viper.h(51): warning C4002: too many actual parameters for macro 'BOOST_FUSION_ADAPT_STRUCT_FILLER_0' 
1>c:\users\srzmtl\local_copies\visual studio\visual studio 2010\viper\viper\viper.h(51): error C2146: syntax error : missing ',' before identifier 'attribute_type' 
1>c:\users\srzmtl\local_copies\visual studio\visual studio 2010\viper\viper\viper.h(51): error C2065: 'attribute_type' : undeclared identifier 
1>c:\users\srzmtl\local_copies\visual studio\visual studio 2010\viper\viper\viper.h(51): error C2143: syntax error : missing '>' before ';' 
1>c:\users\srzmtl\local_copies\visual studio\visual studio 2010\viper\viper\viper.h(51): error C2208: 'boost::variant' : no members defined using this type 
1>c:\users\srzmtl\local_copies\visual studio\visual studio 2010\viper\viper\viper.h(51): fatal error C1903: unable to recover from previous error(s); stopping compilation 
1> 
1>Build FAILED. 
1> 
1>Time Elapsed 00:00:23.25 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

51行是第三BOOST_FUSION_ADAPT_STRUCT()宏的关闭 ')'。

回答

3

问题是boost::variant<viper::identifier,viper::identifier2>包含逗号(,),因此预处理器将其解释为2个参数。

一种解决方法:

typedef boost::variant<viper::identifier,viper::identifier2> Variant; 
BOOST_FUSION_ADAPT_STRUCT(
    viper::function, 
    (Variant, func) 
) 

一些其他方法列出here

+0

感谢您的回复!不幸的是,你的建议导致编译器错误信息: '1> c:\ users \ srzmtl \ local_copies \ visual studio \ visual studio 2010 \ viper \ viper \ viper.h(48):error C2143:syntax error:missing'; “ '=' 1> c:\ users \ srzmtl \ local_copies \ visual studio \ visual studio 2010 \ viper \ viper \ viper.h(48):error C2873:'Variant':符号不能在使用声明中使用 1> c:\ users \ srzmtl \ local_copies \ visual studio \ visual studio 2010 \ viper \ viper \ viper.h(48):error C2513:'int':'='前没有声明变量 48行使用声明在哪里。 – Sakuragaoka

+0

@Sakuragaoka使用typedef而不是如果您的编译器不支持使用,我更新了上述代码 –

+0

typedef工作。谢谢! – Sakuragaoka