Compile time (LR) type safe parser generator for C++
A parser is defined using the LrParser class. An LrParser type takes a variadic number of template arguments, where each argument is a Production type. A Production type takes 3 arguments:
- A nonterminal (See "Nonterminals" for more information)
- A std::tuple-type, which takes a variable number of nonterminals and terminals
- A semantic action, which is something that is calleble (See "Semantic Actions" for more information)
using namespace parse;
using d = Terminal<0>;
using c = Terminal<1>;
using a = Terminal<2>;
using Parser = LrParser<
Production<
Z,
std::tuple<d>,
Rule1
>,
Production<
Z,
std::tuple<X, Y, Z>,
Rule2
>,
Production<
Y,
std::tuple<>,
Rule3
>,
Production<
Y,
std::tuple<c>,
Rule4
>,
Production<
X,
std::tuple<Y>,
Rule5
>,
Production<
X,
std::tuple<a>,
Rule6
>
>;A Nonterminal class A must obey the following:
Amust publically derive fromNonterminal<A>
A Terminal must obey the following:
- Must have type
Terminal<n>, wherenis an integer that satisfies that two terminalsTerminal<n>andTerminal<m>are equal if and only ifn == m. These Terminal-types model token classes returned from some lexer.
A semantic action R valid if and only if:
- Given a
Productionof the following form
Production<
A,
std::tuple<B1, B2, ..., BN>,
R
>then an instance of type R is callable with arguments b1, b2, ..., bN, (where decltype(bi) = Bi) and the result of R{}(b1, b2, ..., bN) is of type A.
- The number of rows or columns in the LR parsing table can be no more than
BOOST_PP_LIMIT_REPEAT, which sadly is a very real limitation when parsing complex languages. - Due to the amount of template meta-programming used within the library, the compile time can be quite long
