Spirit syntax for list

In the previous post we have seen a function, csvSum() that adds up all the elements of a CSV (Comma Separated Value) list returning the result in a double that is passed as input parameter. A user could be surprised by the fact that the double value provided in input is not considered at all. Besides, if we just accept the fact that the function caller could initialize the returned value as he likes, the resulting code is more linear, since we are allowed to manage all the elements in the list in the same way.

That's how the call to phrase_parse() was written in our function:
bool r = phrase_parse(beg, input.end(),
double_[ref(sum) = _1] >> *(',' >> double_[ref(sum) += _1]), space);

The first element in the list is assigned to sum, overwriting whatever the caller has put in it. Instead of it, now we want to use the same parser semantic action for all the elements: ref(sum) += _1.

Having a CSV list (or, more generically speaking, a list of values separated by something) that requires each if its element to be managed in the same way is such a common task that Spirit provides an elegant syntax just for this case.

So, a CSV list of floating point numbers could be expressed with the full notation that we already know:
double_ >> *(',' >> double_)
Or with a more compact syntax that use the percent character to show an indefinite repetition with a separator:
double_ % ','
Usually the separator is just a character, and normally a comma. But the same notation could be used also if the separator is a string. For instance, we could have values separated by an uppercase triple X sequence:
double_ % "XXX"
Said that, this is the change we are about to do in our code:
bool r = phrase_parse(beg, input.end(), double_[ref(sum) += _1] % ',', space);

And we are about to call the adding function like this:
std::string s("1, 3, 4, 5");
double sum = 1000; // 1.

if(csvSum(s, sum) == false)
std::cout << "Bad CSV" << std::endl;

std::cout << "Sum is " << sum << std::endl;

1. Now we should remember to initialize correctly the startup value, otherwise we would get an unexpected result back.

No comments:

Post a Comment