zeroOrMore

Tries to match subrule 'r' zero or more times. It always succeeds, since if 'r' fails from the very beginning, it matched 'r' zero times...

Its matches are those of its subrules (they might be different for each match) and its children are all the parse trees returned by the successive application of 'r'.

1 alias zeroOrMore!(or!(literal!"abc", literal!"d")) rule; // in PEG-speak:  '("abc" / "d")*'
2 ParseTree input = ParseTree("",false,[], "abcdabce");
3 
4 ParseTree result = rule(input);
5 
6 assert(result.successful);
7 assert(result.matches == ["abc", "d", "abc"]);
8 assert(result.end == 7); // matched "abcdabce"[0..7] => "abcdabc". "e" at the end is not part of the parse tree.
9 assert(result.children.length == 3);
10 writeln(result);
11 /+
12 writes:
13 zeroOrMore  [0, 7]["abc", "d", "abc"]
14  +-or  [0, 3]["abc"]
15  |  +-literal(abc)  [0, 3]["abc"]
16  +-or  [3, 4]["d"]
17  |  +-literal(d)  [3, 4]["d"]
18  +-or  [4, 7]["abc"]
19     +-literal(abc)  [4, 7]["abc"]
20 +/

So we know the first child used the 'literal!"abc"' sub-rule and matched input[0..3]. The second matched input[3..4] and the third input[4..7].

input = ParseTree("",false,[], "efgh");
result = rule(input);
assert(result.successful); // succeed, even though all patterns failed.
assert(result.children.length == 0);
template zeroOrMore(alias r)
zeroOrMore

Meta