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

私はスピリットの深さを完全には理解していなかったと言わざるを得ません。ただし、コンストラクターでqg_stringパーサーを宣言した場合、parseメソッドを呼び出すときにqg_stringパーサーは存在しません。私の知る限り、階層内のルールは依然として相互に依存しています。それらは「親」ルールにコピーされません。

于 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 ルールで参照される (つまり、コピーされない) だけです (私はスピリットの内部についてよく知らないので、引用しないでください)。ぶら下がっている参照が原因で、クラッシュが発生します。

おそらく動作させることができる copy() 関数が存在しますが、問題の明らかな解決策は、あなたが言ったように、構造体のルールになることです(ほとんどの精神の例でそれらがどのように機能するかを参照してください)。

(念のため、この例で copy() 関数の使用例を確認できますが、これはあなたの場合には必要ありません)。

于 2012-03-11T20:49:20.193 に答える