Current section
Files
Jump to
Current section
Files
src/rexen@nfa@machine.erl
-module(rexen@nfa@machine).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/rexen/nfa/machine.gleam").
-export([new/0, set_initial_state/2, set_ending_states/2, add_state/2, declare_states/2, add_transition/4, evaluate/2]).
-export_type([n_f_a/0, node_/0]).
-type n_f_a() :: {n_f_a,
gleam@dict:dict(binary(), rexen@nfa@state:state()),
binary(),
list(binary())}.
-type node_() :: {node, integer(), rexen@nfa@state:state()}.
-file("src/rexen/nfa/machine.gleam", 15).
-spec new() -> n_f_a().
new() ->
{n_f_a, maps:new(), <<""/utf8>>, []}.
-file("src/rexen/nfa/machine.gleam", 19).
-spec set_initial_state(n_f_a(), binary()) -> n_f_a().
set_initial_state(Nfa, State) ->
{n_f_a, erlang:element(2, Nfa), State, erlang:element(4, Nfa)}.
-file("src/rexen/nfa/machine.gleam", 27).
-spec set_ending_states(n_f_a(), list(binary())) -> n_f_a().
set_ending_states(Nfa, Values) ->
{n_f_a, erlang:element(2, Nfa), erlang:element(3, Nfa), Values}.
-file("src/rexen/nfa/machine.gleam", 35).
-spec add_state(n_f_a(), binary()) -> n_f_a().
add_state(Nfa, Name) ->
{n_f_a,
gleam@dict:insert(
erlang:element(2, Nfa),
Name,
rexen@nfa@state:new(Name)
),
erlang:element(3, Nfa),
erlang:element(4, Nfa)}.
-file("src/rexen/nfa/machine.gleam", 43).
-spec declare_states(n_f_a(), list(binary())) -> n_f_a().
declare_states(Nfa, Names) ->
case Names of
[] ->
Nfa;
[Name | Rest] ->
declare_states(add_state(Nfa, Name), Rest)
end.
-file("src/rexen/nfa/machine.gleam", 50).
-spec add_transition(n_f_a(), binary(), binary(), rexen@nfa@state:matcher()) -> n_f_a().
add_transition(Nfa, From, To, Matcher) ->
From_state@1 = case gleam_stdlib:map_get(erlang:element(2, Nfa), From) of
{ok, From_state} -> From_state;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"rexen/nfa/machine"/utf8>>,
function => <<"add_transition"/utf8>>,
line => 56,
value => _assert_fail,
start => 1127,
'end' => 1181,
pattern_start => 1138,
pattern_end => 1152})
end,
case gleam_stdlib:map_get(erlang:element(2, Nfa), To) of
{ok, _} -> nil;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"rexen/nfa/machine"/utf8>>,
function => <<"add_transition"/utf8>>,
line => 57,
value => _assert_fail@1,
start => 1184,
'end' => 1227,
pattern_start => 1195,
pattern_end => 1200})
end,
Transitions = rexen@nfa@state:add_transition(
erlang:element(3, From_state@1),
{Matcher, To}
),
New_state = {state, erlang:element(2, From_state@1), Transitions},
{n_f_a,
gleam@dict:insert(erlang:element(2, Nfa), From, New_state),
erlang:element(3, Nfa),
erlang:element(4, Nfa)}.
-file("src/rexen/nfa/machine.gleam", 132).
-spec process_transitions(
n_f_a(),
list({rexen@nfa@state:matcher(), binary()}),
integer(),
gleam@set:set(node_()),
list(node_()),
binary()
) -> list(node_()).
process_transitions(Nfa, Transitions, Index, Visited_nodes, Pending_nodes, Char) ->
case Transitions of
[] ->
Pending_nodes;
[{Matcher, Name} | Rest] ->
case rexen@nfa@state:matches(Matcher, Char) of
false ->
process_transitions(
Nfa,
Rest,
Index,
Visited_nodes,
Pending_nodes,
Char
);
true ->
To@1 = case gleam_stdlib:map_get(
erlang:element(2, Nfa),
Name
) of
{ok, To} -> To;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"rexen/nfa/machine"/utf8>>,
function => <<"process_transitions"/utf8>>,
line => 155,
value => _assert_fail,
start => 3629,
'end' => 3675,
pattern_start => 3640,
pattern_end => 3646})
end,
New_node = case rexen@nfa@state:is_epsilon(Matcher) of
true ->
{node, Index, To@1};
false ->
{node, Index + 1, To@1}
end,
Nodes = case gleam@set:contains(Visited_nodes, New_node) of
true ->
Pending_nodes;
false ->
lists:append(Pending_nodes, [New_node])
end,
process_transitions(
Nfa,
Rest,
Index,
Visited_nodes,
Nodes,
Char
)
end
end.
-file("src/rexen/nfa/machine.gleam", 82).
-spec evaluate_loop(n_f_a(), binary(), list(node_()), gleam@set:set(node_())) -> boolean().
evaluate_loop(Nfa, Input, Nodes, Visited_nodes) ->
case Nodes of
[] ->
false;
[Node | Rest] ->
Visited_nodes@1 = gleam@set:insert(
Visited_nodes,
{node, erlang:element(2, Node), erlang:element(3, Node)}
),
case gleam@list:contains(
erlang:element(4, Nfa),
erlang:element(2, erlang:element(3, Node))
) of
true ->
case string:length(Input) =:= erlang:element(2, Node) of
true ->
true;
false ->
Char = gleam@string:slice(
Input,
erlang:element(2, Node),
1
),
Updated_nodes = process_transitions(
Nfa,
erlang:element(3, erlang:element(3, Node)),
erlang:element(2, Node),
Visited_nodes@1,
Rest,
Char
),
evaluate_loop(
Nfa,
Input,
Updated_nodes,
Visited_nodes@1
)
end;
false ->
Char@1 = gleam@string:slice(
Input,
erlang:element(2, Node),
1
),
Updated_nodes@1 = process_transitions(
Nfa,
erlang:element(3, erlang:element(3, Node)),
erlang:element(2, Node),
Visited_nodes@1,
Rest,
Char@1
),
evaluate_loop(Nfa, Input, Updated_nodes@1, Visited_nodes@1)
end
end.
-file("src/rexen/nfa/machine.gleam", 73).
-spec evaluate(n_f_a(), binary()) -> boolean().
evaluate(Nfa, Input) ->
S@1 = case gleam_stdlib:map_get(
erlang:element(2, Nfa),
erlang:element(3, Nfa)
) of
{ok, S} -> S;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"rexen/nfa/machine"/utf8>>,
function => <<"evaluate"/utf8>>,
line => 74,
value => _assert_fail,
start => 1645,
'end' => 1703,
pattern_start => 1656,
pattern_end => 1661})
end,
Nodes = [{node, 0, S@1}],
Visited_nodes = gleam@set:new(),
evaluate_loop(Nfa, Input, Nodes, Visited_nodes).