x3 beginner semantic actions
Patrick Welche <[email protected]> Tue, 24 Apr 2018 15:48:13 +0100
| Newsgroups | gmane.comp.parsers.spirit.general |
|---|---|
| Message-ID | <20180424144813.GA19902@quark> |
In a bid to understand semantic actions a bit better, I thought I would
try to write an x3 program to count the number of + and - (think heads
and tails) in a sequence. The aim was to see:
1) how to deal with matching on a char, but wanting to use an int as attribute,
i.e., not the expected type of attribute.
2) how to select which int buried inside a struct to use
3) how to initialise said int
1) might be doable with e.g.
auto const head
= rule<class _, int, true>
= lit('+') // [addhead]
;
2) given that toss is int or int, it is just an int, so presumably
tosses.heads always gets sent to head or tail?
3) I don't see how to not overwrite the result with the initialisation
Presumably this is just the wrong way of looking at it. (I don't want to
"cheat" and have external variables which the lambda change directly -
or is that the only way?)
Cheers,
Patrick
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Spirit-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-general
coin.cpp
(text/plain, 1.5 KB)
#define BOOST_SPIRIT_X3_DEBUG
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
struct tosses {
int heads;
int tails;
};
BOOST_FUSION_ADAPT_STRUCT(tosses, heads, tails)
int main()
{
std::string buf("++--+-++++-");
auto iter = buf.begin(), end = buf.end();
auto peek = [&](auto& ctx){
std::cout << "peek["
<< boost::spirit::x3::_attr(ctx)
<< ']' << std::endl;
};
auto zerotosses = [&](auto& ctx){
boost::spirit::x3::_attr(ctx)=0;
};
auto addhead = [&](auto& ctx){
boost::spirit::x3::_val(ctx)++;
};
auto addtail = [&](auto& ctx){
boost::spirit::x3::_val(ctx)--;
};
auto parser = [&]{
using namespace boost::spirit::x3;
auto const head
= lit('+') // [addhead]
;
auto const tail
= lit('-') // [addtail]
;
auto const toss
= head | tail
;
auto const tosses
= +toss
;
return rule<struct _, struct tosses> {"parser"} = skip(space) [ tosses ];
};
tosses res;
boost::spirit::x3::ascii::space_type space;
bool ok = boost::spirit::x3::phrase_parse(iter, end, parser(), space, res);
if (ok) {
std::cout << "Parse success\n";
}
else {
std::cout << "Parsing failed\n";
}
if (iter != end) {
std::cout << "Bit left over at the end: " << std::string(iter, end) << std::endl;
}
else {
std::cout << "heads: " << res.heads << std::endl
<< "tails: " << res.tails << std::endl;
}
return 0;
}