Callbacks that receive the values produced during parsing and process them.

Callback

template <typename T>
concept callback_ = requires { typename T::return_type; }

template <typename T, typename ... Args>
concept callback-for = callback<T>
  && requires(const T& cb, Args&&... args) {
      { cb(std::forward<Args>(args)...) }
        -> std::same_as<typename T::return_type;
    };

template <typename T, typename Context, typename ... Args>
concept callback-with-context = callback<T>
  && requires(const T& cb, const Context& context) {
        { cb[context](std::forward<Args>(args)...) }
          -> std::same_as<typename T::return_type>;
     };

A callback is a function object with a return_type typedef that specifies its return type.

The callback can have multiple overloads of operator(), but all of them must return the same type. To be usable in the grammar, a callback must not have any mutable state.

A callback can optionally take a context. This is an additional parameter that is passed via operator[] in addition to all the arguments. During parsing, the callback arguments are the values produced by the rules while the context parameter is the parse state.

Sink

template <typename T>
concept sink-callback = requires (T& cb) {
      typename T::return_type;

      // there exist some args... with:
      { cb(args...) } -> std::same_as<void>;

      { std::move(cb).finish() } -> std::same_as<typename T::return_type>;
  };

template <typename T, typename ... Args>
concept sink = requires (const T& s, Args&&... args) {
      { s.sink(std::forward<Args>(args)...) } -> callback-sink;
  };

A sink is an object with a sink() member function that returns a sink callback, which is a callback that can be invoked multiples times before producing the final value.

The sink() member function can take arbitrary arguments to construct the sink callback. This is used to e.g. pass allocator parameters to a container’s constructor. During parsing, sink() is passed the parse state, if it accepts it, otherwise it is invoked without arguments.

The sink callback can be invoked with some arguments, and will somehow append them to the result. Calling finish() on the sink callback will return the finished result. Once finish() has been called, the sink callback is never used again. During parsing, the sink callback is repeatedly invoked by values produced during a list rule.

Pre-defined callbacks and sinks

Adapters and composition:
lexy::callback

Turn an overload set of function objects into a callback.

lexy::operator| and lexy::operator>>

Combine callbacks and sinks.

lexy::bind and lexy::bind_sink

Bind parameters and reorder and transform arguments of a callback or sink.

lexy::fold and lexy::fold_inplace

Fold over all arguments of a sink.

Primitives:
lexy::noop

Do nothing.

lexy::constant

Produce a constant value.

lexy::forward

Forward an existing value unchanged.

lexy::construct and lexy::new_

Construct a new object.

Rule specific:
lexy::as_integer

Produce a (signed) integer value.

lexy::as_string

Produce a string.

lexy::as_list and lexy::as_collection

Produce a container from all list items.

lexy::as_aggregate

Produce an aggregate by setting the specified members.