この簡単なブーストの問題は何ですか::スピリット:: QIパーサー?
-
01-10-2019 - |
質問
VBスタイルの二重引用文字列を解析することを目的としたこのシンプルなパーサーがあります。したがって、パーサーは次のようなものを回す必要があります
"This is a quoted string containing quotes ("" "")"
の出力に
This is a quoted string containing quotes (" ")
これが私がこれのために思いついた文法です:
namespace qi = boost::spirit::qi;
namespace wide = qi::standard_wide;
class ConfigurationParser : public qi::grammar<std::wstring::iterator, std::wstring()>
{
qi::rule<std::wstring::iterator, std::wstring()> quotedString;
qi::rule<std::wstring::iterator> doubleQuote;
public:
ConfigurationParser() : ConfigurationParser::base_type(quotedString, "vFind Command Line")
{
doubleQuote = (wide::char_(L'"') >> wide::char_(L'"'));
quotedString = L'"' >> +(doubleQuote[qi::_val = L'"'] | (wide::char_ - L'"'))>> L'"';
}
};
ただし、私が得ている属性は、完全な解析メッセージではなく、単一の引用マーク( ")です。
解決
セマンティックアクションなしでそれを行うことができます:
class ConfigurationParser
: public qi::grammar<std::wstring::iterator, std::wstring()>
{
qi::rule<std::wstring::iterator, std::wstring()> quotedString;
qi::rule<std::wstring::iterator, wchar_t()> doubleQuote;
public:
ConfigurationParser()
: ConfigurationParser::base_type(quotedString, "vFind Command Line")
{
doubleQuote = wide::char_(L'"') >> omit[wide::char_(L'"')];
quotedString = L'"' >> +(doubleQuote | (wide::char_ - L'"')) >> L'"';
}
};
omit[]
ディレクティブはまだ組み込みパーサーを実行しますが、属性を公開しないため、DoubleQuoteルールをシングルに返します L'"'
.
他のヒント
結果を適切に保存しないと思います:
doubleQuote[qi::_val = L'"']
ここでは、「=」のサインのために、すでに入っていたものをオーバーライドします。代わりに '+='で試してください。
doubleQuote[qi::_val += L'"']
また、保存が自動であるかどうかはわかりません。代替の他のパーサーの後に同じ「+=」を追加する必要がある場合があります。
(wide::char_ - L'"')[qi::_val += boost::spirit::arg_names::_1]
しかし、私はQIがそれほど良くないので、おそらく自動化されているので、理にかなっています。
まあ、私は理由が完全にはわかりませんが、その割り当てアクションをサブルールに移動することでそれを修正することができました。
doubleQuote %= (wide::char_(L'"') >> L'"')[qi::_val = L'"'];
doubleQuote.name("double quote");
quotedString = L'"' >> +(doubleQuote | (wide::char_ - L'"')) >> L'"';
quotedString.name("quoted string");
の使用に注意してください operator %=
DoubleQuoteとセマンティックアクションが現在そこにあるという事実の場合。
所属していません StackOverflow