规则属性的兼容性

时间:2013-01-13 22:07:02

标签: c++ boost-spirit boost-spirit-qi

我正在尝试编写一个解析器,它使用Variable-Declaration和-Instantiations读取文本文件,并构造一个Variable-Table,其中包含所有声明的变量及其关联值。

该文件如下所示:

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

为了实现这一点,我想使用boost :: spirit :: qi解析器库,它提供了一个动态符号表解析器,可以将符号关联到可变数据类型T. 提供的符号表解析器的缺点是,它只能将其符号与一种数据类型的值相关联。

我有以下代码:

 #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语句之前的一行。 '%='左侧的属性显然与右侧的属性不兼容(因为Visual Studio正在抱怨该代码)。

我的问题是,为什么会这样?

当我阅读Spirit :: Qi的文档时,它会解释以下关于解析器属性的内容:

  • 符号的属性类型&lt; Char,T&gt;是T.
    =&gt; intDecs的属性类型应该是int64_t(),floatDecs的属性类型应该是double()
  • 解析器的属性类型!a未使用。
  • 如果解析器X的属性类型未使用且paser Y为T,则解析器的属性类型(X>&gt; Y)为T.
    =&gt;属性类型(!floatDecs&gt;&gt; intDecs)应为int64_t()
  • 如果解析器a的属性类型是A而解析器b的属性类型是B,那么解析器的属性类型(a | b)是boost :: variant()属性类型(!floatDecs&gt; &gt; intDecs)| floatDecs)应该是boost :: variant()

1 个答案:

答案 0 :(得分:1)

我找到了一个源,它提供了一个算法来显示精神解析器源的属性:“http://boost-spirit.com/home/2010/01/31/what-is-the-attribute-type -exposed逐一个解析器/“

经过一些修改后,我发现了

的属性
  • (!floatDecs&gt;&gt; intDecs)是__int64(我认为这并不奇怪!)
  • floatDecs是双倍的(毫不奇怪)和
  • (!floatDecs&gt;&gt; intDecs)| floatDecs是类boost :: variant&lt; _ 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_&gt;

对于算法中的那些人:

#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;
}