-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdfa.erl
58 lines (46 loc) · 1.31 KB
/
dfa.erl
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
% $ erlc dfa.erl
% $ erl -noshell -s dfa start -s init stop
% a => false
% baa => false
% baba => true
-module(dfa).
-export([start/0]).
appliesTo({rule, State0, Character0, _}, State1, Character1) ->
(State0 == State1) and (Character0 == Character1).
follow({rule, _, _, NextState}) ->
NextState.
ruleFor([Rule|Rules], State, Character) ->
case appliesTo(Rule, State, Character) of
true -> Rule;
false -> ruleFor(Rules, State, Character)
end.
nextState(Rules, State, Character) ->
Rule = ruleFor(Rules, State, Character),
follow(Rule).
isAccepting({dfa, State, AcceptStates, _}) ->
lists:member(State, AcceptStates).
readCharacter(DFA, Character) ->
{dfa, State0, AcceptStates, Rules} = DFA,
State1 = nextState(Rules, State0, Character),
{dfa, State1, AcceptStates, Rules}.
readString(DFA, "") ->
DFA;
readString(DFA, [C|CS]) ->
DFA2 = readCharacter(DFA, C),
readString(DFA2, CS).
isAccepts(DFA, String) ->
DFA1 = readString(DFA, String),
isAccepting(DFA1).
rules() -> [
{rule, 1, $a, 2}, {rule, 1, $b, 1},
{rule, 2, $a, 2}, {rule, 2, $b, 3},
{rule, 3, $a, 3}, {rule, 3, $b, 3}
].
test(DFA, String) ->
io:format("~s => ~p~n", [String, isAccepts(DFA, String)]).
start() ->
Rules = rules(),
DFA = {dfa, 1, [3], Rules},
test(DFA, "a"),
test(DFA, "baa"),
test(DFA, "baba").