Boost Spirit Symbol 抛出访问冲突
Boost Spirit Symbol throws access violation
您好,我是 Boost Spirit 的新手,我在使用 qi::symbol 对象时遇到了问题。
#include <iostream>
#include <vector>
#define BOOST_SPIRIT_DEBUG
#define BOOST_SPIRIT_DEBUG_OUT std::cerr
#include <boost/config/warning_disable.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_symbols.hpp>
#include <boost/spirit/include/qi_nonterminal.hpp>
struct Thing
{
Thing() = default;
Thing(std::string s, std::string t)
:
one(s),
two(t)
{
}
std::string one;
std::string two;
};
BOOST_FUSION_ADAPT_STRUCT(
Thing,
(std::string, one)
(std::string, two)
)
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
namespace ascii = boost::spirit::ascii;
template <typename Iterator>
struct parse_things : qi::grammar<Iterator, Thing(), ascii::space_type>
{
parse_things() : parse_things::base_type(keyword)
{
qi::symbols<char, Thing> keywords;
keywords.add
("One", Thing("ThingOne","ThingTwo"))
("Two", Thing("ThingTwo","ThingOne"));
keyword %= keywords;
BOOST_SPIRIT_DEBUG_NODE(keyword);
}
qi::rule<Iterator, Thing(), ascii::space_type> keyword;
};
int main(int argc, const char *argv[])
{
Thing t;
std::string s("One");
std::string s2("Two");
parse_things<std::string::const_iterator> parser;
bool r = qi::phrase_parse(
std::cbegin(s),
std::cend(s),
parser,
ascii::space,
t);
assert(r == true);
assert(t.one == "ThingOne");
assert(t.two == "ThingTwo");
assert(t.two == "ThingOne");
assert(t.one == "ThingTwo");
return 0;
}
这在 Visual Studio 2014 Update 4 上为我编译,但在解析时抛出访问冲突。我做错了什么?
你应该
qi::symbols<char, Thing> keywords;
结构的成员,而不是构造函数中的临时局部变量。您的解析器将对 symbols
对象中的 trie 数据结构有陈旧的引用。
带有更多测试的稍微简化的程序:
//#define BOOST_SPIRIT_DEBUG
#define BOOST_SPIRIT_DEBUG_OUT std::cerr
#include <boost/fusion/adapted/struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_symbols.hpp>
#include <iostream>
#include <vector>
struct Thing
{
std::string one;
std::string two;
};
BOOST_FUSION_ADAPT_STRUCT(
Thing,
(std::string, one)
(std::string, two)
)
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
namespace ascii = boost::spirit::ascii;
template <typename Iterator>
struct parse_things : qi::grammar<Iterator, Thing(), ascii::space_type>
{
parse_things() : parse_things::base_type(keyword)
{
keywords.add
("One", Thing{"ThingOne","ThingTwo"})
("Two", Thing{"ThingTwo","ThingOne"});
keyword %= keywords;
BOOST_SPIRIT_DEBUG_NODE(keyword);
}
qi::symbols<char, Thing> keywords;
qi::rule<Iterator, Thing(), ascii::space_type> keyword;
};
int main()
{
const parse_things<std::string::const_iterator> parser;
for (std::string const s : { "One", "Two", "Three" })
{
auto f = begin(s), l = end(s);
Thing data;
bool ok = qi::phrase_parse(f,l,parser,ascii::space,data);
std::cout << s << ": " << std::boolalpha << ok << ", " << boost::fusion::as_vector(data) << '\n';
if (f != l)
std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
}
}
版画
One: true, (ThingOne ThingTwo)
Two: true, (ThingTwo ThingOne)
Three: false, ( )
Remaining unparsed: 'Three'
您好,我是 Boost Spirit 的新手,我在使用 qi::symbol 对象时遇到了问题。
#include <iostream>
#include <vector>
#define BOOST_SPIRIT_DEBUG
#define BOOST_SPIRIT_DEBUG_OUT std::cerr
#include <boost/config/warning_disable.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_symbols.hpp>
#include <boost/spirit/include/qi_nonterminal.hpp>
struct Thing
{
Thing() = default;
Thing(std::string s, std::string t)
:
one(s),
two(t)
{
}
std::string one;
std::string two;
};
BOOST_FUSION_ADAPT_STRUCT(
Thing,
(std::string, one)
(std::string, two)
)
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
namespace ascii = boost::spirit::ascii;
template <typename Iterator>
struct parse_things : qi::grammar<Iterator, Thing(), ascii::space_type>
{
parse_things() : parse_things::base_type(keyword)
{
qi::symbols<char, Thing> keywords;
keywords.add
("One", Thing("ThingOne","ThingTwo"))
("Two", Thing("ThingTwo","ThingOne"));
keyword %= keywords;
BOOST_SPIRIT_DEBUG_NODE(keyword);
}
qi::rule<Iterator, Thing(), ascii::space_type> keyword;
};
int main(int argc, const char *argv[])
{
Thing t;
std::string s("One");
std::string s2("Two");
parse_things<std::string::const_iterator> parser;
bool r = qi::phrase_parse(
std::cbegin(s),
std::cend(s),
parser,
ascii::space,
t);
assert(r == true);
assert(t.one == "ThingOne");
assert(t.two == "ThingTwo");
assert(t.two == "ThingOne");
assert(t.one == "ThingTwo");
return 0;
}
这在 Visual Studio 2014 Update 4 上为我编译,但在解析时抛出访问冲突。我做错了什么?
你应该
qi::symbols<char, Thing> keywords;
结构的成员,而不是构造函数中的临时局部变量。您的解析器将对 symbols
对象中的 trie 数据结构有陈旧的引用。
带有更多测试的稍微简化的程序:
//#define BOOST_SPIRIT_DEBUG
#define BOOST_SPIRIT_DEBUG_OUT std::cerr
#include <boost/fusion/adapted/struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_symbols.hpp>
#include <iostream>
#include <vector>
struct Thing
{
std::string one;
std::string two;
};
BOOST_FUSION_ADAPT_STRUCT(
Thing,
(std::string, one)
(std::string, two)
)
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
namespace ascii = boost::spirit::ascii;
template <typename Iterator>
struct parse_things : qi::grammar<Iterator, Thing(), ascii::space_type>
{
parse_things() : parse_things::base_type(keyword)
{
keywords.add
("One", Thing{"ThingOne","ThingTwo"})
("Two", Thing{"ThingTwo","ThingOne"});
keyword %= keywords;
BOOST_SPIRIT_DEBUG_NODE(keyword);
}
qi::symbols<char, Thing> keywords;
qi::rule<Iterator, Thing(), ascii::space_type> keyword;
};
int main()
{
const parse_things<std::string::const_iterator> parser;
for (std::string const s : { "One", "Two", "Three" })
{
auto f = begin(s), l = end(s);
Thing data;
bool ok = qi::phrase_parse(f,l,parser,ascii::space,data);
std::cout << s << ": " << std::boolalpha << ok << ", " << boost::fusion::as_vector(data) << '\n';
if (f != l)
std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
}
}
版画
One: true, (ThingOne ThingTwo)
Two: true, (ThingTwo ThingOne)
Three: false, ( )
Remaining unparsed: 'Three'