aboutsummaryrefslogtreecommitdiffstats
path: root/system/doc/programming_examples/funparse.erl
blob: 5e23c90df98c73164318a48372979dfc1f6f103b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
-module(funparse).
-compile(export_all).
-import(lists, [reverse/1]).

%17
%% > hof:parse([a,c]).
%% {ok,{'and',{'or',1,{const,a}},{'or',1,{const,c}}}}
%% > hof:parse([a,d]). 
%% {ok,{'and',{'or',1,{const,a}},{'or',2,{const,d}}}}
%% > hof:parse([b,c]).   
%% {ok,{'and',{'or',2,{const,b}},{'or',1,{const,c}}}}
%% > hof:parse([b,d]). 
%% {ok,{'and',{'or',2,{const,b}},{'or',2,{const,d}}}}
%% > hof:parse([a,b]).   
%% fail
%17

%% Grammar = (a | b) & (c | d)

%12
parse(List) ->
    (grammar())(List).
%12

%13
grammar() ->
    pand(
         por(pconst(a), pconst(b)),
         por(pconst(c), pconst(d))).
%13

%14
pconst(X) ->
    fun (T) ->
       case T of
           [X|T1] -> {ok, {const, X}, T1};
           _      -> fail
       end
    end.
%14

%15
por(P1, P2) ->
    fun (T) ->
        case P1(T) of
            {ok, R, T1} -> 
                {ok, {'or',1,R}, T1};
            fail -> 
                case P2(T) of
                    {ok, R1, T1} ->
                        {ok, {'or',2,R1}, T1};
                    fail ->
                        fail
                end
        end
    end.
%15

%16
pand(P1, P2) ->
    fun (T) ->
        case P1(T) of
            {ok, R1, T1} ->
                case P2(T1) of
                    {ok, R2, T2} ->
                        {ok, {'and', R1, R2}};
                    fail ->
                        fail
                end;
            fail ->
                fail
        end
    end.
%16