Я пытаюсь написать синтаксический анализатор, который читает в текстовом файле с объявлением переменных и -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», он сказал следующее об атрибутах парсера:
Я нашел источник, который предоставляет алгоритм для отображения атрибутов источника анализаторов спирта: «http://boost-spirit.com/home/2010/01/31/what-is-the-attribute-type-exposed- на-а-парсер /»
После некоторых модификаций я узнал, что атрибут
Для тех, кто заинтересован в алгоритме:
#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;
}
Других решений пока нет …