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;
}