Utilizzando Iterator parsing con boost :: Spirit Grammatiche
-
22-08-2019 - |
Domanda
Quando si tenta di utilizzare il modulo iteratore di analisi per una grammatica Spirit ottengo un argomento che passa errore di conversione dal tipo iteratore a const char *. Come posso risolvere questo problema?
Ci sono alcune restrizioni. Sto usando un adattatore iteratore su grandi ingressi, quindi non è possibile per me, per convertire in una stringa stile C.
Ecco il codice di esempio dimostrando il problema:
#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;
}
Questo codice rompe con: errore: non può convertire const boost::spirit::file_iterator<char_t, boost::spirit::fileiter_impl::mmap_file_iterator<char_t> >
a const char*
in argomento passando
Soluzione
Difficile da dire dal codice come pubblicato, dal momento che contiene alcuni errori di base. Dopo la correzione di questi, compila bene sulla mia macchina (con 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;
}
Altri suggerimenti
Ecco un modo di ottenere il char * s 'che punta agli stessi elementi delle iteratori:
&v.front() // v.begin()
&v.back() + 1 // v.end()
Non sono sicuro di come hai questo di compilare però:
vector<char> v;
v.push_back("3.2");
L'errore di compilazione non era nel campione fornito. Nella grammatica di cui sopra non ho azioni semantiche, mentre nel codice stavo semplificando l'ho fatto.
I callback per quelle azioni utilizzati char * invece del tipo iteratore stavo usando.
Si può provare a fare in modo che le vostre azioni semantiche erano polimorfa del tipo dell'argomento. Proprio nel codice che ci si vuole qualcosa di simile:
struct my_action {
template <class ParamType>
void operator()(ParamType const & parameter) const {
// deal with parameter
}
};
Si potrebbe utilizzare un azione semantica unario come questo, come illustrato di seguito:
real_p[my_action()]
Se avete bisogno di un'azione semantica binario, devi fare qualcosa di simile:
struct binary_action {
template <class ParamType>
void operator()(ParamType const & param1, ParamType const & param2) const {
// deal with either parameter
}
};
(*char_p)[binary_action()]