Current section
Files
Jump to
Current section
Files
src/chomp.erl
-module(chomp).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([run/2, return/1, succeed/1, throw/1, fail/1, lazy/1, backtrackable/1, do/2, then/2, map/2, replace/2, map_error/2, or_error/2, replace_error/2, get_pos/0, is_at_end/0, token/1, 'end'/0, one_of/1, 'or'/2, optional/1, loop/2, until_end/1, sequence/2, many/1, many1/1, take_if/1, any/0, take_map/1, until/2, in/2, do_in/3, inspect/2]).
-export_type([parser/4, step/4, state/2, committed/0, error/2, loop/2]).
-opaque parser(GUW, GUX, GUY, GUZ) :: {parser,
fun((state(GUY, GUZ)) -> step(GUW, GUX, GUY, GUZ))}.
-type step(GVA, GVB, GVC, GVD) :: {cont, committed(), GVA, state(GVC, GVD)} |
{fail,
committed(),
error(GVB, GVC),
chomp@span:span(),
list({chomp@span:span(), GVD})}.
-type state(GVE, GVF) :: {state,
gleam@dict:dict(integer(), chomp@lexer:token(GVE)),
integer(),
chomp@span:span(),
list({chomp@span:span(), GVF})}.
-type committed() :: {committed, boolean()}.
-type error(GVG, GVH) :: {custom, GVG} |
end_of_input |
{expected, GVH, GVH} |
{unexpected, GVH} |
{bad_parser, binary()}.
-type loop(GVI, GVJ) :: {continue, GVJ} | {break, GVI}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 131).
-spec runwrap(state(GVZ, GWA), parser(GWD, GWE, GVZ, GWA)) -> step(GWD, GWE, GVZ, GWA).
runwrap(State, Parser) ->
{parser, Parse} = Parser,
Parse(State).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 115).
-spec run(list(chomp@lexer:token(GVK)), parser(GVN, GVO, GVK, GVP)) -> {ok, GVN} |
{error,
{error(GVO, GVK), chomp@span:span(), list({chomp@span:span(), GVP})}}.
run(Src, Parser) ->
Src@1 = gleam@list:index_fold(
Src,
gleam@dict:new(),
fun(Dict, Tok, Idx) -> gleam@dict:insert(Dict, Idx, Tok) end
),
Init = {state, Src@1, 0, {span, 1, 1, 1, 1}, []},
case runwrap(Init, Parser) of
{cont, _, A, _} ->
{ok, A};
{fail, _, Problem, Pos, Ctx} ->
{error, {Problem, Pos, Ctx}}
end.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 139).
-spec next(state(GWN, GWO)) -> {gleam@option:option(GWN), state(GWN, GWO)}.
next(State) ->
case gleam@dict:get(erlang:element(2, State), erlang:element(3, State)) of
{error, _} ->
{none, State};
{ok, {token, Span, _, Tok}} ->
{{some, Tok},
erlang:setelement(
4,
erlang:setelement(3, State, erlang:element(3, State) + 1),
Span
)}
end.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 180).
-spec return(GWU) -> parser(GWU, any(), any(), any()).
return(Value) ->
{parser, fun(State) -> {cont, {committed, false}, Value, State} end}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 190).
-spec succeed(GXC) -> parser(GXC, any(), any(), any()).
succeed(Value) ->
return(Value).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 197).
-spec throw(GXK) -> parser(any(), GXK, any(), any()).
throw(Error) ->
{parser,
fun(State) ->
Error@1 = {custom, Error},
{fail,
{committed, false},
Error@1,
erlang:element(4, State),
erlang:element(5, State)}
end}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 207).
-spec fail(GXS) -> parser(any(), GXS, any(), any()).
fail(Error) ->
throw(Error).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 214).
-spec lazy(fun(() -> parser(GYA, GYB, GYC, GYD))) -> parser(GYA, GYB, GYC, GYD).
lazy(Parser) ->
{parser, fun(State) -> runwrap(State, Parser()) end}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 239).
-spec backtrackable(parser(GYM, GYN, GYO, GYP)) -> parser(GYM, GYN, GYO, GYP).
backtrackable(Parser) ->
{parser, fun(State) -> case runwrap(State, Parser) of
{cont, _, A, State@1} ->
{cont, {committed, false}, A, State@1};
{fail, _, Problem, Pos, Ctx} ->
{fail, {committed, false}, Problem, Pos, Ctx}
end end}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 248).
-spec should_commit(committed(), committed()) -> committed().
should_commit(A, B) ->
{committed, A@1} = A,
{committed, B@1} = B,
{committed, A@1 orelse B@1}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 279).
-spec do(parser(GYY, GYZ, GZA, GZB), fun((GYY) -> parser(GZG, GYZ, GZA, GZB))) -> parser(GZG, GYZ, GZA, GZB).
do(Parser, F) ->
{parser, fun(State) -> case runwrap(State, Parser) of
{cont, To_a, A, State@1} ->
case runwrap(State@1, F(A)) of
{cont, To_b, B, State@2} ->
{cont, should_commit(To_a, To_b), B, State@2};
{fail, To_b@1, Problem, Pos, Ctx} ->
{fail,
should_commit(To_a, To_b@1),
Problem,
Pos,
Ctx}
end;
{fail, Committed, Problem@1, Pos@1, Ctx@1} ->
{fail, Committed, Problem@1, Pos@1, Ctx@1}
end end}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 309).
-spec then(parser(HAG, HAH, HAI, HAJ), fun((HAG) -> parser(HAO, HAH, HAI, HAJ))) -> parser(HAO, HAH, HAI, HAJ).
then(Parser, F) ->
do(Parser, F).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 318).
-spec map(parser(HAX, HAY, HAZ, HBA), fun((HAX) -> HBF)) -> parser(HBF, HAY, HAZ, HBA).
map(Parser, F) ->
do(Parser, fun(A) -> return(F(A)) end).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 329).
-spec replace(parser(any(), HBL, HBM, HBN), HBS) -> parser(HBS, HBL, HBM, HBN).
replace(Parser, B) ->
map(Parser, fun(_) -> B end).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 400).
-spec map_error(
parser(HCJ, HCK, HCL, HCM),
fun((error(HCK, HCL)) -> error(HCK, HCL))
) -> parser(HCJ, HCK, HCL, HCM).
map_error(Parser, Map) ->
{parser, fun(State) -> case runwrap(State, Parser) of
{fail, _, end_of_input, _, _} = Fail ->
Fail;
{fail, {committed, false}, Error, Pos, Ctx} ->
{fail, {committed, false}, Map(Error), Pos, Ctx};
Result ->
Result
end end}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 358).
-spec or_error(parser(HBX, HBY, HBZ, HCA), HBY) -> parser(HBX, HBY, HBZ, HCA).
or_error(Parser, Error) ->
map_error(Parser, fun(_) -> {custom, Error} end).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 443).
-spec replace_error(parser(HCZ, HDA, HDB, HDC), HDA) -> parser(HCZ, HDA, HDB, HDC).
replace_error(Parser, Error) ->
{parser, fun(State) -> case runwrap(State, Parser) of
{fail, Committed, _, Pos, Ctx} ->
{fail, Committed, {custom, Error}, Pos, Ctx};
Result ->
Result
end end}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 459).
-spec get_pos() -> parser(chomp@span:span(), any(), any(), any()).
get_pos() ->
{parser,
fun(State) ->
{cont, {committed, false}, erlang:element(4, State), State}
end}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 467).
-spec is_at_end() -> parser(boolean(), any(), any(), any()).
is_at_end() ->
{parser, fun(State) -> case next(State) of
{{some, _}, _} ->
{cont, {committed, false}, false, State};
{none, _} ->
{cont, {committed, false}, true, State}
end end}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 492).
-spec token(HEG) -> parser(chomp@span:span(), any(), HEG, any()).
token(Tok) ->
{parser, fun(State) -> case next(State) of
{{some, T}, State@1} when Tok =:= T ->
{cont,
{committed, true},
erlang:element(4, State@1),
State@1};
{{some, T@1}, State@2} ->
{fail,
{committed, false},
{expected, Tok, T@1},
erlang:element(4, State@2),
erlang:element(5, State@2)};
{none, State@3} ->
{fail,
{committed, false},
end_of_input,
erlang:element(4, State@3),
erlang:element(5, State@3)}
end end}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 507).
-spec 'end'() -> parser(nil, any(), any(), any()).
'end'() ->
{parser, fun(State) -> case next(State) of
{{some, Tok}, State@1} ->
{fail,
{committed, false},
{unexpected, Tok},
erlang:element(4, State@1),
erlang:element(5, State@1)};
{none, _} ->
{cont, {committed, false}, nil, State}
end end}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 523).
-spec one_of(list(parser(HEU, HEV, HEW, HEX))) -> parser(HEU, HEV, HEW, HEX).
one_of(Parsers) ->
{parser, fun(State) -> case Parsers of
[] ->
{fail,
{committed, false},
{bad_parser,
<<"one_of requires at least one parser"/utf8>>},
erlang:element(4, State),
erlang:element(5, State)};
[Parser] ->
runwrap(State, Parser);
[Parser@1 | Rest] ->
case runwrap(State, Parser@1) of
{cont, _, _, _} = Result ->
Result;
{fail, {committed, true}, _, _, _} = Result@1 ->
Result@1;
{fail, _, _, _, _} ->
runwrap(State, one_of(Rest))
end
end end}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 547).
-spec 'or'(parser(HFH, HFI, HFJ, HFK), HFH) -> parser(HFH, HFI, HFJ, HFK).
'or'(Parser, Default) ->
one_of([Parser, return(Default)]).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 555).
-spec optional(parser(HFT, HFU, HFV, HFW)) -> parser(gleam@option:option(HFT), HFU, HFV, HFW).
optional(Parser) ->
one_of([map(Parser, fun(Field@0) -> {some, Field@0} end), return(none)]).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 687).
-spec loop_help(
fun((IDA) -> parser(loop(IDM, IDA), IDF, IDG, IDH)),
committed(),
IDA,
state(IDG, IDH)
) -> step(IDM, IDF, IDG, IDH).
loop_help(F, Commit, Loop_state, State) ->
case runwrap(State, F(Loop_state)) of
{cont, Can_backtrack, {continue, Next_loop_state}, Next_state} ->
loop_help(
F,
should_commit(Commit, Can_backtrack),
Next_loop_state,
Next_state
);
{cont, Can_backtrack@1, {break, Result}, Next_state@1} ->
{cont, should_commit(Commit, Can_backtrack@1), Result, Next_state@1};
{fail, Can_backtrack@2, Problem, Pos, Ctx} ->
{fail, should_commit(Commit, Can_backtrack@2), Problem, Pos, Ctx}
end.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 678).
-spec loop(HJQ, fun((HJQ) -> parser(loop(HJR, HJQ), HJU, HJV, HJW))) -> parser(HJR, HJU, HJV, HJW).
loop(Init, Step) ->
{parser, fun(State) -> loop_help(Step, {committed, false}, Init, State) end}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 610).
-spec until_end(parser(HHY, HHZ, HIA, HIB)) -> parser(list(HHY), HHZ, HIA, HIB).
until_end(Parser) ->
loop([], fun(Xs) -> do(is_at_end(), fun(Is_at_end) -> case Is_at_end of
true ->
return({break, lists:reverse(Xs)});
false ->
do(
Parser,
fun(X) -> return({continue, [X | Xs]}) end
)
end end) end).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 647).
-spec more(HIY, parser(HIY, HIZ, HJA, HJB), parser(any(), HIZ, HJA, HJB)) -> parser(list(HIY), HIZ, HJA, HJB).
more(X, Parser, Separator) ->
loop(
[X],
fun(Xs) ->
Break = fun() -> return({break, lists:reverse(Xs)}) end,
Continue = (do(
Separator,
fun(_) ->
do(Parser, fun(X@1) -> return({continue, [X@1 | Xs]}) end)
end
)),
one_of([Continue, lazy(Break)])
end
).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 563).
-spec sequence(parser(HGG, HGH, HGI, HGJ), parser(any(), HGH, HGI, HGJ)) -> parser(list(HGG), HGH, HGI, HGJ).
sequence(Parser, Sep) ->
one_of(
[begin
_pipe = Parser,
then(_pipe, fun(_capture) -> more(_capture, Parser, Sep) end)
end,
return([])]
).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 576).
-spec many(parser(HGY, HGZ, HHA, HHB)) -> parser(list(HGY), HGZ, HHA, HHB).
many(Parser) ->
sequence(Parser, return(nil)).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 585).
-spec many1(parser(HHL, HHM, HHN, HHO)) -> parser(list(HHL), HHM, HHN, HHO).
many1(Parser) ->
do(Parser, fun(X) -> do(many(Parser), fun(Xs) -> return([X | Xs]) end) end).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 707).
-spec take_if(fun((HKK) -> boolean())) -> parser(HKK, any(), HKK, any()).
take_if(Predicate) ->
{parser,
fun(State) ->
{Tok, State@1} = next(State),
case {Tok, gleam@option:map(Tok, Predicate)} of
{{some, Tok@1}, {some, true}} ->
{cont, {committed, true}, Tok@1, State@1};
{{some, Tok@2}, {some, false}} ->
{fail,
{committed, false},
{unexpected, Tok@2},
erlang:element(4, State@1),
erlang:element(5, State@1)};
{_, _} ->
{fail,
{committed, false},
end_of_input,
erlang:element(4, State@1),
erlang:element(5, State@1)}
end
end}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 480).
-spec any() -> parser(HDZ, any(), HDZ, any()).
any() ->
take_if(fun(_) -> true end).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 723).
-spec take_map(fun((HKR) -> gleam@option:option(HKS))) -> parser(HKS, any(), HKR, any()).
take_map(F) ->
{parser,
fun(State) ->
{Tok, State@1} = next(State),
case {Tok, gleam@option:then(Tok, F)} of
{none, _} ->
{fail,
{committed, false},
end_of_input,
erlang:element(4, State@1),
erlang:element(5, State@1)};
{{some, Tok@1}, none} ->
{fail,
{committed, false},
{unexpected, Tok@1},
erlang:element(4, State@1),
erlang:element(5, State@1)};
{_, {some, A}} ->
{cont, {committed, true}, A, State@1}
end
end}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 625).
-spec until(parser(HIL, HIM, HIN, HIO), HIN) -> parser(list(HIL), HIM, HIN, HIO).
until(Parser, Tok) ->
loop(
[],
fun(Xs) ->
Break = take_map(fun(T) -> case T =:= Tok of
true ->
{some, {break, lists:reverse(Xs)}};
false ->
none
end end),
Continue = (do(Parser, fun(X) -> return({continue, [X | Xs]}) end)),
one_of([Break, Continue])
end
).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 769).
-spec push_context(state(HLM, HLN), HLN) -> state(HLM, HLN).
push_context(State, Context) ->
erlang:setelement(
5,
State,
[{erlang:element(4, State), Context} | erlang:element(5, State)]
).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 773).
-spec pop_context(state(HLS, HLT)) -> state(HLS, HLT).
pop_context(State) ->
case erlang:element(5, State) of
[] ->
State;
[_ | Context] ->
erlang:setelement(5, State, Context)
end.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 757).
-spec in(parser(HLA, HLB, HLC, HLD), HLD) -> parser(HLA, HLB, HLC, HLD).
in(Parser, Context) ->
{parser, fun(State) -> case runwrap(push_context(State, Context), Parser) of
{cont, Committed, A, State@1} ->
{cont, Committed, A, pop_context(State@1)};
{fail, Committed@1, Problem, Pos, Ctx} ->
{fail, Committed@1, Problem, Pos, Ctx}
end end}.
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 298).
-spec do_in(
GZP,
parser(GZQ, GZR, GZS, GZP),
fun((GZQ) -> parser(GZX, GZR, GZS, GZP))
) -> parser(GZX, GZR, GZS, GZP).
do_in(Context, Parser, F) ->
_pipe = do(Parser, F),
in(_pipe, Context).
-file("/home/mystic/projects/gleam/chomp/src/chomp.gleam", 781).
-spec inspect(parser(HLY, HLZ, HMA, HMB), binary()) -> parser(HLY, HLZ, HMA, HMB).
inspect(Parser, Message) ->
{parser,
fun(State) ->
gleam@io:println(<<Message/binary, ": "/utf8>>),
_pipe = runwrap(State, Parser),
gleam@io:debug(_pipe)
end}.