En utilisant Iterator avec l'analyse syntaxique Boost :: Spirit Grammars
-
22-08-2019 - |
Question
Lorsque je tente d'utiliser le formulaire de iterator de l'analyse syntaxique pour une grammaire de l'Esprit, je reçois une erreur de conversion passant argument du type iterator à const char *. Comment puis-je résoudre ce problème?
Il y a quelques restrictions. J'utilise un adaptateur iterator sur de grandes entrées, il est donc impossible pour moi de convertir en une chaîne de style C.
Voici un exemple de code démontrant la question:
#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;
}
Ce code rompt avec: erreur: ne peut pas convertir passer const boost::spirit::file_iterator<char_t, boost::spirit::fileiter_impl::mmap_file_iterator<char_t> >
à const char*
en argument
La solution
Difficile à dire à partir du code comme affiché, car il contient quelques erreurs de base. Après correction de ces derniers, il compile bien sur ma machine (avec 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;
}
Autres conseils
Voici une façon d'obtenir le pointage ombles de * les mêmes éléments que les itérateurs:
&v.front() // v.begin()
&v.back() + 1 // v.end()
Je ne sais pas comment vous avez cela compilez si:
vector<char> v;
v.push_back("3.2");
L'erreur de compilation n'a pas été dans l'échantillon fourni. Dans la grammaire ci-dessus, je n'ai pas les actions sémantiques, alors que dans le code que je simplifiait je l'ai fait.
Les callbacks pour les actions utilisées char * au lieu du type iterator j'utilisais.
Vous pouvez essayer de faire en sorte que vos actions sémantiques sont polymorphes sur le type de l'argument. Précisément dans le code que vous voudriez quelque chose comme ceci:
struct my_action {
template <class ParamType>
void operator()(ParamType const & parameter) const {
// deal with parameter
}
};
Vous utiliseriez une action sémantique unaire comme celui-ci, comme indiqué ci-dessous:
real_p[my_action()]
Ou si vous avez besoin d'une action sémantique binaire, vous feriez quelque chose comme:
struct binary_action {
template <class ParamType>
void operator()(ParamType const & param1, ParamType const & param2) const {
// deal with either parameter
}
};
(*char_p)[binary_action()]