139 lines
4.7 KiB
Plaintext
139 lines
4.7 KiB
Plaintext
[section Preface]
|
|
|
|
[section Description]
|
|
|
|
Metaparse is a compile-time parser generator library. Metaparse provides tools
|
|
to write parsers parsing the content of string literals at compile-time, which
|
|
makes it possible to embed domain specific languages (DSLs) into C++ without
|
|
altering their original syntax (Note that the DSL code snippets will be written
|
|
in string literals, therefore they may need to be escaped).
|
|
|
|
Assuming that the following template class is available for representing
|
|
rational numbers in template metaprogramming:
|
|
|
|
template <class Num, class Denom>
|
|
struct rational;
|
|
|
|
Metaparse can be used to construct such values (instantiate the `rational`
|
|
template class) from string literals. Instead of `rational<1, 3>` one can write
|
|
`RATIONAL("1/3")` which can be processed by any standard-compliant C++11
|
|
compiler (and mean the same). This can be implemented using Metaparse the
|
|
following way:
|
|
|
|
using namespace boost::metaparse;
|
|
|
|
typedef
|
|
sequence_apply2<
|
|
rational,
|
|
|
|
token<int_>,
|
|
last_of<lit_c<'/'>, token<int_>>
|
|
>
|
|
rational_grammar;
|
|
|
|
typedef build_parser<entire_input<rational_grammar>> rational_parser;
|
|
|
|
#define RATIONAL(s) \
|
|
(::rational_parser::apply<BOOST_METAPARSE_STRING(s)>::type::run())
|
|
|
|
Note that this is the entire implementation. Also note that this implementation
|
|
can be extended to improve the error reports in certain situations.
|
|
|
|
[endsect]
|
|
|
|
|
|
|
|
[section Scope]
|
|
|
|
Metaparse is intended to be used by library authors to make their APIs follow
|
|
the usual notation of the library's problem domain.
|
|
|
|
[section Comparsion to Boost.Proto]
|
|
|
|
Boost.Proto is a tool for building expression templates. Expression templates
|
|
can be used for DSL embedding by reinterpreting valid C++ expressions as
|
|
expressions written in the DSL to embed.
|
|
|
|
This technique has the advantages over parsing the content of string literals
|
|
(which is Metaparse's approach) that:
|
|
|
|
* is faster in most cases
|
|
* APIs using this technique can "emerge" as a process of advancing the API of a
|
|
library step-by-step. Moving to a completely new DSL (with its own syntax) is
|
|
a relatively big step.
|
|
|
|
Using expression templates for DSL embedding has the following disadvantages:
|
|
|
|
* the syntax of the embedded DSL is limited. It has to be a valid C++
|
|
expression. For most libraries, people familiar with the original DSL usually
|
|
need to learn the library's syntax to understand the embedded code snippets.
|
|
|
|
Proto helps embedding DSLs based on expression templates, while Metaparse helps
|
|
embedding DSLs based on parsing the content of string literals.
|
|
|
|
[endsect]
|
|
|
|
[section Comparison to Boost.Spirit]
|
|
|
|
Spirit is a tool that can be used to build parsers parsing (among others) the
|
|
content of string literals at runtime, while Metaparse is a tool that can be
|
|
used to parse the content of string literals at compile-time.
|
|
|
|
[endsect]
|
|
|
|
[endsect]
|
|
|
|
[section Advantages of using this library]
|
|
|
|
This library is useful to provide an API for C++ libraries dealing with a
|
|
problem domain with its own notation. Interfaces built with Metaparse make it
|
|
possible for the users of the interface to use the domain's own notation, which
|
|
makes it easier to write and maintain the code. Users of the interface don't
|
|
need to learn a new notation (trying to follow the problem domain's original
|
|
one) library authors constrained by the C++ syntax can provide. Example problem
|
|
domains are regular expressions and SQL queries.
|
|
|
|
Metaparse can also be useful to build libraries validating the content of string
|
|
literals at compile time instead of doing it at runtime or not doing it at all.
|
|
This can help finding (and fixing) bugs in the code early (during compilation).
|
|
An example problem domain is `printf`.
|
|
|
|
[endsect]
|
|
|
|
[section Cost of using Metaparse]
|
|
|
|
The parsers built with Metaparse process the content of the string literals
|
|
using template metaprograms. This impacts the library using Metaparse the
|
|
following way:
|
|
|
|
* The maintainer of the API built with Metaparse will need to understand
|
|
template metaprogramming.
|
|
* The content of the string literals will be (re)parsed during every
|
|
compilation. This will impact the compiler's memory consumption and the
|
|
compilation speed.
|
|
* The users of the library will receive the error reports coming from the
|
|
parsers as template error messages of their compiler. (Note that Metaparse
|
|
actively tries improving their quality and provides
|
|
[link dealing_with_invalid_input tools] for parser authors).
|
|
|
|
[endsect]
|
|
|
|
|
|
[section Supported platforms]
|
|
|
|
Metaparse is based on C++98. The only exception is the
|
|
[link BOOST_METAPARSE_STRING] macro, which needs C++11 `constexpr`.
|
|
|
|
Compilers Metaparse is actively (in a CI environment) tested on:
|
|
|
|
* GCC 4.6, 4.7, 4.8, 4.9
|
|
* Clang 3.4, 3.5, 3.6
|
|
* Visual C++ 2015
|
|
|
|
Metaparse is expected to work on Visual C++ 2012 and 2010.
|
|
|
|
[endsect]
|
|
|
|
[endsect]
|
|
|