revati
How to parse strings with NimbleParsec?
Hello.
i would like to parse strings (with nimble parsec i assume) that look something like this:
x(some.dot.split.values) → [x: [“some”, “dot”, “split”, “value”]]
y(some.x(dot).split.values) → [y: [“some”, [x: [“dot”]], “split”, “value”]]
maybe if it is easier to implement
x some.dot.split.values → [x: [“some”, “dot”, “split”, “value”]]
y some.(x dot).split.values → [y: [“some”, [x: [“dot”]], “split”, “value”]]
Idea is to have nested patterns, and dot split strings that should represent array
I found this, but i do not understand how perentacies are implemented there How do you write nested and recursive NimbleParsec parsers? - #4 by jakemorrison
Maybe someone knows. Thanks.
Marked As Solved
NduatiK
defmodule Parser do
import NimbleParsec
# Step 1: Define your smallest units
# I've assumed here that the a word is a list of
# more than one lowercase character
#
# Match abc
defparsecp(
:word,
times(ascii_char([?a..?z]), min: 1)
|> reduce({List, :to_string, []})
)
# Step 2: Define a function as a a thing
# that has a word followed by:
# - an opening bracket
# - a "chain of stuff"
# - a closing bracket
#
# Match abc(___)
defparsec(
:function,
parsec(:word)
|> map({String, :to_atom, []})
|> concat(
ignore(string("("))
|> concat(parsec(:chain))
|> concat(ignore(string(")")))
# Put the function arguments in a list
|> wrap()
)
)
# Match abc or abc(___)
defparsecp(
:function_or_word,
choice([
parsec(:function),
parsec(:word)
])
)
# Step 3: Define the "chain" as a
# word or function followed by a "."
# delimited list of words or functions
#
# Match abc.def or abc(___).def or abc(___).def
defparsecp(
:chain,
parsec(:function_or_word)
|> times(
ignore(string("."))
|> concat(parsec(:function_or_word)),
min: 0
)
)
def parse!(str) do
# Only parse successfully if the entire string is consumed
{:ok, result, "" = _unconsumed, %{}, {_, _}, _} =
function(str)
result
end
end
Parser.parse!("x(some.dot.split.values)")
Parser.parse!("y(some.x(dot).split.values)")
Also Liked
jakemorrison
Here is a library that supports parsing nested lists with parentheses: GitHub - cogini/http_structured_field: Elixir library to parse HTTP Structured Fields (RFC 8941)







