2011-01-24 11 views
6

Sto scrivendo un analizzatore lessigrafico. Prende una stringa inglese e la converte in un insieme di coordinate di latitudine/longitudine. È un po 'come Google Earth.boost :: spirit :: qi e variabili fuori sequenza

In ogni caso, ho scritto le tabelle dei simboli e la grammatica, ed è felicemente analizzando i dati formattati.

struct LatLongDegrees 
{ 
std::string dirLat_; 
double degLat_; 
std::string  dirLong_; 
double degLong_; 
} 

Ad esempio: { "Nord", 23.59, "Oriente", -30,82}

Ecco la mia grammatica:

basic =(latitude >> ' ' >> double_ >> ' ' >> longitude >> ' ' >> double_); 

Dove latitudine e longitudine sono tabelle dei simboli che mappano da stenografia bussola indicazioni per archi (ad esempio "e" a "Oriente")

Così, alla mia domanda:

Voglio aggiungere la seguente regola per la mia grammatica, dove i latitudine e longitudine simboli sono nelle posizioni opposte:

reversed = (longitude >> ' ' >> double_ >> ' ' >> latitude >> double_) 

Questo analizza, ma i valori degLat_ e degLong_ non sono ripristinate con i valori di stringa. Vengono semplicemente analizzati direttamente nella struttura, senza riguardo per le etichette stringa.

Come si costruisce un vettore struct (o boost :: fusion) quando i dati da analizzare non sono sequenziali?

risposta

6

Avete diverse possibilità. Il metodo più semplice è quello di adattare lo struct in una sequenza Fusion nell'ordine desiderato:

BOOST_FUSION_ADAPT_STRUCT(
    LatLongDegrees, 
    (std::string, dirLong_) 
    (double, degLong_) 
    (std::string, dirLat_) 
    (double, degLat_) 
); 

(sì, l'ordine di adattamento non deve necessariamente corrispondere all'ordine dei membri della struct originale, si può anche lasciare fuori membri o duplicarli). Funziona bene se hai un ordine particolare in cui vuoi analizzare i tuoi membri.

Se hai bisogno di diversi ordini nello stesso programma, potresti voler utilizzare un meccanismo di adattamento simile, ma che consente anche di dare un nome a struct adattato:

BOOST_FUSION_ADAPT_STRUCT_NAME(
    LatLongDegrees, reversed_LatLongDegrees, 
    (std::string, dirLong_) 
    (double, degLong_) 
    (std::string, dirLat_) 
    (double, degLat_) 
); 

dove reversed_LatLongDegrees è il tipo di dati utilizzato come attributo nella tua grammatica Spirito:

rule <Iterator, reversed_LatLongDegrees()> reversed; 
reversed = longitude >> ' ' >> double_ >> ' ' >> latitude >> double_; 

LatLongDegrees data; 
parse(begin, end, reversed, data); 

Questo permette di creare diversi adattamenti per lo stesso struct, allo stesso tempo.

Problemi correlati