私は少しだけコンパイラを書くのが楽しいです。私はBoost Spirit Qiを使って文法を説明しています。今私は、いくつかの追加機能を準備するために、文法を少し変更したいと思います。残念ながら、これらの変更はコンパイルされません。なぜこれが当てはまるのか理解したいと思います。ブーストスピリットQi:わずかなルール変更でコンパイルエラー
ここでは、変更したいコードのスニペットを示します。提供された情報がそのアイデアを理解するのに十分であることを願っています完全なコードは少し大きいですが、それを見たりテストしたりするには(MakefileとTravis CIが提供されています)、https://github.com/Kruecke/BFGenerator/blob/8f66aa5/bf/compiler.cpp#L433を参照してください。
typedef boost::variant<
function_call_t,
variable_declaration_t,
variable_assignment_t,
// ...
> instruction_t;
struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> {
grammar() : grammar::base_type(program) {
instruction = function_call
| variable_declaration
| variable_assignment
// | ...
;
function_call = function_name >> '(' > -(variable_name % ',') > ')' > ';';
// ...
}
qi::rule<iterator, instruction::instruction_t(), ascii::space_type> instruction;
qi::rule<iterator, instruction::function_call_t(), ascii::space_type> function_call;
// ...
};
これまでのところ、すべて正常に機能しています。今度は、末尾のセミコロン(> ';'
)の解析をfunction_call
ルールからinstruction
ルールに移動したいと考えています。文字パーサ3210は、任意の属性を得られないと、このパーサが配置された場合ので、それは問題ではないはずので、ルールは本当に変わっていない私の理解から
struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> {
grammar() : grammar::base_type(program) {
instruction = (function_call > ';') // Added trailing semicolon
| variable_declaration
| variable_assignment
// | ...
;
// Removed trailing semicolon here:
function_call = function_name >> '(' > -(variable_name % ',') > ')';
// ...
}
:私のコードは次のようになります。しかし、この変更はコンパイルされません。
/usr/include/boost/spirit/home/support/container.hpp:278:13: error: no matching function for call to ‘std::basic_string<char>::insert(std::basic_string<char>::iterator, const bf::instruction::function_call_t&)’
c.insert(c.end(), val);
^
(このエラーはinstruction = ...
ラインから来ている。)
をこの変更がコンパイルされていないのはなぜ?むしろ回避策よりも何が起こっているのかを理解するための説明を探しています。
あなたは絶対に正しいです! 'function_call_t'に' std :: string'を1つしか持たないことは意図したものではありませんでしたので、前のコードが最初に実行されたことに非常に驚いています! 私は構造体に 'std :: vector variable_names'を追加しました。これはすぐに問題を解決します。どうもありがとう! –