1

这是我第一次在这里提问。我已经花了很多时间和研究来完成这项工作,但我做不到。我真的希望你能帮助我。我是使用 Spirit 的新手,我不完全理解所有术语;然而,即使在阅读了大量文章和帖子之后,我也不知道我错过了什么。

所以,我在头文件中有以下结构和类。

typedef std::string::const_iterator iterator_type;
struct GrammarRules
{
    qi::rule<iterator_type, ascii::space_type> create_char;
};

class Parser
{
    public:
        Parser();
        bool parse(std::string const& to_parse);

    private:
        GrammarRules rules_;
        gtor::World * world_;
};

然后我在 .cpp 文件中有以下内容:

Parser::Parser()
    : rules_()
    , world_(nullptr)
{
    world_ = new gtor::World();

    qi::rule<iterator_type, std::string(), ascii::space_type> qg_string;
    qg_string %= qi::lexeme[ +(ascii::alnum) ];

    rules_.create_char =
        (
            qi::lit("CreateChar")
            >> '('
            >> qg_string >> ','
            >> qg_string >> ','
            >> qi::int_
            >> ')'
        )
        [
            phx::bind(&gtor::World::createCharacter, world_, qi::_1, qi::_2, qi::_3)
        ]
        ;
}

...

bool Parser::parse(std::string const& to_parse)
{
    iterator_type it  = to_parse.begin();
    iterator_type end = to_parse.end();
    bool success = qi::phrase_parse(it, end, rules_.create_char, ascii::space);

    /*qi::rule<iterator_type, std::string(), ascii::space_type> qg_string;
        qg_string %= qi::lexeme[ +(ascii::alnum) ];

    qi::rule<iterator_type, ascii::space_type> create_char1 =
        (
            qi::lit("CreateChar")
            >> '('
            >> qg_string >> ','
            >> qg_string >> ','
            >> qi::int_
            >> ')'
        )
        [
            phx::bind(&gtor::World::createCharacter, world_, qi::_1, qi::_2, qi::_3)
        ]
        ;
    bool success = qi::phrase_parse(it, end, create_char1, ascii::space);*/

    if (success && it == end)
        return true;

    return false;
}

没有在方法上注释的代码parse()不起作用,Access Violation只要解析器到达qg_string规则,我就会得到一个。但是,注释的代码可以完美运行。除了明显的差异外,它对我来说看起来完全一样。也许我错过了一些非常明显的东西,但我找不到它。

如果我将所有内容都用作局部变量,我已经花了很多时间才发现我的代码可以工作。而且还是找不到问题。

预先感谢您的任何帮助。抱歉,如果帖子中有任何错误(凌晨 5 点)。

4

2 回答 2

2

I have to say, I didn't fully understand the depth of Spirit. But if you declare your qg_string parser in the constructor it does not exist when you call the parse method. As far as I know the rules in a hierarchy still depend on each other. They are not copied into the "parent" rule.

于 2012-03-01T13:41:03.167 回答
1

就像 Smittii 所说的,问题在于调用 parse 时规则不再存在,因为它是在构造函数中本地声明的(将在调用 parse 时执行)。整个解析中仍然存在评论中的那个,因此它可以工作。

基本上问题是当你写:

rules_.create_char =
        (
            qi::lit("CreateChar")
            >> '('
            >> qg_string >> ','
            >> qg_string >> ','
            >> qi::int_
            >> ')'
        )

qg_string 有点(我真的不知道精神内部,所以不要引用我的话)只在 rules_.create_char 规则中引用(即不复制),所以当离开构造函数时 qg_string 规则被破坏时它离开悬空引用它,导致您遇到崩溃。

存在一个 copy() 函数,您可能可以使其工作,但对于您的问题,显而易见的解决方案是成为您的结构中的规则,就像您说的那样(看看他们在大多数精神示例中是如何做的)。

(以防万一,您可以查看此示例以获取使用 copy() 函数的示例,但这对于您的情况不是必需的)。

于 2012-03-11T20:49:20.193 回答