混合変数($(name)
)と変数と値のペア($(name:value)
)で構成される単純な文法があります。私は手作業でコーディングされた再帰下降パーサーを持っていますが、それをスピリットを学ぶための演習として使用することに興味があります。これは、最終的にはより複雑な文法に必要になります(/すぐに)。
とにかく、私が使用している可能なフォームのセット(完全な文法から簡略化)は次のとおりです。
$(variable) // Uses simple look-up, recursion and inline replace
$(name:value) // Inserts a new variable into the local lookup table
私の現在のルールは次のようになります。
typedef std::map<std::string, std::string> dictionary;
template <typename Iterator>
bool parse_vars(Iterator first, Iterator last, dictionary & vars, std::string & output)
{
using qi::phrase_parse;
using qi::_1;
using ascii::char_;
using ascii::string;
using ascii::space;
using phoenix::insert;
dictionary statevars;
typedef qi::rule<Iterator, std::string()> string_rule;
typedef qi::rule<Iterator, std::pair<std::string, std::string>()> pair_rule;
string_rule state = string >> ':' >> string; // Error 3
pair_rule variable =
(
char_('$') >> '(' >>
(
state[insert(phoenix::ref(statevars), _1)] |
string[output += vars[_1]] // Error 1, will eventually need to recurse
) >> ')'
); // Error 2
bool result = phrase_parse
(
first, last,
(
variable % ','
),
space
);
return r;
}
はっきりしていなければ、Spiritがどのように機能するのかわかりません。ドキュメントには実際の説明以外のすべてが含まれているので、これは例をまとめて約1時間です。
私が特に質問する部分char_('$')
は変数ルールの先頭ですが、これを削除するとシフト演算子エラーが発生します(コンパイラー'$' >> '('
は右シフトとして解釈します)。
コンパイルすると、状態ルール、特にペアの作成、およびルックアップに関連するエラーが発生します。
- エラーC2679:バイナリ'[':タイプ'const boost :: spirit :: _ 1_type'の右側のオペランドをとる演算子が見つかりません(または受け入れ可能な変換がありません)
- エラーC2512:'boost :: spirit :: qi :: rule :: rule':適切なデフォルトコンストラクターが利用できません
ルックアップ(vars[_1]
)を単純に変更すると、次のようになり+=
ます。
3。エラーC2665:'boost :: spirit :: char_class :: classify :: is':15個のオーバーロードのいずれもすべての引数タイプを変換できませんでした
_1
エラー1は、プレースホルダーのタイプ(属性?)に関連しているようですが、これは文字列である必要があり、出力文字列への印刷または連結に使用されます。2は1によって引き起こされたノイズのようです。
テンプレートエラーのスタックを掘り下げるエラー3は、状態ルールをペアに変換できないことに関連しているようです。これは、この例のルールの1つとほぼ完全に一致するため、奇妙に思えます。
両方の入力フォームを適切に処理するように変数ルールを変更するにはどうすればよいですか?