X3: declare/define/instantiate linker error

Tore Halvorsen <[email protected]>
Newsgroups gmane.comp.parsers.spirit.general
Message-ID <CADGw-SejxtvLAgGSRnFxU_iN4Wx2k0319XFvzeYqBtkp6Y2=bg@mail.gmail.com>
Hi,

I tried to make a rather large X3 parser and got into problems with
compiler heap space. I figured that I could break the parser into different
pieces with declare/define/instantiate, but I get a linking error.

The problem only exists when foo_def = a() >> x3::lit(":") >> b();
If this is changed to foo_def = a() >> b(); the linking issue disappears.

So, is my basic approach sound? In the larger project I have several fusion
structs that is build up using more fusion structs.

Is there another way to split parsers into different parts?

I'm using visual studio vs14_1 and boost 1_64, and this is the smallest
version where I managed to reproduce the problem.

The abbrivated linking error is:
Error    LNK2019    unresolved external symbol "bool __cdecl
field::parse_rule<class std::_String_const_iterator<class
std::_String_val<struct std::_Simple_types<char> > >,struct
boost::spirit::x3::unused_type,struct boost::fusion::iterator_range<struct
boost::fusion::basic_iterator<struct
boost::fusion::struct_iterator_tag,struct
boost::fusion::random_access_traversal_tag,struct s::foo,0>,struct
boost::fusion::basic_iterator<struct
boost::fusion::struct_iterator_tag,struct
boost::fusion::random_access_traversal_tag,struct s::foo,1> > >

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot

_______________________________________________
Spirit-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-general
group.cpp (text/plain, 214 B)
#include "group_def.h"

namespace group
{
	namespace x3 = boost::spirit::x3;
	typedef std::string::const_iterator iterator_type;

	BOOST_SPIRIT_INSTANTIATE(foo_type, iterator_type, x3::unused_type);
}
group.h (text/plain, 362 B)
#pragma once

#ifndef GROUP_H_INCLUDED
#define GROUP_H_INCLUDED

#include <boost/spirit/home/x3.hpp>
#include "struct.h"

namespace group
{
	namespace x3 = boost::spirit::x3;

	struct foo_class;

	typedef x3::rule<foo_class, s::foo> foo_type;

	BOOST_SPIRIT_DECLARE(foo_type);
}

group::foo_type const& foo();

#endif // GROUP_H_INCLUDED
field.cpp (text/plain, 280 B)
#include "field_def.h"

namespace field
{
	namespace x3 = boost::spirit::x3;

	typedef std::string::const_iterator iterator_type;

	BOOST_SPIRIT_INSTANTIATE(a_type, iterator_type, x3::unused_type);
	BOOST_SPIRIT_INSTANTIATE(b_type, iterator_type, x3::unused_type);
}
field.h (text/plain, 435 B)
#pragma once

#ifndef FIELD_H_INCLUDED
#define FIELD_H_INCLUDED

#include <boost/spirit/home/x3.hpp>

namespace field
{
	namespace x3 = boost::spirit::x3;

	struct a_class;
	struct b_class;

	typedef x3::rule<a_class, char> a_type;
	typedef x3::rule<b_class, std::vector<char>> b_type;

	BOOST_SPIRIT_DECLARE(a_type, b_type);
}

field::a_type const& a();
field::b_type const& b();

#endif // FIELD_H_INCLUDED
field_def.h (text/plain, 603 B)
#pragma once

#ifndef FIELD_DEF_H_INCLUDED
#define FIELD_DEF_H_INCLUDED

#include <boost/spirit/home/x3.hpp>

namespace field
{
	namespace x3 = boost::spirit::x3;

	struct a_class;
	struct b_class;

	typedef x3::rule<a_class, char> a_type;
	typedef x3::rule<b_class, std::vector<char>> b_type;

	a_type const a = "a";
	b_type const b = "b";

	auto const a_def = x3::char_;
	auto const b_def = +x3::char_;

	BOOST_SPIRIT_DEFINE(a, b);
}

field::a_type const& a()
{
	return field::a;
}

field::b_type const& b()
{
	return field::b;
}

#endif // FIELD_DEF_H_INCLUDED
group_def.h (text/plain, 499 B)
#pragma once

#ifndef GROUP_DEF_H_INCLUDED
#define GROUP_DEF_H_INCLUDED

#include <boost/spirit/home/x3.hpp>
#include "struct.h"
#include "field.h"

namespace group
{
	namespace x3 = boost::spirit::x3;

	struct foo_class;

	typedef x3::rule<foo_class, s::foo> foo_type;

	foo_type const foo = "foo";

	auto const foo_def = a() >> x3::lit(":") >> b();

	BOOST_SPIRIT_DEFINE(foo);
}

group::foo_type const& foo()
{
	return group::foo;
}

#endif // GROUP_DEF_H_INCLUDED
struct.h (text/plain, 333 B)
#pragma once

#ifndef STRUCT_H_INCLUDED
#define STRUCT_H_INCLUDED

#include <boost/fusion/include/adapt_struct.hpp>
#include <vector>

namespace s
{
	
struct foo
{
	char a; 
	std::vector<char> b;
};

}

BOOST_FUSION_ADAPT_STRUCT(
	s::foo,
	(char, a)
	(std::vector<char>, b)
)


#endif // STRUCT_H_INCLUDED
main.cpp (text/plain, 176 B)
#include "group.h"

int main(int argc, char* argv[])
{
	std::string s("1:ABC");
	s::foo f;
	auto ok = parse(s.cbegin(), s.cend(), foo(), f);

	return EXIT_SUCCESS;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.