Boost regola Spirito con attributo personalizzato parsing
-
30-09-2019 - |
Domanda
Sto scrivendo una grammatica Boost Spirito in testo parse in un vettore di questi le strutture:
struct Pair
{
double a;
double b;
};
BOOST_FUSION_ADAPT_STRUCT(
Pair,
(double, a)
(double, a)
)
Questa grammatica è una regola come questa:
qi::rule<Iterator, Pair()> pairSequence;
Tuttavia, la grammatica effettiva di pairSequence
è questo:
double_ % separator
Voglio questa grammatica per produrre un Pair
con a
pari al doppio e b
uguale ad una costante. Voglio fare qualcosa di simile:
pairSequence = double_[_val = Pair(_1, DEFAULT_B)] % separator;
È possibile che questo non compila, ovviamente. Ho provato ad aggiungere un costruttore per Pair
, ma ho ancora errori di compilazione ( nessuna funzione di corrispondenza per la chiamata a 'Coppia :: Coppia (spinta const :: :: Phoenix attore> &, doppio)' ).
Soluzione
Prima di tutto, la firma di pairSequence
deve essere:
qi::rule<Iterator, std::vector<Pair>()> pairSequence;
come l'operatore lista espone una std::vector<Pair>
come suo attributo.
Tutte le funzioni chiamate dall'interno di un'azione semantica devono essere 'pigro', quindi è necessario utilizzare phoenix:
namespace phx = boost::phoenix;
pairSequence =
double_[
phx::push_back(_val,
phx::construct<Pair>(_1, phx::val(DEFAULT_B))
)
] % separator
;
Un'altra possibilità sarebbe quella di aggiungere un costruttore (non esplicito) a Pair
:
struct Pair
{
Pair(double a) : a(a), b(DEFAULT_B) {}
double a;
double b;
};
che consente di semplificare la grammatica:
pairSequence = double_ % separator;
e si basa completamente sul Spirito built-in regole di attributo di propagazione.
A proposito, per tutto questo al lavoro, non c'è bisogno di adattarsi Pair
come una sequenza di fusione.