Search code examples
c++boostboost-proto

Non-default constructed boost::proto terminal


I'm trying to define a very limited parser combinator library using boost::proto and was wondering if it's by any means possible to define a non-default constructed proto terminal.

I have a structure like this:

struct symbol
{
   symbol(const string &str): str_(str) {}
   bool operator()(const string &str) const {
      return (str == str_);
   }

   string str_;
};

that I'd like to use as a boost proto terminal in proto expressions. I was able to get it to work with the help of BOOST_PROTO_DEFINE_OPERATORS, but I find it somewhat inconvenient to frequently have to wrap it in a proto::lit() inside proto expressions:

match(symbol("abc") >> (proto::lit(symbol("xyz")) | symbol("klm")))

I was wondering if I could create a proto terminal like this:

proto::terminal<symbol>::type sym;

that would somehow be able to take a string argument and pass it to the constructor of symbol.

Note: I know about Spirit, but my compiler doesn't quite support it!


Solution

  • You can make the name sym a function that returns a terminal:

    proto::terminal<symbol>::type sym(std::string const& s)
    { return { symbol(s) }; }
    

    much like lit is a function template that turns its parameter into a terminal.