2

Spirit Qi のシーケンス演算子とセマンティック アクションについていくつか質問があります。

通常の指数形式だけでなく、メトリック プレフィックス (u、m、k、M など) を受け入れる浮動小数点数の文法規則を定義しようとしています。

  rule<Iterator, std::string()> sign = char_("+-") [ _val = _1 ];
  rule<Iterator, std::string()> exp = char_("eE") >> -sign >> +digit;
  rule<Iterator, std::string()> suffix = char_("yzafpnumkKMGTPEZY") [ _val = _1 ];
  rule<Iterator, std::string()> mantissa = ((*digit >> char_('.') >> +digit) | (+digit >> char_('.') >> *digit));
  rule<Iterator, std::string()> unsigned_floating = (mantissa >> -(exp | suffix) | +digit >> (exp | suffix));
  rule<Iterator, std::string()> floating = -sign >> unsigned_floating;

質問 1:上記のルールにセマンティック アクションを追加する必要があるのはなぜsignですか? charに変換できませんstd::stringか?

質問 2: 次のように最後の 2 つのルールをマージしようとすると、コンパイルが失敗するのはなぜですか?

  rule<Iterator, std::string()> floating = -sign >> (mantissa >> -(exp | suffix) | +digit >> (exp | suffix));

質問 3:floatingの属性をbedoubleにして、string から double への変換を行うセマンティック アクションを記述したいとします。セマンティック アクション内からルールに一致する文字列全体を参照するにはどうすればよいですか?

質問 4:質問 2のルールfloatingで、プレースホルダー_2は何を参照し、その型は何ですか?

編集:

最後の質問には説明が必要だと思います。

次のルールのセマンティック アクションで、プレースホルダー _2 は何を参照し、その型は何ですか?

  rule<Iterator, std::string()> floating = (-sign >> (mantissa >> -(exp | suffix) | +digit >> (exp | suffix))) [ _2 ];

ありがとう!

4

1 に答える 1

2

まずは一撃一撃。すぐに使える答えについては、以下を参照してください。

質問 1 : 上記の規則記号にセマンティック アクションを追加する必要があるのはなぜですか? char は std::string に変換できませんか?

ええと、どの文字も文字列に変換できません。その他のオプションについては、以下を参照してください。

質問 2 : 最後の 2 つのルールを次のようにマージしようとすると、コンパイルが失敗するのはなぜですか。

rule<Iterator, std::string()> floating = -sign >> 
              (mantissa >> -(exp | suffix) | +digit >> (exp | suffix));

これは、アトミック属性割り当ての規則によるものです。パーサーは次のようなものを公開します

vector2<optional<string>, variant<
      vector2<string, optional<string> >,
      vector2<std::vector<char>, optional<string> > >

または同様のもの(パーサーのドキュメントを参照してください。これは、ブラウザーでメモリから入力したものです)。これは、明らかに、文字列に割り当てることはできません。qi::as<>アトミック割り当てを強制するために使用します。便宜上、***がありますqi::as_string

floating = qi::as_string [ -sign >> (mantissa >> -(exp | suffix) | 
                                     +digit >> (exp | suffix)) ] 

質問 3 : float の属性を double にして、string から double への変換を行うセマンティック アクションを書きたいとします。セマンティック アクション内からルールに一致する文字列全体を参照するにはどうすればよいですか?

qi::as_stringもう一度使用することもできますが、最も適切なのは以下を使用することqi::rawです。

floating = qi::raw [ -sign >> (mantissa >> -(exp | suffix) | 
                               +digit >> (exp | suffix)) ] 
       [ _val = parse_float(_1, _2) ];

このパーサーディレクティブはソース イテレータのペアを公開するため、これを使用して、一致した正確な入力シーケンスを参照できます。

質問 4 : 質問 2 のルール フローティングで、プレースホルダー _2 は何を参照し、その型は何ですか?

一般に、属性タイプを検出するには、つまり、ドキュメントで混乱したり、理解を再確認したい場合は、次の回答を参照してください。


すぐに使える

包括的にカスタマイズできるQi の組み込みreal_parser<>テンプレートの使用を見たことがありますか。セマンティックアクションでカスタム解析を行う代わりに、それを使用したいようです。

ポリシーを含む real_parserテンプレートは、高速であり、非常に柔軟で堅牢です。最近の回答も参照してください入力ストリームを使用して無限大または NaN 値を読み取ることは可能ですか? .

RealPolicies のモデルでは、次の式が有効でなければなりません。

Expression                 | Semantics 
===========================+=============================================================================
RP::allow_leading_dot      | Allow leading dot. 
RP::allow_trailing_dot     | Allow trailing dot. 
RP::expect_dot             | Require a dot. 
RP::parse_sign(f, l)       | Parse the prefix sign (e.g. '-'). Return true if successful, otherwise false. 
RP::parse_n(f, l, n)       | Parse the integer at the left of the decimal point. Return true if successful, otherwise false. If successful, place the result into n. 
RP::parse_dot(f, l)        | Parse the decimal point. Return true if successful, otherwise false. 
RP::parse_frac_n(f, l, n)  | Parse the fraction after the decimal point. Return true if successful, otherwise false. If successful, place the result into n. 
RP::parse_exp(f, l)        | Parse the exponent prefix (e.g. 'e'). Return true if successful, otherwise false. 
RP::parse_exp_n(f, l, n)   | Parse the actual exponent. Return true if successful, otherwise false. If successful, place the result into n. 
RP::parse_nan(f, l, n)     | Parse a NaN. Return true if successful, otherwise false. If successful, place the result into n. 
RP::parse_inf(f, l, n)     | Parse an Inf. Return true if successful, otherwise false. If successful, place the result into n

それをどのように使用するかについての説得力のあるアイデアについては、例を参照してください。

于 2012-07-20T08:34:25.823 に答える