Re: Parse succeeds, but doesn't propagate to first attribute with extra actions.
Henri Menke <[email protected]> Tue, 19 Nov 2019 20:17:15 +1300
| Newsgroups | gmane.comp.parsers.spirit.general |
|---|---|
| Message-ID | <[email protected]> |
Here is an alternative suggestion based on an answer by Seth on SO.
To this end I had to abandon the rule
(('=' >> bool_[bold]) | attr(true)[bold])
and replaced it with just
'=' >> bool_
together with setting those values to true in the default constructor.
This makes more sense to me and also keep the grammar much cleaner.
Cheers, Henri
---
#include <iostream>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/home/x3.hpp>
struct font {
std::string face_name;
size_t point = 0;
bool bold = true;
bool italic = true;
bool strike = true;
size_t id = 0;
};
BOOST_FUSION_ADAPT_STRUCT(font, face_name, point, bold, italic, strike, id)
namespace parsers {
// Thanks to the ingenious Seth!
// https://stackoverflow.com/a/49269239
auto const font_parser = boost::spirit::x3::rule<class _, font>{"font"} = [] {
using namespace boost::spirit::x3;
auto set = [](auto member, auto p) {
auto propagate = [member](auto& ctx) {
traits::move_to(_attr(ctx), _val(ctx).*(member));
};
return as_parser(p)[propagate];
};
auto const words = lexeme[+char_("a-zA-Z ")];
return lit("font(") >> set(&font::face_name, words)
>> *(
';'
>> (
lit("size") >> set(&font::point, '=' >> int_)
| lit("bold") >> set(&font::bold, '=' >> bool_)
| lit("italic") >> set(&font::italic, '=' >> bool_)
| lit("strike") >> set(&font::strike, '=' >> bool_)
)
);
}();
}
int main() {
font afont;
std::string target;
std::string test_str("font(Times New Roman;size=12;bold=true;italic);circle");
auto begin = test_str.begin();
phrase_parse(begin, test_str.end(), parsers::font_parser, boost::spirit::x3::space, afont);
std::cout << std::boolalpha
<< "face_name = " << afont.face_name << '\n'
<< "point = " << afont.point << '\n'
<< "bold = " << afont.bold << '\n'
<< "italic = " << afont.italic << '\n'
<< "strike = " << afont.strike << '\n';
return 0;
}
On 11/19/19 2:40 PM, Dan Bloomquist wrote:
> Dan Bloomquist wrote:
>> I started here. ...
>
> I'm gathering, even if I could not find it, that any semantic action
> will kill attribute propagation globally for the given target. At least,
> that is what I'm seeing. So, I just did it all with SA. The part where I
> make '= true/false' is verbose, I'm working on that. But this works.
> Best, Dan.
>
> #include <iostream>
> #include <boost/fusion/adapted/struct.hpp>
> #include <boost/spirit/home/x3.hpp>
> struct font {
> std::string face_name;
> size_t point=0;
> bool bold=false;
> bool italic = false;
> bool strike = false;
> size_t id=0;
> };
> namespace parsers {
> using namespace boost::spirit::x3;
> auto const face = [](auto& attr) { _val(attr).face_name =
> _attr(attr); };
> auto const point = [](auto& attr) { _val(attr).point = _attr(attr); };
> auto const bold = [](auto& attr) { _val(attr).bold = _attr(attr); };
> auto const italic = [](auto& attr) { _val(attr).italic =
> _attr(attr); };
> auto const strike = [](auto& attr) { _val(attr).strike =
> _attr(attr); };
>
> auto word = lexeme[+char_("a-zA-Z")];
> auto words = lexeme[+char_("a-zA-Z ")];
>
> auto font_parser = rule<struct _, font>() =
> lit("font(") >> words[face] >>
> *(
> lit("size") >> '=' >> int_[point]
> | lit("bold") >> (('=' >> bool_[bold]) | attr(true)[bold])
> | lit("italic") >> (('=' >> bool_[italic]) |
> attr(true)[italic])
> | lit("strike") >> (('=' >> bool_[strike]) |
> attr(true)[strike])
> ) % ';';
> }
> int main() {
> font afont;
> std::string target;
> std::string test_str("font(Times New
> Roman;size=12;bold=true;italic);circle");
> auto begin = test_str.begin();
> phrase_parse(begin, test_str.end(), parsers::font_parser,
> boost::spirit::x3::space, afont);
> return 0;
> }
>
>
> _______________________________________________
> Spirit-general mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/spirit-general
>
_______________________________________________
Spirit-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-general