Оператор присваивания правила Boost Spirit - PullRequest
1 голос
/ 01 марта 2012

Я впервые задаю вопрос здесь. Мне уже потребовалось много времени и исследований, чтобы заставить это работать, и я не могу. Я действительно надеюсь, что вы можете помочь мне с этим. Я новичок, использующий Дух, я не полностью понимаю все термины; однако даже после прочтения множества статей и постов я не знаю, что мне не хватает.

Итак, у меня есть следующая структура и класс в заголовочном файле.

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 утра).

Ответы [ 2 ]

2 голосов
/ 01 марта 2012

Должен сказать, я не до конца понимал глубину Духа. Но если вы объявите свой синтаксический анализатор qg_string в конструкторе, он не будет существовать при вызове метода parse. Насколько я знаю, правила в иерархии все еще зависят друг от друга. Они не копируются в «родительское» правило.

1 голос
/ 12 марта 2012

Как сказал Smittii, проблема в том, что правило больше не существует при вызове parse, потому что оно объявлено локально в конструкторе (что будет выполнено при вызове parse). Тот, что в комментарии, все еще существует для всего анализа, так что он работает.

В основном проблема в том, что когда вы пишете:

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

qg_string является своего рода (я не знаю духовных внутренних органов, поэтому не цитируйте меня об этом), на которое ссылаются (т.е. не копируют) только в правиле rules_.create_char, поэтому, когда правило qg_string уничтожается при выходе конструктор, он оставляет висящую ссылку на него, что приводит к аварийному завершению.

Существует функция copy (), которую вы, вероятно, могли бы заставить работать, но для вашей проблемы очевидным решением было бы стать правилом в вашей структуре, как вы и сказали (посмотрите, как они это делают в большинстве духовных примеров).

(На всякий случай вы можете проверить в этом примере для примера использования функции copy (), но это не обязательно для вашего случая).

...