5

Mathematica に似た言語用のパーサーを書こうとしていますが、式の部分部分を解析するために私の精神文法を呼び出すとよいことがわかりました。

つまり、解析しようとしている場合

a+b*c+d 

parse()「+」記号を照会しながら「b*c」部分を呼び出すと便利です。

私の文法の同じインスタンスを使用しながら、これを行うことは可能ですか? (文法パラメーターは「*this」になります)

これがこの特定のタスクを達成するための最良の方法であるかどうかはまだ完全には確信が持てませんが、ドキュメントには何も見つからなかったので、興味深い質問だと思います。

この手法を使用する場合、明らかに、クラスローカル変数またはグローバル変数に依存するべきではありません。しかし、精神の設計上、それが原則的に許されているかどうか知りたいです。

編集

私の文法インスタンスは次のようになります。

class MyGrammar : public boost::spirit::qi::grammar<...>  
{  
    /* a few rules. Some with local and/or inherited attributes */  
    MyGrammar( void )  
    {
         /* assign all the rules, use a few 'on_error' statements */
         // In one or two rules I would like to invoke parse(...,*this,...)  
         // on a subrange of the expression
    }
}  

ありがとう!

4

1 に答える 1

8

もちろん、次のことができます。

// In one or two rules I would like to invoke parse(...,*this,...)  
// on a subrange of the expression

^ それは、宣言文法でルールが構成される方法ではありません。あなたはこれを手続き的な観点から考えているようです (これは、再帰降下パーサーを作成した経験があることを示している可能性があります)。


私の考えでは、単純な表現文法は次のようになります。

  literal     = +qi::int_;
  variable    = lexeme [ qi::alpha >> *qi::alnum ];
  term        =  literal 
               | variable 
               | (qi::lit('(') > expression >> ')');

  factor      = term >> *(qi::char_("+-") >> term);
  expression  = factor >> *(qi::char_("*/%") >> term);

の最後の分岐での再帰に注意してください。これは、term括弧で囲まれた式を解析します。

この単純化されたサンプルでは、​​実際には、演算子の優先順位を反映する解析ツリーは得られません。しかし、Spirit ライブラリのサンプルとテストには、実行する多くの例が含まれています。

これがどのように機能するかをより詳細に示す私の他の回答も参照してください(完全なサンプル付き):

それが役立つことを願っています

于 2012-09-27T13:41:20.130 に答える