【问题标题】:boost::spirit::qi and access violation exceptionboost::spirit::qi 和访问冲突异常
【发布时间】:2014-09-21 17:23:56
【问题描述】:

在下一个简单代码中,我收到“访问冲突”异常。为什么会发生?找不到原因。

#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。

【问题讨论】:

    标签: c++ parsing boost boost-spirit boost-spirit-qi


    【解决方案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),那么是时候查看补丁级别、库版本、架构、优化标志和所有这些爵士乐了。

    【讨论】:

    • 对不起,我的示例代码中的错误 - 它是从几个大代码部分中删除的。我再次创建清晰的项目并复制粘贴您的代码,一切正常。感谢帮助。我认为我的麻烦真的取决于标志。好的,让我搜索一下我这边引发的异常对项目有什么影响。
    • @AeroSun 或由于构建不一致而导致的未定义行为。可能需要完全重建
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    相关资源
    最近更新 更多