我试图使用提升精神编写一个非常简单的语法,但是现在我得到了这个编译错误,并花了一个小时试图找出原因我希望社区中的某个人立即看到问题是什么或者可能是。这是源代码Viper.h:
#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行是关闭&#39;)&#39;第3个BOOST_FUSION_ADAPT_STRUCT()宏。
答案 0 :(得分: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。