Sakuragaoka
Sakuragaoka

Reputation: 177

too many actual parameters for macro 'BOOST_FUSION_ADAPT_STRUCT_FILLER_0'

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

Answers (1)

m.s.
m.s.

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

Related Questions