I am trying my hand at my first spirit parser and it seems like I have run into an attribute propagation issue. Trying a plantuml grammar. Damned if I hack it, damned if I do not...
The full gist is here: https://coliru.stacked-crooked.com/a/023ec430b509e1be
The essence of it, I think it this:
using ast_node = boost::variant<
ast_null,
ast_transition,
boost::recursive_wrapper<ast_state>,
boost::recursive_wrapper<ast_region>,
ast_machine
>;
using ast_nodes_t = std::vector<ast_node>;
struct ast_transition
{
//std::string _id;
std::string _fromState;
std::string _toState;
std::string _event;
std::string _guard;
std::string _effect;
};
BOOST_FUSION_ADAPT_STRUCT(
ast_transition,
//(std::string, _id)
(std::string, _fromState)
(std::string, _toState)
(std::string, _event)
(std::string, _guard)
(std::string, _effect)
)
struct ast_region
{
ast_nodes_t _subtree;
};
BOOST_FUSION_ADAPT_STRUCT(
ast_region,
(ast_nodes_t, _subtree)
)
// possible "fix" for "error: no type named 'value_type' in 'struct ast_region'" but causes infinite matching loop on region(s)
//region = eps >> *transition
region = *transition
;
bs::qi::rule<ITER, ast_transition(), SKIPPER> transition;
bs::qi::rule<ITER, ast_region(), SKIPPER> region;
bs::qi::rule<ITER, ast_nodes_t(), SKIPPER> regions;
Which gives:
/usr/local/include/boost/spirit/home/support/container.hpp:130:12: error: no type named 'value_type' in 'struct ast_region'
Any ideas how to massage the container attribute would be appreciated, thanks!
What I am trying to model from a plantuml state machine description:
- a state machine is a collection of regions
- a region is a collection of states & transitions
- a state is a collection of regions & transitions
I can only assume you have been leaving out code to account for the location tracking bases and iterator passing (I hope you're using
on_sucess, not juston_error).I simplified/reshaped things in order to review. In the end I think the only real change required seems to be the one you already had commented:
For rationale, see
Now the infinite loop indicates that
regionmatches the empty input. Since transition requires at leastrstringwhich requires at least a single character, you should be able to fix this by requiring at least one transition:I ended up with this example, which also fixes the debug-output in the most energy-efficient way I know how to:
Live On Compiler Explorer
Printing