Совместимость атрибутов правила

Я пытаюсь написать синтаксический анализатор, который читает в текстовом файле с объявлением переменных и -Instantiations и создает таблицу переменных, которая содержит все объявленные переменные с соответствующими значениями.

Файл выглядит следующим образом:

 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», он сказал следующее об атрибутах парсера:

  • Тип атрибута символа<Char, T> — это Т.
    => тип атрибута intDecs должен быть int64_t (), а тип атрибута floatDecs должен быть double ()
  • Тип атрибута парсера! A не используется.
  • Если тип атрибута синтаксического анализатора X не используется, а для псевдонима Y — T, то тип атрибута синтаксического анализатора (X >> Y) — T.
    => тип атрибута (! floatDecs >> intDecs) должен быть int64_t ()
  • Если тип атрибута синтаксического анализатора a равен A, а синтаксического анализатора b — B, то тип атрибута синтаксического анализатора (a | b) — boost :: variable ()
    тип атрибута (! floatDecs >> intDecs) | floatDecs) должен быть повышен :: Вариант ()

1

Решение

Я нашел источник, который предоставляет алгоритм для отображения атрибутов источника анализаторов спирта: «http://boost-spirit.com/home/2010/01/31/what-is-the-attribute-type-exposed- на-а-парсер /»

После некоторых модификаций я узнал, что атрибут

  • (! floatDecs >> intDecs) — это __int64 (я думаю, что это не удивительно!)
  • floatDecs является двойным (не удивительно) и
  • (! floatDecs >> intDecs) | floatDecs — это повышение класса :: вариант<_int64, double, struct boost :: detail :: option :: void,structboost :: деталь :: вариант :: void_, структура boost :: detail :: вариант :: void_, структура boost :: detail :: Вариант :: void_, структура boost :: detail :: Вариант :: void_, структура boost: : деталь :: вариант :: void_, расширение структуры :: деталь :: вариант :: void_, повышение структуры :: деталь :: вариант :: void_, повышение структуры :: деталь :: вариант :: void_, повышение структуры :: деталь :: вариант :: void_, расширение структуры :: деталь :: вариант :: void_, расширение структуры :: деталь :: вариант :: void_, повышение структуры :: деталь :: вариант :: void_, повышение структуры :: деталь :: Вариант :: void_, расширение структуры :: деталь :: вариант :: void_, расширение структуры :: деталь :: вариант :: void_, повышение структуры :: деталь :: вариант :: void_, повышение структуры :: деталь :: вариант: : 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;
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector