スピリットを使用してこれを正しく解析するにはどうすればよいですか?
-
19-08-2019 - |
質問
私の状況:私はSpiritが初めてなので、VC6を使用する必要があるため、Spirit 1.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)
どうやってヒットさせるのですか?
解決
confix_p(as_lower_d["//the description;"],
(+print_p)[assign(vDescription)],
ch_p(';')
)
Fredの応答と同等でなければなりません。
コードが失敗する理由は、print_p
が貪欲であるためです。 +print_p
パーサーは、入力の終わりまたは印刷できない文字が見つかるまで文字を消費します。セミコロンは印刷可能であるため、(print_p - ';')
が主張しています。入力が使い果たされ、変数が割り当てられ、一致が失敗します<!>#8212;パーサーの最後のセミコロンに一致するものは何もありません。
Fredの答えは、新しいパーサー<=>を構築します。これは、セミコロンを除き、<=>が行うすべてに一致します。 <!> quot; X 以外のすべてを照合してから、 X <!> quot;に一致は一般的なパターンであるため、そのようなパーサーを構築するためのショートカットとして<=>が提供されます。ドキュメントでは、CまたはPascalスタイルのコメントの解析に使用することを推奨していますが、必須ではありません。
コードが機能するためには、Spiritは貪欲な<=>の一致が多すぎることを認識してから、一致を少なくするにはバックトラックする必要があります。しかし、Spiritはバックトラックしますが、<!> quot; middle <!> quot;にはバックトラックしません。サブパーサーがそれ以外の場合は貪欲に一致するものの。次の<!> quot; choice point、<!> quot;に戻ります。しかし、あなたの文法には何もありません。 徹底的なバックトラッキングと欲張りSpiritドキュメントのRD 。
他のヒント
「;」が原因でヒットしないprint_pと一致します。これを試してください:
parse(chars,
// Begin grammar
(
as_lower_d["//the description;"]
>> (+(print_p-';'))[assign(vDescription)]
>> ';'
),
// End grammar
space_p).hit)