0

I have some C++ code that uses Boost Qi and Phoenix to parse command line parameters. The following code worked fine with Boost 1.56.

namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
using boost::spirit::repository::distinct;

int type;
unsigned pause, siteID;
bool testMode, log;
std::string filePath;

auto fileName = qi::lexeme[+qi::char_("0-9a-zA-Z_/.:")];
auto grammar = boost::proto::deep_copy(
    distinct(qi::alpha)["/pause="][phx::ref(type) = 0] >> qi::uint_[phx::ref(pause) = qi::_1] |
    distinct(qi::alpha)["/id="][phx::ref(type) = 1] >> qi::uint_[phx::ref(siteID) = qi::_1] |
    distinct(qi::alpha)["/testmode="][phx::ref(type) = 2] >> qi::uint_[phx::ref(testMode) = (qi::_1 != FALSE)] |
    distinct(qi::alpha)["/log="][phx::ref(type) = 3] >> qi::uint_[phx::ref(log) = (qi::_1 != FALSE)] |
    distinct(qi::alpha)["/ini="][phx::ref(type) = 4] >> fileName[phx::ref(filePath) = qi::_1]
);

Recently I moved to Boost 1.71, but now I get the following compile time errors, all from boost.1.71.0.0\lib\native\include\boost\proto\transform\default.hpp, line 154:

Error C2955 'boost::type': use of class template requires template argument list
Error C2955 'boost::mpl::if_c': use of class template requires template argument list
Error C2679 binary '=': no operator found which takes a right-hand operand of type 'T' (or there is no acceptable conversion)
Error C2672 'boost::proto::detail::check_reference': no matching overloaded function
Error C2238 unexpected token(s) preceding ';'
Error C2062 type 'unknown-type' unexpected
Error C2039 'type': is not a member of 'boost::proto::detail::default_assign<Grammar>::impl<Expr     &,State,Data>::nested_and_hidden_nested_result_type'
Error C2039 'type': is not a member of 'boost::proto::detail::default_assign<Grammar>::impl<Expr &,State,Data>::nested_result_type'

I've worked out the issue is the code fileName[phx::ref(filePath) = qi::_1]. phx::ref can no longer assign the value of qi::_1 when _1 is the result of a sub-expression.

qi::uint_[phx::ref(pause) = qi::_1] \\ This is fine
fileName[phx::ref(filePath) = "test"] \\ This is fine
fileName[phx::ref(filePath) = qi::_1] \\ Compile error

How can I fix this? Thanks

B-Dawg
  • 13
  • 3
  • Can you try setting the type of `filePath` to `std::vector` and then check whether it compiles? – llonesmiz Jan 20 '20 at 09:39
  • Thanks @llonesmiz. Yes that works, then I can use std::string(filePath.begin(), filePath.end()) to get the string.Is there a more elegant way to do this conversion within the grammar? – B-Dawg Jan 20 '20 at 22:41
  • I think [this](https://www.boost.org/libs/spirit/doc/html/spirit/qi/reference/directive/as.html) might be useful for the definition of `filePath`. – llonesmiz Jan 21 '20 at 07:08
  • I tried qi::as_string, but this also causes a compile time error. – B-Dawg Jan 22 '20 at 00:57
  • `boost::any_cast(qi::_1)` compiles ok though – B-Dawg Jan 22 '20 at 01:03
  • I meant `auto fileName = qi::as_string[qi::lexeme[+qi::char_("0-9a-zA-Z_/.:")]];`. – llonesmiz Jan 22 '20 at 04:44

0 Answers0