Analisi con Boost :: Spirit (V2.4) nel contenitore
-
29-09-2019 - |
Domanda
Ho appena iniziato a scavare in Boost :: Spirito, la versione più recente, ormai - V2.4. L'essenza del mio problema è il seguente:
Vorrei stringhe parse come "1a2" o "3B4". Quindi l'uso regola che è:
(double_ >> lit('b') >> double_)
| (double_ >> lit('a') >> double_);
L'attributo della regola deve essere "vector
Il codice completo:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cstring>
int main(int argc, char * argv[])
{
using namespace std;
using namespace boost::spirit;
using namespace boost::spirit::qi;
using boost::phoenix::arg_names::arg1;
char const * first = "1a2";
char const * last = first + std::strlen(first);
vector<double> h;
rule<char const *, vector<double>()> or_test;
or_test %= (double_ >> lit('b') >> double_)
| (double_ >> lit('a') >> double_);
if (parse(first, last, or_test,h)) {
cout << "parse success: ";
for_each(h.begin(), h.end(), (cout << arg1 << " "));
cout << "end\n";
} else cout << "parse error\n" << endl;
return 0;
}
Sto compilando con g ++ 4.4.3. E si ritorna "1 1 2". Mentre mi aspetto "1 2".
Per quanto ho capito questo accade perché parser:
- va alla prima alternativa
- legge un double_ e lo memorizza nel contenitore
- poi si ferma in "a", mentre aspettandosi acceso ( "b")
- va alla seconda alternativa
- legge due ulteriori doppie
La mia domanda è - È questo un comportamento corretto, e se sì, - perché
Soluzione
comportamento che ci si aspetta. Durante backtracking Spirito non fa cambiamenti 'disfare' a attributi. Pertanto, è necessario utilizzare la direttiva hold[]
costringendo esplicitamente il parser per tenere su di una copia dell'attributo (che consente di ripristinare ogni cambiamento attributo):
or_test =
hold[double_ >> lit('b') >> double_)]
| (double_ >> lit('a') >> double_)
;
la presente direttiva deve essere applicato a tutte le alternative che modificano l'attributo, tranne l'ultimo.