_site/cover/scran_branch.COVER.html

1 %% Copyright (c) 2023 Peter Morgan <peter.james.morgan@gmail.com>
2 %%
3 %% Licensed under the Apache License, Version 2.0 (the "License");
4 %% you may not use this file except in compliance with the License.
5 %% You may obtain a copy of the License at
6 %%
7 %% http://www.apache.org/licenses/LICENSE-2.0
8 %%
9 %% Unless required by applicable law or agreed to in writing, software
10 %% distributed under the License is distributed on an "AS IS" BASIS,
11 %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 %% See the License for the specific language governing permissions and
13 %% limitations under the License.
14
15 %% @doc Parser combinators that deal with branches.
16
17 -module(scran_branch).
18
19 -feature(maybe_expr, enable).
20
21 -import(scran_sequence, [sequence/1]).
22 -export([alt/1]).
23 -export([permutation/1]).
24 -include_lib("kernel/include/logger.hrl").
25
26
27 %% @doc Try each alternative parser in turn until one returns other
28 %% than nomatch (or none from optional/conditional parsers).
29
30 -spec alt([scran:parser()]) -> scran:parser().
31
32 alt(Alternatives) ->
33 33 fun
34 (Input) ->
35 39 ?FUNCTION_NAME(Alternatives, Input)
36 end.
37
38
39 -spec alt([scran:parser()], scran:input()) -> scran:result().
40
41 alt([Alternative | Alternatives], Input) ->
42 67 ?LOG_DEBUG(#{alternative => scran_debug:pp(Alternative),
43 67 input => Input}),
44 67 case Alternative(Input) of
45 {_, none} ->
46 %% condition or optional parser that has returned none,
47 %% continue parsing with remaining alternatives.
48 3 ?LOG_DEBUG(#{nomatch => scran_debug:pp(Alternative)}),
49 3 ?FUNCTION_NAME(Alternatives, Input);
50
51 {_, _} = Result ->
52 30 Result;
53
54 nomatch ->
55 34 ?LOG_DEBUG(#{nomatch => scran_debug:pp(Alternative)}),
56 34 ?FUNCTION_NAME(Alternatives, Input)
57 end;
58
59 alt([], _) ->
60 9 nomatch.
61
62
63 %% @doc Try each permutation of the supplied parsers until one returns
64 %% other than nomatch.
65
66 -spec permutation([scran:parser()]) -> scran:parser().
67
68 permutation(Alternatives) ->
69 4 fun
70 (Input) ->
71 4 ?FUNCTION_NAME(permutations(Alternatives), Input)
72 end.
73
74
75 -spec permutation([[scran:parser()]], unicode:chardata()) -> scran:result().
76
77 permutation([Permutation | Permutations], Input) ->
78 7 maybe
79 7 {_, _} ?= (sequence(Permutation))(Input)
80
81 else
82 nomatch ->
83 4 ?FUNCTION_NAME(Permutations, Input)
84 end;
85
86 permutation([], _) ->
87 1 nomatch.
88
89
90 -spec permutations([scran:parser()]) -> [[scran:parser()]].
91
92 permutations([]) ->
93 8 [[]];
94
95 permutations(L) ->
96 12 [[H | T] || H <- L, T <- ?FUNCTION_NAME(L -- [H])].
Line Hits Source