1

Variable-Declaration と -Instantiations を含むテキスト ファイルを読み取り、宣言されたすべての変数とそれに関連付けられた値を含む Variable-Table を構築するパーサーを作成しようとしています。

ファイルは次のようになります。

 int a = 18, b = 1+a*5;
 float test = rand(a);

これを達成するために、boost::spirit::qi パーサー ライブラリを使用したいと思います。これは、シンボルを可変データ型 T に関連付けることができる動的シンボル テーブル パーサーを提供します。提供されたシンボル テーブル パーサーの欠点は、その記号のみを 1 つのデータ型の値に関連付けます。

次のコードがあります。

 #include <boost/spirit/include/qi.hpp>
 #include <stdint.h>
 #include <string>
 template<typename VTYPE>
 struct VTable : boost::spirit::qi::symbols<char, VTYPE> {
      VTable() {} // empty
 };

 int main()
 {
      using boost::spirit::qi::rule;
      using boost::spirit::qi::space_type;

      VTable<int64_t> intDecs; VTable<double> floatDecs;
      rule<std::string::iterator, boost::variant<int64_t, double>() ,space_type> decs %= (!floatDecs >> intDecs) | floatDecs;
      return 0;
 }

問題は、return ステートメントの 1 行前にあります。「%=」の左側の属性は、明らかに右側の属性と互換性がありません (Visual Studio がそのコードについて不平を言っているため)。

私の質問は、なぜそうなのかということです。

Documentation of Spirit::Qi を読んだとき、パーサー属性について次のように述べていました。

  • symbol<Char, T> の属性タイプは T です。
    => intDecs の属性タイプは int64_t() であり、floatDecs の属性タイプは double() である必要があります。
  • パーサー !a の属性タイプは使用されていません。
  • パーサー X の属性タイプが未使用で、パーサー Y の属性タイプが T の場合、パーサーの属性タイプ (X >> Y) は T です。
    => (!floatDecs >> intDecs) の属性タイプは int64_t() である必要があります。
  • パーサー a の属性タイプが A で、パーサー b の属性タイプが B の場合、パーサー (a | b) の属性タイプは boost::variant()
    attribute type of (!floatDecs >> intDecs) | floatDecs) は boost::variant() にする必要があります
4

1 に答える 1

1

スピリットパーサーソースの属性を表示するアルゴリズムを提供するソースを見つけました:「http://boost-spirit.com/home/2010/01/31/what-is-the-attribute-type-exposed- by-a-parser/"

いくつかの変更の後、私はの属性を発見しました

  • (!floatDecs >> intDecs) は __int64 です (当然のことだと思います!)
  • floatDecs は double (驚くことではありません) であり、
  • (!floatDecs >> intDecs) | floatDecs はクラス boost::variant<_ int64,double,struct boost::detail::variant::void ,structboost::detail::variant::void_,struct boost::detail::variant::void_,struct boost です::detail::variant::void_,struct boost::detail::variant::void_,struct boost::detail::variant::void_,struct boost::detail::variant::void_,struct boost:: detail::variant::void_,struct boost::detail::variant::void_,struct boost::detail::variant::void_,struct boost::detail::variant::void_,struct boost::detail: :variant::void_,struct boost::detail::variant::void_,struct boost::detail::variant::void_,struct boost::detail::variant::void_,struct boost::detail::variant ::void_,struct boost::detail::variant::void_,struct boost::detail::variant::void_>

アルゴリズムに興味のある方へ:

#include <boost/spirit/include/qi.hpp>
#include <stdint.h>
#include <iostream>
#include <string>

template<typename VTYPE>
struct VTable : boost::spirit::qi::symbols<char, VTYPE> {
    VTable() {} // empty
};

template <typename Expr, typename Iterator = std::string::iterator>
struct attribute_of_parser {
    typedef typename boost::spirit::result_of::compile<boost::spirit::qi::domain, Expr>::type parser_expression_type;
    typedef typename boost::spirit::traits::attribute_of<parser_expression_type, boost::spirit::unused_type, Iterator>::type type;
};

template <typename T>
void display_attribute_of_parser(T const&)
{
    typedef typename attribute_of_parser<T>::type attribute_type;
    std::cout << typeid(attribute_type).name() << std::endl;
}

int main()
{
    using boost::spirit::qi::eps;
    using boost::spirit::qi::rule;
    using boost::spirit::qi::space_type;

    VTable<int64_t> intDecs; VTable<double> floatDecs;
    display_attribute_of_parser((!floatDecs >> intDecs));
    display_attribute_of_parser(floatDecs);
    display_attribute_of_parser((!floatDecs >> intDecs) | floatDecs);

    return 0;
}
于 2013-01-13T22:54:46.657 に答える