在下一个简单代码中我收到“访问冲突”异常。为什么会这样?我无法理解。
#define BOOST_SPIRIT_DEBUG
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
typedef boost::spirit::ascii::space_type TSkipper;
struct MyField
{
bool isConst;
std::string mtype;
std::string name;
};
BOOST_FUSION_ADAPT_STRUCT
(
MyField,
(bool, isConst)
(std::string, mtype)
(std::string, name)
)
template<typename Iterator, typename TSkipper = boost::spirit::ascii::space_type>
struct field_grammar : qi::grammar < Iterator, Field(), TSkipper >
{
field_grammar() : field_grammar::base_type(field, "field_grammar")
{
// must parse values such as: int, list, i, j9_
valid_symbols %= lexeme[qi::char_("a-zA-Z") > *(qi::char_("a-zA-Z0-9_"))];
valid_symbols.name("valid_symbols");
field %= qi::matches["const"] >> valid_symbols >> valid_symbols;
field.name("field");
BOOST_SPIRIT_DEBUG_NODES((valid_symbols)(field));
}
boost::spirit::qi::rule<Iterator, std::string(), TSkipper> valid_symbols;
boost::spirit::qi::rule<Iterator, Field(), TSkipper> field;
};
我在下一个方面使用这个语法:
void SpiritTestSimple()
{
std::string mdata = "int destroyWindow";
std::string::const_iterator first = mdata.begin(), last = mdata.end();
field_grammar<std::string::const_iterator> test_grammar;
Field parsed;
bool is_parsed;
try
{
is_parsed = qi::phrase_parse(first, last, test_grammar,
boost::spirit::ascii::space, parsed);
}
catch (const qi::expectation_failure<std::string::const_iterator>& e)
{
std::string frag(e.first, e.last);
std::cout << e.what() << "'" << frag << "'" << std::endl;
}
BOOST_ASSERT(is_parsed && "the example not parsed");
}
执行“qi :: phrase_parse”函数时收到异常。 为什么会这样?以及如何解决它? 我用的是msvs2013。
答案 0 :(得分:1)
我也使用VS2013。它运作正常,除了长镜头外,我看不出它有多大错:
qi::lexeme
(与我一起导致编译错误)Field
引用可能需要MyField
(这也会导致编译错误)is_parsed
可能在ASSERT宏中未初始化。您可以尝试以下版本: Live On Coliru
#define BOOST_SPIRIT_DEBUG
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
struct MyField
{
bool isConst = false;
std::string mtype = "";
std::string name = "";
friend std::ostream& operator<<(std::ostream& os, MyField const& mf)
{
return os << "MyField["
<< "isConst:" << std::boolalpha << mf.isConst
<< "\nmtype:" << mf.mtype
<< "\nname: " << mf.name << "]";
}
};
BOOST_FUSION_ADAPT_STRUCT
(
MyField,
(bool, isConst)
(std::string, mtype)
(std::string, name)
)
template<typename Iterator, typename TSkipper = boost::spirit::ascii::space_type>
struct field_grammar : qi::grammar <Iterator, MyField(), TSkipper>
{
field_grammar() : field_grammar::base_type(field, "field_grammar")
{
// must parse values such as: int, list, i, j9_
valid_symbols = qi::char_("a-zA-Z") >> *(qi::char_("a-zA-Z0-9_"));
field = qi::matches["const"] >> valid_symbols >> valid_symbols;
BOOST_SPIRIT_DEBUG_NODES((valid_symbols)(field));
}
boost::spirit::qi::rule<Iterator, std::string()> valid_symbols;
boost::spirit::qi::rule<Iterator, MyField(), TSkipper> field;
};
void SpiritTestSimple()
{
std::string const mdata = "int destroyWindow";
std::string::const_iterator first = mdata.begin(), last = mdata.end();
field_grammar<std::string::const_iterator> test_grammar;
try
{
MyField parsed;
if (qi::phrase_parse(first, last, test_grammar,
boost::spirit::ascii::space, parsed))
{
std::cout << "Parsed: " << parsed << "\n";
} else
{
std::cout << "Failed to parse '" << std::string(first, last) << "'\n";
}
}
catch (const qi::expectation_failure<std::string::const_iterator>& e)
{
std::string frag(e.first, e.last);
std::cout << e.what() << "'" << frag << "'" << std::endl;
}
}
int main()
{
SpiritTestSimple();
}
如果那不是WorksForYou(TM),那么就该看看补丁级别,库版本,架构,优化标志和所有爵士乐。