Subject: [Boost-bugs] [Boost C++ Libraries] #12016: x3::symbols moves result and therefore removes it from the symbol_parser itself
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2016-02-23 21:53:14
#12016: x3::symbols moves result and therefore removes it from the symbol_parser
itself
------------------------------+------------------------
Reporter: UsYer | Owner: djowel
Type: Bugs | Status: new
Milestone: To Be Determined | Component: spirit
Version: Boost 1.60.0 | Severity: Regression
Keywords: |
------------------------------+------------------------
So, I ran into strange behaviour with boost::spirit::x3 as supplied in
boost 1.59:
{{{
#!div
I defined a 'dynamic' symbol table via:
{{{#!c++
struct instructions : x3::symbols<OpCode> {
instructions()
{
name("instructions");
}
void set_instruction_set(const
std::unordered_map<std::string, OpCode>& instruction_set) {
for (const auto& var : instruction_set) {
add(var.first, var.second);
}
}
} instructions_parser;
}}}
}}}
{{{
#!div
''OpCode'' is defined as :
{{{#!c++
struct OpCode
{
std::string mnemonic;
std::vector<...> variants;// actual type in vector<> not
important.
};
}}}
}}}
now, with the symbol table embedded in the neccessary rules, when parsing
an input string like
{{{
#!div
{{{#!asm
mov r2 r1
mov r1 @80
}}}
}}}
the resulting ast only contains the first `mov` with its operands.
The second mov is missing but the operands are correctly parsed.
This may look as followed, when printing the resulting AST:
{{{
#!div
{{{#!asm
mov r2 r1
r1 @80
}}}
}}}
{{{
#!div
With the debugger I located the source of the error in symbols.hpp in
''symbol_parser::parse()'':
{{{#!c++:
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute& attr) const
{
x3::skip_over(first, last, context);
if (value_type* val_ptr
= lookup->find(first, last,
get_case_compare<Encoding>(context)))
{
x3::traits::move_to(*val_ptr, attr); //<- the error
originates from here
return true;
}
return false;
}
}}}
}}}
{{{
#!div
with ''move_to'' beeing:
{{{#!c++:
template <typename T>
inline void move_to(T& src, T& dest)
{
if (boost::addressof(src) != boost::addressof(dest))
dest = std::move(src);
}
}}}
}}}
As you can see, the ''src'' which is my OpCode instance added in the
symbol_parser is moved. This means after the first call its empty again
and that's why only the first instructions appears. It's, simply put,
moved out of the symbol table.
[http://melpon.org/wandbox/permlink/XxPCnmWExNkmsmP2 '''Live example
(shows the bug is also present in 1.60)''']
provided by cv_and_he @stackoverflow
'''Temporary Workaround:'''
By declaring the template parameter as const one can suppress move
semantics. The copy-ctor is then called.
{{{
#!div
I.E.:
{{{#!c++:
x3::symbols<const OpCode>
}}}
}}}
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/12016> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:19 UTC