I am currentyl trying to separate my boost spirit x3 parser into different _def and .cpp files using BOOST_SPIRIT_DEFINE/DECLARE/INSTANTIATE
, but I keep getting a linking error.
HERE is my parser which is separated.
The linker error reads
<artificial>:(.text.startup+0xbb): undefined reference to `bool kyle::parser::impl::parse_rule<__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::spirit::x3::context<boost::spirit::x3::skipper_tag, boost::spirit::x3::char_class<boost::spirit::char_encoding::standard, boost::spirit::x3::space_tag> const, boost::spirit::x3::unused_type>, boost::spirit::x3::unused_type const>(boost::spirit::x3::rule<kyle::parser::impl::identifier_class, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, false>, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, boost::spirit::x3::context<boost::spirit::x3::skipper_tag, boost::spirit::x3::char_class<boost::spirit::char_encoding::standard, boost::spirit::x3::space_tag> const, boost::spirit::x3::unused_type> const&, boost::spirit::x3::unused_type const&)'
What am I doing wrong? How can I make my example work?
config.hpp:
#include <boost/spirit/home/x3.hpp>
namespace kyle{
namespace parser{
namespace x3 = boost::spirit::x3;
typedef std::string::const_iterator iterator_type;
typedef x3::phrase_parse_context<x3::ascii::space_type>::type context_type;
}
}
literals.cpp:
#include "literals_def.hpp"
#include "config.hpp"
#include <boost/spirit/home/x3.hpp>
namespace kyle {
namespace parser {
namespace impl {
BOOST_SPIRIT_INSTANTIATE(identifier_type, iterator_type, context_type);
}
}
}
literals_def.hpp:
#include <boost/spirit/home/x3.hpp>
#include "literals.hpp"
namespace kyle {
namespace parser {
namespace impl {
namespace x3 = boost::spirit::x3;
const identifier_type identifier = "identifier";
auto const identifier_def = x3::alpha >> *x3::alnum;
BOOST_SPIRIT_DEFINE(identifier)
}
impl::identifier_type identifier(){
return impl::identifier;
}
}
}
literals.hpp:
#include <boost/spirit/home/x3.hpp>
namespace kyle{
namespace parser{
namespace impl {
namespace x3 = boost::spirit::x3;
struct identifier_class;
typedef x3::rule<identifier_class, std::string> identifier_type;
BOOST_SPIRIT_DECLARE(identifier_type)
}
impl::identifier_type identifier();
}
}
main.cpp:
#include "literals.hpp"
#include <iostream>
template<typename Parser>
bool test(std::string str, Parser&& p, bool full_match = true)
{
auto in = str.begin();
auto end = str.end();
bool ret = boost::spirit::x3::phrase_parse(in, end, p, boost::spirit::x3::space);
ret &= (!full_match || (in == end));
return ret;
}
int main(){
auto b = test("fobar", kyle::parser::identifier());
std::cout << b << std::endl;
}
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…