I'm writing a lexigraphical analyser. It takes an English string, and converts it into a set of latitude/longitude co-ordinates. It's a bit like Google Earth.
Anyway, I've written my symbol tables and grammar, and it's happily parsing formatted data.
struct LatLongDegrees
{
std::string dirLat_;
double degLat_;
std::string dirLong_;
double degLong_;
}
For example: {"North", 23.59, "East", -30.82}
Here is my grammar:
basic =(latitude >> ' ' >> double_ >> ' ' >> longitude >> ' ' >> double_);
Where latitude and longitude are symbol tables that map from shorthand compass directions to strings (eg "e" to "East")
So, on to my question:
I want to add the following rule to my grammar, where the latitude and longitude symbols are in the opposite positions:
reversed = (longitude >> ' ' >> double_ >> ' ' >> latitude >> double_ )
This parses, BUT the degLat_ and degLong_ values are not reversed along with string values. They are simply parsed directly into the struct, without regard for the string labels.
How do I build a struct (or boost::fusion vector) when the data to be parsed is not sequential?
You have several possibilities. The easiest is to adapt your struct into a Fusion sequence in the required order:
BOOST_FUSION_ADAPT_STRUCT(
LatLongDegrees,
(std::string, dirLong_)
(double, degLong_)
(std::string, dirLat_)
(double, degLat_)
);
(yes, the order of adaptation does not have to match the order of the members in the original struct, you can even leave out members or duplicate them). This works fine if you have one particular order you want to parse your members in.
If you need different orderings in the same program, you might want to utilize a similar adaptation mechanism, but which additionally allows to give a name to the adapted struct:
BOOST_FUSION_ADAPT_STRUCT_NAME(
LatLongDegrees, reversed_LatLongDegrees,
(std::string, dirLong_)
(double, degLong_)
(std::string, dirLat_)
(double, degLat_)
);
where reversed_LatLongDegrees
is the data type used as the attribute in your Spirit grammar:
rule <Iterator, reversed_LatLongDegrees()> reversed;
reversed = longitude >> ' ' >> double_ >> ' ' >> latitude >> double_;
LatLongDegrees data;
parse(begin, end, reversed, data);
This allows to create several adaptations for the same struct at the same time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With