mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-23 20:18:00 +01:00
reformat
This commit is contained in:
parent
aef0e7f7d5
commit
108377462e
3 changed files with 60 additions and 38 deletions
|
@ -8,6 +8,7 @@ defmodule Philomena.Search.Lexer do
|
|||
cond do
|
||||
is_float(float_val) ->
|
||||
float_val
|
||||
|
||||
is_integer(int_val) ->
|
||||
int_val
|
||||
end
|
||||
|
@ -44,7 +45,7 @@ defmodule Philomena.Search.Lexer do
|
|||
|
||||
quot = string("\"")
|
||||
|
||||
quoted_term =
|
||||
quoted_term =
|
||||
ignore(quot)
|
||||
|> choice([
|
||||
ignore(string("\\")) |> string("\""),
|
||||
|
@ -57,47 +58,51 @@ defmodule Philomena.Search.Lexer do
|
|||
|> reduce({List, :to_string, []})
|
||||
|> unwrap_and_tag(:term)
|
||||
|
||||
stop_words = choice([
|
||||
string("\\") |> eos(),
|
||||
string(","),
|
||||
concat(space, l_and),
|
||||
concat(space, l_or),
|
||||
concat(space, l_not),
|
||||
rparen,
|
||||
fuzz,
|
||||
boost
|
||||
])
|
||||
stop_words =
|
||||
choice([
|
||||
string("\\") |> eos(),
|
||||
string(","),
|
||||
concat(space, l_and),
|
||||
concat(space, l_or),
|
||||
concat(space, l_not),
|
||||
rparen,
|
||||
fuzz,
|
||||
boost
|
||||
])
|
||||
|
||||
defcombinatorp :simple_term,
|
||||
defcombinatorp(
|
||||
:simple_term,
|
||||
lookahead_not(stop_words)
|
||||
|> choice([
|
||||
string("\\") |> utf8_char([]),
|
||||
string("(") |> parsec(:simple_term) |> string(")"),
|
||||
utf8_char([]),
|
||||
utf8_char([])
|
||||
])
|
||||
|> times(min: 1)
|
||||
)
|
||||
|
||||
unquoted_term =
|
||||
parsec(:simple_term)
|
||||
|> reduce({List, :to_string, []})
|
||||
|> unwrap_and_tag(:term)
|
||||
|
||||
outer = choice([
|
||||
l_and,
|
||||
l_or,
|
||||
l_not,
|
||||
lparen,
|
||||
rparen,
|
||||
boost,
|
||||
fuzz,
|
||||
space,
|
||||
quoted_term,
|
||||
unquoted_term
|
||||
])
|
||||
outer =
|
||||
choice([
|
||||
l_and,
|
||||
l_or,
|
||||
l_not,
|
||||
lparen,
|
||||
rparen,
|
||||
boost,
|
||||
fuzz,
|
||||
space,
|
||||
quoted_term,
|
||||
unquoted_term
|
||||
])
|
||||
|
||||
search =
|
||||
times(outer, min: 1)
|
||||
|> eos()
|
||||
|
||||
defparsec :search, search
|
||||
end
|
||||
defparsec(:search, search)
|
||||
end
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
defmodule Philomena.Search.Parser do
|
||||
alias Philomena.Search.Lexer
|
||||
|
||||
def parse(ctx, tokens) do
|
||||
{tree, [eof: "$"]} = search_top(ctx, tokens)
|
||||
{tree, []} = search_top(ctx, tokens)
|
||||
|
||||
{:ok, tree}
|
||||
rescue
|
||||
e in ArgumentError ->
|
||||
{:error, e.message}
|
||||
|
||||
_ ->
|
||||
{:error, "Parsing error."}
|
||||
end
|
||||
|
@ -20,11 +19,13 @@ defmodule Philomena.Search.Parser do
|
|||
#
|
||||
# Boolean OR
|
||||
#
|
||||
|
||||
defp search_or(ctx, tokens) do
|
||||
case search_and(ctx, tokens) do
|
||||
{left, [{:or, _} | r_tokens]} ->
|
||||
{right, rest} = search_top(ctx, r_tokens)
|
||||
{%{bool: %{should: [left, right]}}, rest}
|
||||
|
||||
{child, rest} ->
|
||||
{child, rest}
|
||||
end
|
||||
|
@ -33,11 +34,13 @@ defmodule Philomena.Search.Parser do
|
|||
#
|
||||
# Boolean AND
|
||||
#
|
||||
|
||||
defp search_and(ctx, tokens) do
|
||||
case search_boost(ctx, tokens) do
|
||||
{left, [{:and, _} | r_tokens]} ->
|
||||
{right, rest} = search_top(ctx, r_tokens)
|
||||
{%{bool: %{must: [left, right]}}, rest}
|
||||
|
||||
{child, rest} ->
|
||||
{child, rest}
|
||||
end
|
||||
|
@ -46,10 +49,12 @@ defmodule Philomena.Search.Parser do
|
|||
#
|
||||
# Subquery score boosting
|
||||
#
|
||||
|
||||
defp search_boost(ctx, tokens) do
|
||||
case search_not(ctx, tokens) do
|
||||
{child, [{:boost, _}, {:float, value} | r_tokens]} ->
|
||||
{%{function_score: %{query: child, boost_factor: value}}, r_tokens}
|
||||
|
||||
{child, rest} ->
|
||||
{child, rest}
|
||||
end
|
||||
|
@ -58,40 +63,52 @@ defmodule Philomena.Search.Parser do
|
|||
#
|
||||
# Boolean NOT
|
||||
#
|
||||
|
||||
defp search_not(ctx, [{:not, _} | r_tokens]) do
|
||||
{child, rest} = search_top(ctx, r_tokens)
|
||||
|
||||
{%{bool: %{must_not: child}}, rest}
|
||||
end
|
||||
|
||||
defp search_not(ctx, tokens), do: search_group(ctx, tokens)
|
||||
|
||||
#
|
||||
# Logical grouping
|
||||
#
|
||||
|
||||
defp search_group(ctx, [{:lparen, _} | rest]) do
|
||||
case search_top(ctx, rest) do
|
||||
{child, [{:rparen, _} | r_tokens]} ->
|
||||
{child, r_tokens}
|
||||
|
||||
_ ->
|
||||
raise ArgumentError, "Imbalanced parentheses."
|
||||
end
|
||||
end
|
||||
defp search_group(_ctx, [{:rparen, _} | _rest]), do: raise ArgumentError, "Imbalanced parentheses."
|
||||
|
||||
defp search_group(_ctx, [{:rparen, _} | _rest]),
|
||||
do: raise(ArgumentError, "Imbalanced parentheses.")
|
||||
|
||||
defp search_group(ctx, tokens), do: search_fuzz(ctx, tokens)
|
||||
|
||||
#
|
||||
# Term fuzzing
|
||||
#
|
||||
|
||||
defp search_fuzz(ctx, tokens) do
|
||||
nil
|
||||
search_term(ctx, tokens)
|
||||
end
|
||||
|
||||
#
|
||||
# Search terms
|
||||
#
|
||||
defp search_term(ctx, [{:term, t} | rest]) do
|
||||
{TermParser.parse(ctx, t), rest}
|
||||
|
||||
defp search_term(_ctx, [{:term, _t} | rest]) do
|
||||
{[], rest}
|
||||
end
|
||||
defp search_term(_ctx, [eof: "$"]), do: raise ArgumentError, "Expected a term, got <end of input>."
|
||||
defp search_term(_ctx, [{_, text} | _rest]), do: raise ArgumentError, "Expected a term, got `#{text}'."
|
||||
end
|
||||
|
||||
defp search_term(_ctx, []), do: raise(ArgumentError, "Expected a term, got <end of input>.")
|
||||
|
||||
defp search_term(_ctx, [{_, text} | _rest]),
|
||||
do: raise(ArgumentError, "Expected a term, got `#{text}'.")
|
||||
end
|
||||
|
|
2
mix.exs
2
mix.exs
|
@ -50,7 +50,7 @@ defmodule Philomena.MixProject do
|
|||
{:pot, "~> 0.10.1"},
|
||||
{:secure_compare, "~> 0.1.0"},
|
||||
{:elastix, "~> 0.7.1"},
|
||||
{:nimble_parsec, "~> 0.5.1"},
|
||||
{:nimble_parsec, "~> 0.5.1"}
|
||||
]
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue