Использование анализа итератора с Boost::Spirit Grammars

StackOverflow https://stackoverflow.com/questions/529706

  •  22-08-2019
  •  | 
  •  

Вопрос

Когда я пытаюсь использовать форму итератора для анализа грамматики Spirit, я получаю аргумент, передающий ошибку преобразования из типа итератора в const char*.Как это исправить?

Есть некоторые ограничения.Я использую адаптер итератора для больших входных данных, поэтому мне невозможно преобразовать его в строку стиля C.

Вот пример кода, демонстрирующий проблему:

#include <boost/spirit/core.hpp>
#include <boost/spirit/iterator/file_iterator.hpp>
#include <vector>
#include <string>
using std;
using boost::spirit;
struct ex : public grammar<route_grammar> {
  template <typename ScannerT> struct defintion {
    definition(ex const& self) {
      expression = real_p; 
    }
    rule<ScannerT> expression;
    rule<ScannerT> const& start() const { return expression; }
};

int main() {
  file_iterator<char> first;
  file_iterator<char> last = first.make_end();
  ex ex_p;
  parse_info<file_iterator<char> > info = parse(first, last, ex_p, space_p);
  return 0;
}

Этот код ломается:ошибка:не могу конвертировать const boost::spirit::file_iterator<char_t, boost::spirit::fileiter_impl::mmap_file_iterator<char_t> > к const char* при передаче аргумента

Это было полезно?

Решение

Трудно сказать по опубликованному коду, поскольку он содержит несколько основных ошибок.После их исправления он отлично компилируется на моей машине (с MSVC++7.1):

#include <boost/spirit/core.hpp>
#include <vector>
#include <string>
using namespace std;
using namespace boost::spirit;
struct ex : public grammar<ex> {
template <typename ScannerT> 
struct definition {
    definition(ex const& self)
    {
    expression = real_p; 
    }
    rule<ScannerT> expression;
    rule<ScannerT> const& start() const { return expression; }
};
};

int main() {
vector<char> v;
v.push_back('3'); v.push_back('.'); v.push_back('2');
ex ex_p;
parse_info<vector<char>::iterator> info = parse(v.begin(), v.end(), ex_p, space_p);
return 0;
}

Другие советы

Вот один из способов получить символы char *, указывающие на те же элементы, что и итераторы:

&v.front() // v.begin()
&v.back() + 1 // v.end()

Я не уверен, как вам удалось это скомпилировать:

vector<char> v;
v.push_back("3.2");

Ошибки компиляции не было в предоставленном образце.В грамматике выше у меня нет смысловых действий, а в коде, который я упрощал, они есть.

Обратные вызовы для этих действий использовали char* вместо типа итератора, который я использовал.

Вы можете попробовать сделать так, чтобы ваши семантические действия были полиморфными по типу аргумента.Именно в коде вам нужно что-то вроде этого:

struct my_action {
  template <class ParamType>
  void operator()(ParamType const & parameter) const {
    // deal with parameter
  }
};

Вы можете использовать унарное семантическое действие, подобное этому, как показано ниже:

real_p[my_action()]

Или, если вам нужно бинарное семантическое действие, вы должны сделать что-то вроде:

struct binary_action {
  template <class ParamType>
  void operator()(ParamType const & param1, ParamType const & param2) const {
    // deal with either parameter
  }
};

(*char_p)[binary_action()]
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top