]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [section Preface] |
2 | ||
3 | [section Description] | |
4 | ||
5 | Metaparse is a compile-time parser generator library. Metaparse provides tools | |
6 | to write parsers parsing the content of string literals at compile-time, which | |
7 | makes it possible to embed domain specific languages (DSLs) into C++ without | |
8 | altering their original syntax (Note that the DSL code snippets will be written | |
9 | in string literals, therefore they may need to be escaped). | |
10 | ||
11 | Assuming that the following template class is available for representing | |
12 | rational numbers in template metaprogramming: | |
13 | ||
14 | template <class Num, class Denom> | |
15 | struct rational; | |
16 | ||
17 | Metaparse can be used to construct such values (instantiate the `rational` | |
18 | template class) from string literals. Instead of `rational<1, 3>` one can write | |
19 | `RATIONAL("1/3")` which can be processed by any standard-compliant C++11 | |
20 | compiler (and mean the same). This can be implemented using Metaparse the | |
21 | following way: | |
22 | ||
23 | using namespace boost::metaparse; | |
24 | ||
25 | typedef | |
26 | sequence_apply2< | |
27 | rational, | |
28 | ||
29 | token<int_>, | |
30 | last_of<lit_c<'/'>, token<int_>> | |
31 | > | |
32 | rational_grammar; | |
33 | ||
34 | typedef build_parser<entire_input<rational_grammar>> rational_parser; | |
35 | ||
36 | #define RATIONAL(s) \ | |
37 | (::rational_parser::apply<BOOST_METAPARSE_STRING(s)>::type::run()) | |
38 | ||
39 | Note that this is the entire implementation. Also note that this implementation | |
40 | can be extended to improve the error reports in certain situations. | |
41 | ||
42 | [endsect] | |
43 | ||
44 | ||
45 | ||
46 | [section Scope] | |
47 | ||
48 | Metaparse is intended to be used by library authors to make their APIs follow | |
49 | the usual notation of the library's problem domain. | |
50 | ||
51 | [section Comparsion to Boost.Proto] | |
52 | ||
53 | Boost.Proto is a tool for building expression templates. Expression templates | |
54 | can be used for DSL embedding by reinterpreting valid C++ expressions as | |
55 | expressions written in the DSL to embed. | |
56 | ||
57 | This technique has the advantages over parsing the content of string literals | |
58 | (which is Metaparse's approach) that: | |
59 | ||
60 | * is faster in most cases | |
61 | * APIs using this technique can "emerge" as a process of advancing the API of a | |
62 | library step-by-step. Moving to a completely new DSL (with its own syntax) is | |
63 | a relatively big step. | |
64 | ||
65 | Using expression templates for DSL embedding has the following disadvantages: | |
66 | ||
67 | * the syntax of the embedded DSL is limited. It has to be a valid C++ | |
68 | expression. For most libraries, people familiar with the original DSL usually | |
69 | need to learn the library's syntax to understand the embedded code snippets. | |
70 | ||
71 | Proto helps embedding DSLs based on expression templates, while Metaparse helps | |
72 | embedding DSLs based on parsing the content of string literals. | |
73 | ||
74 | [endsect] | |
75 | ||
76 | [section Comparison to Boost.Spirit] | |
77 | ||
78 | Spirit is a tool that can be used to build parsers parsing (among others) the | |
79 | content of string literals at runtime, while Metaparse is a tool that can be | |
80 | used to parse the content of string literals at compile-time. | |
81 | ||
82 | [endsect] | |
83 | ||
84 | [endsect] | |
85 | ||
86 | [section Advantages of using this library] | |
87 | ||
88 | This library is useful to provide an API for C++ libraries dealing with a | |
89 | problem domain with its own notation. Interfaces built with Metaparse make it | |
90 | possible for the users of the interface to use the domain's own notation, which | |
91 | makes it easier to write and maintain the code. Users of the interface don't | |
92 | need to learn a new notation (trying to follow the problem domain's original | |
93 | one) library authors constrained by the C++ syntax can provide. Example problem | |
94 | domains are regular expressions and SQL queries. | |
95 | ||
96 | Metaparse can also be useful to build libraries validating the content of string | |
97 | literals at compile time instead of doing it at runtime or not doing it at all. | |
98 | This can help finding (and fixing) bugs in the code early (during compilation). | |
99 | An example problem domain is `printf`. | |
100 | ||
101 | [endsect] | |
102 | ||
103 | [section Cost of using Metaparse] | |
104 | ||
105 | The parsers built with Metaparse process the content of the string literals | |
106 | using template metaprograms. This impacts the library using Metaparse the | |
107 | following way: | |
108 | ||
109 | * The maintainer of the API built with Metaparse will need to understand | |
110 | template metaprogramming. | |
111 | * The content of the string literals will be (re)parsed during every | |
112 | compilation. This will impact the compiler's memory consumption and the | |
113 | compilation speed. | |
114 | * The users of the library will receive the error reports coming from the | |
115 | parsers as template error messages of their compiler. (Note that Metaparse | |
116 | actively tries improving their quality and provides | |
117 | [link dealing_with_invalid_input tools] for parser authors). | |
118 | ||
119 | [endsect] | |
120 | ||
121 | ||
122 | [section Supported platforms] | |
123 | ||
124 | Metaparse is based on C++98. The only exception is the | |
125 | [link BOOST_METAPARSE_STRING] macro, which needs C++11 `constexpr`. | |
126 | ||
127 | Compilers Metaparse is actively (in a CI environment) tested on: | |
128 | ||
129 | * GCC 4.6, 4.7, 4.8, 4.9 | |
130 | * Clang 3.4, 3.5, 3.6 | |
131 | * Visual C++ 2015 | |
132 | ||
133 | Metaparse is expected to work on Visual C++ 2012 and 2010. | |
134 | ||
135 | [endsect] | |
136 | ||
137 | [endsect] | |
138 |