Packages

A CSS selector parser and evaluator

Current section

Files

Jump to
css_select src css_select@internal@parser.erl
Raw

src/css_select@internal@parser.erl

-module(css_select@internal@parser).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/css_select/internal/parser.gleam").
-export([lexer/0, parse_simple_selector/1]).
-export_type([t/0, parse_error/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(false).
-type t() :: hash |
dot |
star |
colon |
equal_sign |
prefix |
suffix |
l_bracket |
r_bracket |
{name, binary()} |
{str_t, binary()}.
-type parse_error(LFZ) :: {lexer_error, nibble@lexer:error()} |
{parse_error, list(nibble:dead_end(t(), LFZ))}.
-file("src/css_select/internal/parser.gleam", 22).
?DOC(false).
-spec lexer() -> nibble@lexer:lexer(t(), nil).
lexer() ->
nibble@lexer:simple(
[nibble@lexer:token(<<"#"/utf8>>, hash),
nibble@lexer:token(<<"."/utf8>>, dot),
nibble@lexer:token(<<"*"/utf8>>, star),
nibble@lexer:token(<<":"/utf8>>, colon),
nibble@lexer:token(<<"["/utf8>>, l_bracket),
nibble@lexer:token(<<"]"/utf8>>, r_bracket),
nibble@lexer:token(<<"="/utf8>>, equal_sign),
nibble@lexer:token(<<"^="/utf8>>, prefix),
nibble@lexer:token(<<"$="/utf8>>, suffix),
nibble@lexer:string(
<<"\""/utf8>>,
fun(Field@0) -> {name, Field@0} end
),
nibble@lexer:identifier(
<<"^[\\w]"/utf8>>,
<<"[\\w\\-_]"/utf8>>,
gleam@set:new(),
fun(Field@0) -> {name, Field@0} end
)]
).
-file("src/css_select/internal/parser.gleam", 38).
?DOC(false).
-spec identifier_parser() -> nibble:parser(binary(), t(), any()).
identifier_parser() ->
nibble:take_map(<<"identifier"/utf8>>, fun(Tok) -> case Tok of
{name, K} ->
{some, K};
_ ->
none
end end).
-file("src/css_select/internal/parser.gleam", 47).
?DOC(false).
-spec class_parser() -> nibble:parser(css_select@selector:attribute_selector(), t(), any()).
class_parser() ->
nibble:do(
nibble:token(dot),
fun(_) ->
nibble:do(
identifier_parser(),
fun(Class) -> nibble:return({class, Class}) end
)
end
).
-file("src/css_select/internal/parser.gleam", 54).
?DOC(false).
-spec id_parser() -> nibble:parser(css_select@selector:attribute_selector(), t(), any()).
id_parser() ->
nibble:do(
nibble:token(hash),
fun(_) ->
nibble:do(
identifier_parser(),
fun(Id) -> nibble:return({id, Id}) end
)
end
).
-file("src/css_select/internal/parser.gleam", 65).
?DOC(false).
-spec any_parser() -> nibble:parser(css_select@selector:tag_selector(), any(), any()).
any_parser() ->
nibble:succeed(any).
-file("src/css_select/internal/parser.gleam", 69).
?DOC(false).
-spec tag_parser() -> nibble:parser(css_select@selector:tag_selector(), t(), any()).
tag_parser() ->
nibble:do(identifier_parser(), fun(Tag) -> nibble:return({tag, Tag}) end).
-file("src/css_select/internal/parser.gleam", 61).
?DOC(false).
-spec element_parser() -> nibble:parser(css_select@selector:tag_selector(), t(), any()).
element_parser() ->
nibble:one_of([tag_parser(), any_parser()]).
-file("src/css_select/internal/parser.gleam", 78).
?DOC(false).
-spec psuedo_parser() -> nibble:parser(css_select@selector:attribute_selector(), t(), any()).
psuedo_parser() ->
nibble:do(
nibble:token(colon),
fun(_) ->
nibble:do(
identifier_parser(),
fun(Name) -> nibble:return({psuedo, Name}) end
)
end
).
-file("src/css_select/internal/parser.gleam", 84).
?DOC(false).
-spec attr_parser() -> nibble:parser(css_select@selector:attribute_selector(), t(), any()).
attr_parser() ->
nibble:do(
nibble:token(l_bracket),
fun(_) ->
nibble:do(
identifier_parser(),
fun(Key) ->
Attribute_exists = begin
nibble:do(
nibble:token(r_bracket),
fun(_) -> nibble:return({attribute_exists, Key}) end
)
end,
Attribute_equals = begin
nibble:do(
nibble:token(equal_sign),
fun(_) ->
nibble:do(
identifier_parser(),
fun(Value) ->
nibble:do(
nibble:token(r_bracket),
fun(_) ->
nibble:return(
{attribute_equal,
Key,
Value}
)
end
)
end
)
end
)
end,
Attribute_prefix = begin
nibble:do(
nibble:token(prefix),
fun(_) ->
nibble:do(
identifier_parser(),
fun(Value@1) ->
nibble:do(
nibble:token(r_bracket),
fun(_) ->
nibble:return(
{attribute_prefix,
Key,
Value@1}
)
end
)
end
)
end
)
end,
Attribute_suffix = begin
nibble:do(
nibble:token(suffix),
fun(_) ->
nibble:do(
identifier_parser(),
fun(Value@2) ->
nibble:do(
nibble:token(r_bracket),
fun(_) ->
nibble:return(
{attribute_suffix,
Key,
Value@2}
)
end
)
end
)
end
)
end,
nibble:one_of(
[Attribute_exists,
Attribute_equals,
Attribute_prefix,
Attribute_suffix]
)
end
)
end
).
-file("src/css_select/internal/parser.gleam", 74).
?DOC(false).
-spec attr_selector_parser() -> nibble:parser(css_select@selector:attribute_selector(), t(), any()).
attr_selector_parser() ->
nibble:one_of([class_parser(), id_parser(), attr_parser(), psuedo_parser()]).
-file("src/css_select/internal/parser.gleam", 122).
?DOC(false).
-spec parser() -> nibble:parser(css_select@selector:selector(), t(), any()).
parser() ->
nibble:do(
element_parser(),
fun(Tag_selector) ->
nibble:do(
nibble:many(attr_selector_parser()),
fun(Attr_selectors) ->
nibble:return(
{element_selector, Tag_selector, Attr_selectors}
)
end
)
end
).
-file("src/css_select/internal/parser.gleam", 133).
?DOC(false).
-spec parse_simple_selector(binary()) -> {ok, css_select@selector:selector()} |
{error, parse_error(any())}.
parse_simple_selector(Input) ->
_pipe = Input,
_pipe@1 = nibble@lexer:run(_pipe, lexer()),
_pipe@2 = gleam@result:map_error(
_pipe@1,
fun(Field@0) -> {lexer_error, Field@0} end
),
gleam@result:'try'(
_pipe@2,
fun(Tokens) -> _pipe@3 = nibble:run(Tokens, parser()),
gleam@result:map_error(
_pipe@3,
fun(Field@0) -> {parse_error, Field@0} end
) end
).