boost::spirit::qi and out-of-sequence variables

一个人想着一个人 提交于 2019-12-21 04:42:12

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/4788470/boostspiritqi-and-out-of-sequence-variables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!