and

Basic operator: it matches if all its subrules (stored in the rules template parameter tuple) match the input successively. Its subrules parse trees are stored as its children and its matches field will contain all its subrules matches, in order.

1 alias and!(literal!"abc", charRange!('a','z')) rule; // abc followed by any letter between a and z.
2 ParseTree input = ParseTree("",false,[],"abcd"); // low-level plumbing,
3                                                  // the rules described here act on ParseTree's not strings.
4                                                  // It's equivalent to "abcd" as input
5 auto result = rule(input);
6 
7 assert(result.successful); // OK, 'abc' followed by 'd'
8 assert(result.matches == ["abc", "d"]); // stores the matches
9 assert(result.children.length == 2); // two children, the result of "abc" on "abcd" and the result of [a-z] on "d"
10 
11 input.input = "abc"; // changing the input string;
12 assert(!rule(input)).successful); // NOK, abc alone
13 input.input = "ab";
14 assert(!rule(input)).successful); // NOK, does not begin by abc

If it fails, the last children will contain the failed node. That way, when printing, as sort of diagnostic is given:

1 alias and!(literal!"abc", charRange!('a','z')) rule; // 'abc[a-z]', aka 'abc' followed by any letter between 'a' and 'z'.
2 ParseTree input = ParseTree("",false,[],"abc1"); // equivalent to "abc1"
3 
4 auto failure = rule(input);
5 writeln(failure);
6 /+
7 writes:
8 and (failure)
9  +-literal(abc) [0, 3]["abc"]
10  +-charRange(a,z) failure at line 0, col 3, after "abc" a char between 'a' and 'z', but got "1"
11 +/

So we know the global 'and' failed, that the first sub-rule ('abc') succeeded on input[0..3] with "abc" and that the second subrule ('[a-z]') failed at position 3 (so, on '1').

template and(rules...)
and
if (
rules.length > 0
)

Meta