Last active
April 2, 2025 15:22
-
-
Save RobertDober/d6885d863bbd50131395190b192f7066 to your computer and use it in GitHub Desktop.
High Level Architecture for NimbleParsec Integration into EarmarkParser
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule HLArch do | |
# We get a binary from ex_doc anyway, therefore we can ... | |
@spec parse(binary, ast) :: ast | |
def parse(input, ast \\ []) do | |
input | |
|> put_into_struct() # getting fields content: input, lnb: 1, col: 1 | |
|> parse_into_ast() | |
|> semantic_checks() | |
end | |
# We need more info here than in the eventual result, because in case | |
# of errors during semantic checks we will need some context information | |
# concerning the location in the input **at least** | |
# Probably we will also add another argument context :: map or struct, but we will see | |
@spec parse_into_ast(Input.t, ast()) :: annotated_ast() | |
def parse_into_ast(input, ast \\ []) | |
def parse_into_ast("", ast), do: ast |> some_post_processing() # Probably just Enum.reverse | |
def parse_into_ast(input, ast) do | |
# No more pattern matching on function definitions because, unless we have alreadya a very stable codebase, | |
# we can avoid the pain of debugging with... | |
# IO.inspect(input, label: ">>>parse_into_ast") | |
{new_input, new_ast} = | |
case input.content do | |
<<"<", html::binary>> -> {html, rest, position, _} = Nimble.HtmlParser(html) | |
# Ignoring Error Handling here | |
update_ast_and_input(ast, html) | |
_ -> {line, rest} = get_next_line(input.content) | |
# Some of Jonatan's optimizations will be obsoleted by that approach #100, #101 | |
# because we will not read lines inside multiline code blocks anymore | |
# This should make the code clearer though | |
typed_line = LineScanner.type_of(line) | |
# Integrating this with recursive calls into parse_into_ast will be all | |
# save trivial | |
parse_old_logic(typed_line, rest, ast) | |
end | |
# |> IO.inspect(input, label: "<<<parse_into_ast") | |
parse_into_ast(new_input, new_ast) | |
end | |
# I believe a Regex is perfect for that, some better idea? | |
defp get_next_line(input_string) do | |
case Regex.run(~r/\A(.*?)\n(.*)/msu, input.content) do | |
nil -> {input_string, nil} | |
[_, line, rest ] -> {line, rest} | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here are the links of Jonathan's PRs mention in the gist RobertDober/earmark_parser#100 RobertDober/earmark_parser#101