Reputation: 177
I'm trying to compile a very simple grammar using boost spirit, but now I get this compilation error and after spending like an hour trying to figure out the reason I hope someone from the community immediately sees what the problem is or could be. This is the source code 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");
}
}
The output of the compiler is this:
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 ==========
Line 51 is the closing ')' of the 3rd BOOST_FUSION_ADAPT_STRUCT() macro.
Upvotes: 2
Views: 970
Reputation: 16334
The problem is that boost::variant<viper::identifier,viper::identifier2>
contains a comma (,
) and as such is interpreted as 2 arguments by the preprocessor.
A workaround:
typedef boost::variant<viper::identifier,viper::identifier2> Variant;
BOOST_FUSION_ADAPT_STRUCT(
viper::function,
(Variant, func)
)
Some other workarounds are listed here.
Upvotes: 3