3

私の状況:私はSpiritを初めて使用します。VC6を使用する必要があるため、Spirit1.6.4を使用しています。

私はこのような行を持っています:

//The Description;DESCRIPTION;;

DESCRIPTION行が。で始まる場合は、テキストを文字列に入れたいです//The Description;

私にはうまくいくものがありますが、私にはそれほどエレガントに見えません:

vector<char> vDescription; // std::string doesn't work due to missing ::clear() in VC6's STL implementation
if(parse(chars,
    // Begin grammar
    (
       as_lower_d["//the description;"]
    >> (+~ch_p(';'))[assign(vDescription)]
    ),
    // End grammar
    space_p).hit)
{
    const string desc(vDescription.begin(), vDescription.end());
}

印刷可能なすべての文字を次の文字に割り当てたいのです';'が、次の理由で機能しません。parse(...).hit == false

parse(chars,
        // Begin grammar
        (
           as_lower_d["//the description;"]
        >> (+print_p)[assign(vDescription)]
        >> ';'
        ),
        // End grammar
        space_p).hit)

どうすればヒットさせることができますか?

4

2 に答える 2

3

以下を使用してみてくださいconfix_p:

confix_p(as_lower_d["//the description;"],
         (+print_p)[assign(vDescription)],
         ch_p(';')
        )

Fred の応答と同等のはずです。

あなたのコードが失敗する理由print_pは、貪欲だからです。パーサーは、入力の終わりまたは印刷できない文字に遭遇するまで、+print_p文字を消費します。セミコロンは印刷可能であるため、それをprint_p主張します。入力が使い果たされ、変数が割り当てられ、一致が失敗します — パーサーの最後のセミコロンに一致するものは何も残っていません。

フレッドの答えは、セミコロンを除く(print_p - ';')すべてのものに一致する新しいパーサーを構築します。「 Xprint_p以外のすべてに一致し、次に X に一致する」は一般的なパターンであるため、そのようなパーサーを構築するためのショートカットとして提供されています。ドキュメントでは、C または Pascal スタイルのコメントの解析に使用することが推奨されていますが、必須ではありません。confix_p

print_pあなたのコードが機能するためには、Spirit は貪欲な一致が多すぎることを認識し、バックトラックして一致を少なくする必要があります。しかし、Spirit はバックトラックしますが、サブパーサーが貪欲に一致するものの「中間」にはバックトラックしません。次の「選択ポイント」に戻りますが、文法には何もありません。Spirit ドキュメンテーションのExhaustive backtracking と greedy RDを参照してください。

于 2009-01-21T22:43:25.310 に答える
3

「;」のため、ヒットしていません print_p と一致します。これを試して:

parse(chars,
    // Begin grammar
    (
       as_lower_d["//the description;"]
    >> (+(print_p-';'))[assign(vDescription)]
    >> ';'
    ),
    // End grammar
    space_p).hit)
于 2009-01-21T22:30:05.320 に答える