diff --git a/lib/philomena/search/helpers.ex b/lib/philomena/search/helpers.ex new file mode 100644 index 00000000..f407fd99 --- /dev/null +++ b/lib/philomena/search/helpers.ex @@ -0,0 +1,23 @@ +defmodule Philomena.Search.Helpers do + import NimbleParsec + + def to_number(term) do + {float_val, _} = :string.to_float(term) + {int_val, _} = :string.to_integer(term) + + cond do + is_float(float_val) -> + float_val + + is_integer(int_val) -> + int_val + end + end + + def reverse_times(combinator \\ empty(), to_repeat, opts) do + max = opts[:max] + + combinator + |> choice((for x <- max..1, do: times(to_repeat, x)) ++ [empty()]) + end +end \ No newline at end of file diff --git a/lib/philomena/search/lexer.ex b/lib/philomena/search/lexer.ex index 55040eda..7031f42d 100644 --- a/lib/philomena/search/lexer.ex +++ b/lib/philomena/search/lexer.ex @@ -1,18 +1,6 @@ defmodule Philomena.Search.Lexer do import NimbleParsec - - defp to_number(term) do - {float_val, _} = :string.to_float(term) - {int_val, _} = :string.to_integer(term) - - cond do - is_float(float_val) -> - float_val - - is_integer(int_val) -> - int_val - end - end + import Philomena.Search.Helpers l_and = choice([string("AND"), string("&&"), string(",")]) @@ -76,13 +64,27 @@ defmodule Philomena.Search.Lexer do choice([ times(ipv6_fragment, 6) |> concat(ipv6_ls32), string("::") |> times(ipv6_fragment, 5) |> concat(ipv6_ls32), - optional(ipv6_hexadectet) |> string("::") |> times(ipv6_fragment, 4) |> concat(ipv6_ls32), - optional(times(ipv6_fragment, max: 1) |> concat(ipv6_hexadectet)) |> string("::") |> times(ipv6_fragment, 3) |> concat(ipv6_ls32), - optional(times(ipv6_fragment, max: 2) |> concat(ipv6_hexadectet)) |> string("::") |> times(ipv6_fragment, 2) |> concat(ipv6_ls32), - optional(times(ipv6_fragment, max: 3) |> concat(ipv6_hexadectet)) |> string("::") |> concat(ipv6_fragment) |> concat(ipv6_ls32), - optional(times(ipv6_fragment, max: 4) |> concat(ipv6_hexadectet)) |> string("::") |> concat(ipv6_ls32), - optional(times(ipv6_fragment, max: 5) |> concat(ipv6_hexadectet)) |> string("::") |> concat(ipv6_hexadectet), - optional(times(ipv6_fragment, max: 6) |> concat(ipv6_hexadectet)) |> string("::") + + ipv6_hexadectet |> string("::") |> times(ipv6_fragment, 4) |> concat(ipv6_ls32), + string("::") |> times(ipv6_fragment, 4) |> concat(ipv6_ls32), + + times(ipv6_fragment, max: 1) |> concat(ipv6_hexadectet) |> string("::") |> times(ipv6_fragment, 3) |> concat(ipv6_ls32), + string("::") |> times(ipv6_fragment, 3) |> concat(ipv6_ls32), + + times(ipv6_fragment, max: 2) |> concat(ipv6_hexadectet) |> string("::") |> times(ipv6_fragment, 2) |> concat(ipv6_ls32), + string("::") |> times(ipv6_fragment, 2) |> concat(ipv6_ls32), + + times(ipv6_fragment, max: 3) |> concat(ipv6_hexadectet) |> string("::") |> concat(ipv6_fragment) |> concat(ipv6_ls32), + string("::") |> concat(ipv6_fragment) |> concat(ipv6_ls32), + + times(ipv6_fragment, max: 4) |> concat(ipv6_hexadectet) |> string("::") |> concat(ipv6_ls32), + string("::") |> concat(ipv6_ls32), + + times(ipv6_fragment, max: 5) |> concat(ipv6_hexadectet) |> string("::") |> concat(ipv6_hexadectet), + string("::") |> concat(ipv6_hexadectet), + + times(ipv6_fragment, max: 6) |> concat(ipv6_hexadectet) |> string("::"), + string("::") ]) cidr_prefix = @@ -99,6 +101,8 @@ defmodule Philomena.Search.Lexer do |> label("a valid IPv4 or IPv6 address and optional CIDR prefix") |> unwrap_and_tag(:ip) + defparsec :ip, ipv6_address + year = integer(4) month = integer(2) day = integer(2)