4

I'm practicing template programming in C++, trying to implement some kind of parser library for educational purposes using only templates.

an example of how my library is supposed to be used is :

std::stringstream ss { "identif1er 123123 hell0 world 3rror" };

// zM = zero or more , aO = any of

using Identifier = Matcher<Alpha, zM<AlphaNum>>;
using Number = Matcher<Digit, zM<Digit>>; 

Matcher<aO<Identifier, Number>> numberOrIdentifier;

while(!ss.eof()) {
    if(ss.peek() == ' ') ss.ignore(1);

    if(numberLetters.s_match(ss)) {
        std::cout << "Token: " << (*numberLetters.val) << std::endl;
    } else {
        std::cout << "Error\n";
    }
}

this is working, but I encountered with the problem that sometimes ill have to define a pair of types that depends on the other and vise versa.

I just want to know how i can do for example this:

using Expr = Matcher<..... Factor ....>
using Factor = Matcher<aO<Number, Expr>>;

How can i do a forward declaration of Factor using only types and no constructor arguments? its posible?, note: im using a empty struct "Self" to tag the recursion.

Link to the definition of the templates :

templates code

alter
  • 333
  • 4
  • 14
  • 1
    This can't be possible for the following reason: Fundamentally, these are only aliases, so they have to expand to a type without aliases. What should this type be? If you simplyfy your example to `using Expr = Matcher; using Factor = Matcher>;` the resulting type would need to look like `using Expr = Matcher – Corristo Oct 28 '16 at 20:33
  • So to get this to work, you need to implement some form of compile time simplification, in this case for the rule that `Expr ::= Number | Expr` is equivalent to `Expr ::= Number`. – Corristo Oct 28 '16 at 20:43

0 Answers0