-module(deps@cql@parser). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/deps/cql/parser.gleam"). -export([is_last_char/2, is_balanced_parens/3, find_rightmost_operator_at_level/5, 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/deps/cql/parser.gleam", 105). -spec is_last_char(binary(), integer()) -> boolean(). is_last_char(Input, Pos) -> Is_empty = gleam@string:is_empty(Input), Is_last = Pos =:= (string:length(Input) - 1), Is_empty orelse Is_last. -file("src/deps/cql/parser.gleam", 156). -spec count_parens(integer(), binary(), integer()) -> integer(). count_parens(Cur_count, Input, Pos) -> Char = gleam@string:slice(Input, Pos, 1), case Char of <<"("/utf8>> -> Cur_count + 1; <<")"/utf8>> -> Cur_count - 1; _ -> Cur_count end. -file("src/deps/cql/parser.gleam", 92). -spec is_balanced_parens(binary(), integer(), integer()) -> boolean(). is_balanced_parens(Input, Pos, Count) -> case Pos >= string:length(Input) of true -> Count =:= 0; false -> New_count = count_parens(Count, Input, Pos), Does_not_close_too_early = not ((New_count =:= 0) andalso not is_last_char( Input, Pos )), Does_not_close_too_early andalso is_balanced_parens( Input, Pos + 1, New_count ) end. -file("src/deps/cql/parser.gleam", 57). -spec is_fully_parenthesized(binary()) -> boolean(). is_fully_parenthesized(Input) -> (gleam_stdlib:string_starts_with(Input, <<"("/utf8>>) andalso gleam_stdlib:string_ends_with( Input, <<")"/utf8>> )) andalso ((string:length(Input) >= 2) andalso is_balanced_parens(Input, 1, 1)). -file("src/deps/cql/parser.gleam", 112). -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 ) -> Operator_length = string:length(Operator), 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 + Operator_length, Right_length = string:length(Input) - Right_start, Right = gleam@string:trim( gleam@string:slice(Input, Right_start, Right_length) ), {ok, {Left, Right}} end; false -> New_paren_level = count_parens(Paren_level, Input, Start_pos), New_rightmost_pos = case (New_paren_level =:= 0) andalso (gleam@string:slice( Input, Start_pos, Operator_length ) =:= 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/deps/cql/parser.gleam", 85). -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/deps/cql/parser.gleam", 63). -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/deps/cql/parser.gleam", 41). -spec do_parse_expr(binary()) -> {ok, exp()} | {error, binary()}. do_parse_expr(Input) -> Trimmed = gleam@string:trim(Input), case 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/deps/cql/parser.gleam", 36). -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 ).