Current section
Files
Jump to
Current section
Files
src/rexen@grammar.erl
-module(rexen@grammar).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/rexen/grammar.gleam").
-export([to_string/2, shunt/1]).
-export_type([operator_variant/1, token/0]).
-type operator_variant(DQV) :: o_paren |
{asterix, DQV} |
{bar, DQV} |
{dot, DQV} |
{q_mark, DQV} |
{plus, DQV}.
-type token() :: c_paren |
{letter, binary()} |
{operator, operator_variant(integer())}.
-file("src/rexen/grammar.gleam", 19).
-spec tokenize(list(binary()), list(token())) -> list(token()).
tokenize(Input, Tokens) ->
case Input of
[] ->
Tokens;
[Char | Rest] ->
Tok = case Char of
<<"*"/utf8>> ->
{operator, {asterix, 3}};
<<"?"/utf8>> ->
{operator, {q_mark, 3}};
<<"+"/utf8>> ->
{operator, {plus, 3}};
<<"|"/utf8>> ->
{operator, {bar, 1}};
<<"("/utf8>> ->
{operator, o_paren};
<<")"/utf8>> ->
c_paren;
_ ->
{letter, Char}
end,
tokenize(Rest, lists:append(Tokens, [Tok]))
end.
-file("src/rexen/grammar.gleam", 37).
-spec add_concat(list(token()), list(token())) -> list(token()).
add_concat(Tokens, Output) ->
case Tokens of
[] ->
Output;
[Curr | Rest] ->
case gleam@list:last(Output) of
{error, _} ->
add_concat(Rest, lists:append(Output, [Curr]));
{ok, Prev} ->
case Prev of
{letter, _} ->
case Curr of
{letter, _} ->
add_concat(
Rest,
lists:append(
Output,
[{operator, {dot, 2}}, Curr]
)
);
c_paren ->
add_concat(
Rest,
lists:append(Output, [Curr])
);
{operator, Variant} ->
case Variant of
o_paren ->
add_concat(
Rest,
lists:append(
Output,
[{operator, {dot, 2}}, Curr]
)
);
_ ->
add_concat(
Rest,
lists:append(Output, [Curr])
)
end
end;
c_paren ->
case Curr of
{letter, _} ->
add_concat(
Rest,
lists:append(
Output,
[{operator, {dot, 2}}, Curr]
)
);
c_paren ->
add_concat(
Rest,
lists:append(Output, [Curr])
);
{operator, Variant@1} ->
case Variant@1 of
o_paren ->
add_concat(
Rest,
lists:append(
Output,
[{operator, {dot, 2}}, Curr]
)
);
_ ->
add_concat(
Rest,
lists:append(Output, [Curr])
)
end
end;
{operator, Variant@2} ->
case Variant@2 of
{asterix, _} ->
case Curr of
{letter, _} ->
add_concat(
Rest,
lists:append(
Output,
[{operator, {dot, 2}}, Curr]
)
);
c_paren ->
add_concat(
Rest,
lists:append(Output, [Curr])
);
{operator, Variant@3} ->
case Variant@3 of
o_paren ->
add_concat(
Rest,
lists:append(
Output,
[{operator,
{dot, 2}},
Curr]
)
);
_ ->
add_concat(
Rest,
lists:append(
Output,
[Curr]
)
)
end
end;
_ ->
add_concat(
Rest,
lists:append(Output, [Curr])
)
end
end
end
end.
-file("src/rexen/grammar.gleam", 117).
-spec to_string(list(token()), binary()) -> binary().
to_string(Tokens, Output) ->
case Tokens of
[] ->
Output;
[Tok | Rest] ->
case Tok of
c_paren ->
to_string(Rest, gleam@string:append(Output, <<")"/utf8>>));
{letter, Char} ->
to_string(Rest, gleam@string:append(Output, Char));
{operator, Variant} ->
case Variant of
o_paren ->
to_string(
Rest,
gleam@string:append(Output, <<"("/utf8>>)
);
{asterix, _} ->
to_string(
Rest,
gleam@string:append(Output, <<"*"/utf8>>)
);
{bar, _} ->
to_string(
Rest,
gleam@string:append(Output, <<"|"/utf8>>)
);
{dot, _} ->
to_string(Rest, Output);
{q_mark, _} ->
to_string(
Rest,
gleam@string:append(Output, <<"?"/utf8>>)
);
{plus, _} ->
to_string(
Rest,
gleam@string:append(Output, <<"+"/utf8>>)
)
end
end
end.
-file("src/rexen/grammar.gleam", 185).
-spec emptystack(list(token()), list(operator_variant(integer()))) -> list(token()).
emptystack(Output, Stack) ->
case Stack of
[] ->
Output;
[Opvar | Rest] ->
O = lists:append(Output, [{operator, Opvar}]),
emptystack(O, Rest)
end.
-file("src/rexen/grammar.gleam", 195).
-spec handle_operator(
list(token()),
list(operator_variant(integer())),
operator_variant(integer()),
integer()
) -> {list(token()), list(operator_variant(integer()))}.
handle_operator(Output, Stack, Variant, Precedence) ->
case Stack of
[] ->
{Output, gleam@list:prepend(Stack, Variant)};
[Opvar | Rest] ->
case Opvar of
o_paren ->
{Output, gleam@list:prepend(Stack, Variant)};
{asterix, P} ->
case Precedence > P of
true ->
{Output, gleam@list:prepend(Stack, Variant)};
false ->
O = lists:append(Output, [{operator, Opvar}]),
handle_operator(O, Rest, Variant, Precedence)
end;
{bar, P} ->
case Precedence > P of
true ->
{Output, gleam@list:prepend(Stack, Variant)};
false ->
O = lists:append(Output, [{operator, Opvar}]),
handle_operator(O, Rest, Variant, Precedence)
end;
{dot, P} ->
case Precedence > P of
true ->
{Output, gleam@list:prepend(Stack, Variant)};
false ->
O = lists:append(Output, [{operator, Opvar}]),
handle_operator(O, Rest, Variant, Precedence)
end;
{q_mark, P} ->
case Precedence > P of
true ->
{Output, gleam@list:prepend(Stack, Variant)};
false ->
O = lists:append(Output, [{operator, Opvar}]),
handle_operator(O, Rest, Variant, Precedence)
end;
{plus, P} ->
case Precedence > P of
true ->
{Output, gleam@list:prepend(Stack, Variant)};
false ->
O = lists:append(Output, [{operator, Opvar}]),
handle_operator(O, Rest, Variant, Precedence)
end
end
end.
-file("src/rexen/grammar.gleam", 225).
-spec find_oparen(list(token()), list(operator_variant(integer()))) -> {ok,
{list(token()), list(operator_variant(integer()))}} |
{error, binary()}.
find_oparen(Output, Stack) ->
case Stack of
[] ->
{error,
<<"Trailing closing bracket found in the regular expression."/utf8>>};
[Opval | Rest] ->
case Opval of
o_paren ->
{ok, {Output, Rest}};
_ ->
Out = lists:append(Output, [{operator, Opval}]),
find_oparen(Out, Rest)
end
end.
-file("src/rexen/grammar.gleam", 151).
-spec shunt_loop(
list(token()),
list(token()),
list(operator_variant(integer()))
) -> {ok, list(token())} | {error, binary()}.
shunt_loop(Input, Output, Stack) ->
case Input of
[] ->
{ok, emptystack(Output, Stack)};
[Tok | Rest] ->
case Tok of
{letter, _} ->
shunt_loop(Rest, lists:append(Output, [Tok]), Stack);
c_paren ->
case find_oparen(Output, Stack) of
{ok, {O, S}} ->
shunt_loop(Rest, O, S);
{error, Err} ->
{error, Err}
end;
{operator, Opvar} ->
case Opvar of
o_paren ->
shunt_loop(
Rest,
Output,
gleam@list:prepend(Stack, Opvar)
);
{asterix, P} ->
{O@1, S@1} = handle_operator(
Output,
Stack,
Opvar,
P
),
shunt_loop(Rest, O@1, S@1);
{bar, P} ->
{O@1, S@1} = handle_operator(
Output,
Stack,
Opvar,
P
),
shunt_loop(Rest, O@1, S@1);
{dot, P} ->
{O@1, S@1} = handle_operator(
Output,
Stack,
Opvar,
P
),
shunt_loop(Rest, O@1, S@1);
{q_mark, P} ->
{O@1, S@1} = handle_operator(
Output,
Stack,
Opvar,
P
),
shunt_loop(Rest, O@1, S@1);
{plus, P} ->
{O@1, S@1} = handle_operator(
Output,
Stack,
Opvar,
P
),
shunt_loop(Rest, O@1, S@1)
end
end
end.
-file("src/rexen/grammar.gleam", 144).
-spec shunt(binary()) -> {ok, list(token())} | {error, binary()}.
shunt(Input) ->
In = gleam@string:to_graphemes(Input),
_pipe = tokenize(In, []),
_pipe@1 = add_concat(_pipe, []),
shunt_loop(_pipe@1, [], []).