I am trying to parse a PDDL file with Boost::Spirit and have some trouble with parsing preconditions into a struct. I am struggling to understand the Boost manual on how to get the condition into my struct and with recursion.
I give a snippet of the code below, that should illustrate the problem well. A string that looks like this has to be parsed:
:precondition
(and
(at-pos ?r ?pos)
(not (has-pos ?m ?pos))
)
My code so far looks like this, but I am almost sure I did not understand how at_c works having no experience with Boost::Phoenix yet.
predi_param = '?' >> name_type;
predi = '('
>> name_type
>> +predi_param
>> ')';
literal = (
( '(' >> lit("not") >>
predi [at_c<0>(_val) = false]
>> ')'
)
| predi [at_c<0>(_val) = true]
)
>> ')';
pred_list = ( '(' >> lit("and") >> (*pred_list) >> ')')
| literal;
preconditions = lit(":precondition") >> pred_list;
qi::rule<Iterator, std::string(), ascii::space_type> predi_param;
qi::rule<Iterator, Predicate(), ascii::space_type> predi;
qi::rule<Iterator, Literal(), ascii::space_type> literal;
qi::rule<Iterator, std::vector<Literal>(), ascii::space_type> preconditions, pred_list;
My AST looks like this:
struct Predicate
{
std::string name;
std::vector<std::string> predicate_params;
};
struct Literal
{
bool condition;
Predicate predicate;
};
BOOST_FUSION_ADAPT_STRUCT(
pddl_parser::Literal,
(bool, condition)
(pddl_parser::Predicate, predicate)
)
BOOST_FUSION_ADAPT_STRUCT(
pddl_parser::Predicate,
(std::string, name)
(std::vector<std::string>, predicate_params)
)
Compiling this results in a compilation error:
parser.cpp:67:17: required from ‘pddl_parser::domain_parser<Iterator>::domain_parser() [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >]’
parser.cpp:136:10: required from here
/usr/include/boost/spirit/home/qi/detail/assign_to.hpp:153:20: error: no matching function for call to ‘pddl_parser::Literal::Literal(const std::vector<pddl_parser::Literal>&)’
attr = static_cast<Attribute>(val);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from parser.cpp:11:0:
./pddlast.h:23:10: note: candidate: pddl_parser::Literal::Literal()
struct Literal
^~~~~~~
./pddlast.h:23:10: note: candidate expects 0 arguments, 1 provided
./pddlast.h:23:10: note: candidate: pddl_parser::Literal::Literal(const pddl_parser::Literal&)
./pddlast.h:23:10: note: no known conversion for argument 1 from ‘const std::vector<pddl_parser::Literal>’ to ‘const pddl_parser::Literal&’
./pddlast.h:23:10: note: candidate: pddl_parser::Literal::Literal(pddl_parser::Literal&&)
./pddlast.h:23:10: note: no known conversion for argument 1 from ‘const std::vector<pddl_parser::Literal>’ to ‘pddl_parser::Literal&&’
If I reformat the pred_list for test purposes into pred_list = ( '(' >> *literal) >> ')'); the code compiles but still yields no success, although I take the (and ) out. I have the impression I have something totally wrong, but cannot find anything. This is my first try using Boost::Spirit.