2016-04-04 12 views
0

私は少しだけコンパイラを書くのが楽しいです。私は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 = ...ラインから来ている。)

をこの変更がコンパイルされていないのはなぜ?むしろ回避策よりも何が起こっているのかを理解するための説明を探しています。

答えて

2

これをよく見てから、function_call_t型に複数の文字列を挿入しようとしています。これは、単一のstd :: stringから変換できるフュージョンシーケンスです。しかし、実際には属性がtuple <std::string, optional <vector <std::string>>>なので、おそらくfunction_callルールの問題に遭遇するでしょう。私はその精神がその構造を平らにする問題を持っていると想像したいと思いますが、それはあなたの問題を引き起こしていますが、現時点でそれをテストするコンパイラはありません。

+0

あなたは絶対に正しいです! 'function_call_t'に' std :: string'を1つしか持たないことは意図したものではありませんでしたので、前のコードが最初に実行されたことに非常に驚いています! 私は構造体に 'std :: vector variable_names'を追加しました。これはすぐに問題を解決します。どうもありがとう! –

関連する問題