1

I'm trying to write a parser, that reads in a text file with Variable-Declaration and -Instantiations and that constructs a Variable-Table, which contains all declared variables with their associated values.

The file looks like the following:

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

To accomplish this I would like to use the boost::spirit::qi parser library, that provides a dynamic symbol table parser that can associate a symbol to a mutable datatype T. The downside of the provided symbol table parser is, that it can only associate its symbols to values of one datatype.

I have the following code:

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

The problem lies one line before the return statement. The attribute on the left hand side of '%=' is obviously not compatible to the attribute on the right hand side (because Visual Studio is complaining about that code).

My Question is, why is that so?

When I read the Documentation of Spirit::Qi it said the following about the parser attributes:

  • The attribute type of symbol<Char, T> is T.
    =>attribute type of intDecs should be int64_t() and attribute type of floatDecs should be double()
  • The attribute type of the parser !a is unused.
  • If the attribute type of parser X is unused and of paser Y is T, then the attribute type of the parser (X >> Y) is T.
    => attribute type of (!floatDecs >> intDecs) should be int64_t()
  • If the attribute type of parser a is A and of parser b is B, then the attribute type of the parser (a | b) is boost::variant()
    attribute type of (!floatDecs >> intDecs) | floatDecs) should be boost::variant()
user1861174
  • 507
  • 1
  • 5
  • 14

1 Answers1

1

I found a source, that provides an algorithm to display the attributes of the spirit parsers source: "http://boost-spirit.com/home/2010/01/31/what-is-the-attribute-type-exposed-by-a-parser/"

After some modifications, I found out that the attribute of

  • (!floatDecs >> intDecs) is __int64 (i think that is no surprise!)
  • floatDecs is double (no surprise) and
  • (!floatDecs >> intDecs) | floatDecs is class 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_>

For those interestered in the algorithm:

#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;
}
user1861174
  • 507
  • 1
  • 5
  • 14