【问题标题】:Compatiblity of the rule attributes规则属性的兼容性
【发布时间】:2013-01-13 22:07:01
【问题描述】:

我正在尝试编写一个解析器,它读取带有变量声明和实例化的文本文件,并构造一个变量表,其中包含所有声明的变量及其相关值。

文件如下所示:

 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 的文档时,它对解析器属性说了以下内容:

  • symbol的属性类型是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()
    (!floatDecs >> intDecs) 的属性类型) | floatDecs) 应该是 boost::variant()

【问题讨论】:

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


    【解决方案1】:

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

    经过一些修改,我发现了

    的属性
    • (!floatDecs >> intDecs) 是 __int64(我认为这并不奇怪!)
    • floatDecs 是双倍的(不足为奇)并且
    • (!floatDecs >> intDecs) | floatDecs 是类 boost::variant<_>int64,double,struct boost::detail::variant::void,structboost::detail::variant::void_,struct boost::detail::变量::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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-28
      • 1970-01-01
      • 2012-05-07
      相关资源
      最近更新 更多