Packages
caffeine_lang
0.0.9
6.3.1
6.3.0
6.2.2
6.2.1
6.2.0
6.1.2
6.1.1
6.1.0
6.0.0
5.6.0
5.5.0
5.4.4
5.4.3
5.4.2
5.4.1
5.4.0
5.3.0
5.2.0
5.1.1
5.1.0
5.0.12
5.0.11
5.0.10
5.0.8
5.0.7
5.0.6
5.0.5
5.0.4
5.0.1
5.0.0
4.10.0
4.9.0
4.8.3
4.8.2
4.8.1
4.8.0
4.7.9
4.7.8
4.7.7
4.7.6
4.7.5
4.6.7
4.6.6
4.6.5
4.6.4
4.6.3
4.6.2
4.6.0
4.5.1
4.5.0
4.4.4
4.4.3
4.4.1
4.4.0
4.3.7
4.3.6
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
1.0.2
1.0.1
0.1.0
0.0.24
0.0.23
0.0.22
0.0.21
0.0.20
0.0.19
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14
0.0.13
0.0.12
0.0.11
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.2
0.0.1
A compiler for generating reliability artifacts from service expectation definitions.
Current section
Files
Jump to
Current section
Files
src/caffeine_lang@cql@parser.erl
-module(caffeine_lang@cql@parser).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/caffeine_lang/cql/parser.gleam").
-export([do_parse_expr/1, parse_expr/1]).
-export_type(['query'/0, exp_container/0, operator/0, exp/0, primary/0, word/0]).
-type 'query'() :: {'query', exp()}.
-type exp_container() :: {exp_container, exp()}.
-type operator() :: add | sub | mul | 'div'.
-type exp() :: {operator_expr, exp(), exp(), operator()} | {primary, primary()}.
-type primary() :: {primary_word, word()} | {primary_exp, exp()}.
-type word() :: {word, binary()}.
-file("src/caffeine_lang/cql/parser.gleam", 97).
-spec check_balanced_parens(binary(), integer(), integer()) -> boolean().
check_balanced_parens(Input, Pos, Count) ->
case Pos >= string:length(Input) of
true ->
Count =:= 0;
false ->
Char = gleam@string:slice(Input, Pos, 1),
New_count = case Char of
<<"("/utf8>> ->
Count + 1;
<<")"/utf8>> ->
Count - 1;
_ ->
Count
end,
case (New_count =:= 0) andalso (Pos < (string:length(Input) - 1)) of
true ->
false;
false ->
check_balanced_parens(Input, Pos + 1, New_count)
end
end.
-file("src/caffeine_lang/cql/parser.gleam", 85).
-spec is_fully_parenthesized(binary()) -> boolean().
is_fully_parenthesized(Input) ->
Length = string:length(Input),
case Length < 2 of
true ->
false;
false ->
check_balanced_parens(Input, 1, 1)
end.
-file("src/caffeine_lang/cql/parser.gleam", 115).
-spec find_rightmost_operator_at_level(
binary(),
binary(),
integer(),
integer(),
integer()
) -> {ok, {binary(), binary()}} | {error, binary()}.
find_rightmost_operator_at_level(
Input,
Operator,
Start_pos,
Paren_level,
Rightmost_pos
) ->
case Start_pos >= string:length(Input) of
true ->
case Rightmost_pos of
-1 ->
{error, <<"Operator not found"/utf8>>};
Pos ->
Left = gleam@string:trim(gleam@string:slice(Input, 0, Pos)),
Right_start = Pos + string:length(Operator),
Right_length = string:length(Input) - Right_start,
Right = gleam@string:trim(
gleam@string:slice(Input, Right_start, Right_length)
),
{ok, {Left, Right}}
end;
false ->
Char = gleam@string:slice(Input, Start_pos, 1),
New_paren_level = case Char of
<<"("/utf8>> ->
Paren_level + 1;
<<")"/utf8>> ->
Paren_level - 1;
_ ->
Paren_level
end,
Is_target_operator = (Paren_level =:= 0) andalso (gleam@string:slice(
Input,
Start_pos,
string:length(Operator)
)
=:= Operator),
New_rightmost_pos = case Is_target_operator of
true ->
Start_pos;
false ->
Rightmost_pos
end,
find_rightmost_operator_at_level(
Input,
Operator,
Start_pos + 1,
New_paren_level,
New_rightmost_pos
)
end.
-file("src/caffeine_lang/cql/parser.gleam", 78).
-spec find_operator(binary(), binary()) -> {ok, {binary(), binary()}} |
{error, binary()}.
find_operator(Input, Operator) ->
find_rightmost_operator_at_level(Input, Operator, 0, 0, -1).
-file("src/caffeine_lang/cql/parser.gleam", 56).
-spec try_operators(binary(), list({binary(), operator()})) -> {ok, exp()} |
{error, binary()}.
try_operators(Input, Operators) ->
case Operators of
[] ->
Word = {word, Input},
{ok, {primary, {primary_word, Word}}};
[{Op_str, Op} | Rest] ->
case find_operator(Input, Op_str) of
{ok, {Left, Right}} ->
gleam@result:'try'(
do_parse_expr(Left),
fun(Left_exp) ->
gleam@result:'try'(
do_parse_expr(Right),
fun(Right_exp) ->
{ok,
{operator_expr, Left_exp, Right_exp, Op}}
end
)
end
);
{error, _} ->
try_operators(Input, Rest)
end
end.
-file("src/caffeine_lang/cql/parser.gleam", 38).
-spec do_parse_expr(binary()) -> {ok, exp()} | {error, binary()}.
do_parse_expr(Input) ->
Trimmed = gleam@string:trim(Input),
case (gleam_stdlib:string_starts_with(Trimmed, <<"("/utf8>>) andalso gleam_stdlib:string_ends_with(
Trimmed,
<<")"/utf8>>
))
andalso is_fully_parenthesized(Trimmed) of
true ->
Inner = gleam@string:slice(Trimmed, 1, string:length(Trimmed) - 2),
gleam@result:'try'(
do_parse_expr(Inner),
fun(Inner_exp) -> {ok, {primary, {primary_exp, Inner_exp}}} end
);
false ->
Operators = [{<<"+"/utf8>>, add},
{<<"-"/utf8>>, sub},
{<<"*"/utf8>>, mul},
{<<"/"/utf8>>, 'div'}],
try_operators(Trimmed, Operators)
end.
-file("src/caffeine_lang/cql/parser.gleam", 33).
-spec parse_expr(binary()) -> {ok, exp_container()} | {error, binary()}.
parse_expr(Input) ->
gleam@result:'try'(
do_parse_expr(Input),
fun(Exp) -> {ok, {exp_container, Exp}} end
).