mfm-parser/lib/lexer.ex

63 lines
1.3 KiB
Elixir
Raw Normal View History

2022-07-23 17:15:08 +00:00
defmodule MfmParser.Lexer do
alias MfmParser.Reader
alias MfmParser.Token
alias MfmParser.Token.MFM
alias MfmParser.Token.Newline
alias MfmParser.Token.Text
2022-07-23 17:15:08 +00:00
def peek(input) do
case next(input) do
{token, _} -> token
2022-07-23 17:15:08 +00:00
:eof -> :eof
end
end
def next(input) do
recursive_extract_next_token(Reader.next(input), get_empty_token(input))
2022-07-23 17:15:08 +00:00
end
defp recursive_extract_next_token(:eof, _) do
2022-07-23 17:15:08 +00:00
:eof
end
defp recursive_extract_next_token({char, rest}, token) do
if is_last_char_of_token?(char, rest, token) do
{token |> Token.append(char), rest}
2022-07-23 17:15:08 +00:00
else
recursive_extract_next_token(Reader.next(rest), token |> Token.append(char))
end
end
defp get_empty_token(input) do
case Reader.peek(input) do
:eof -> :eof
"$" -> %MFM.Open{}
"]" -> %MFM.Close{}
"\n" -> %Newline{}
_ -> %Text{}
2022-07-23 17:15:08 +00:00
end
end
defp is_last_char_of_token?(char, _, %MFM.Open{}) do
char == " "
2022-07-23 17:15:08 +00:00
end
defp is_last_char_of_token?(_, _, %MFM.Close{}) do
2022-07-23 17:15:08 +00:00
true
end
defp is_last_char_of_token?(_, _, %Newline{}) do
2022-07-23 17:15:08 +00:00
true
end
defp is_last_char_of_token?(_, rest, %Text{}) do
2022-07-23 17:15:08 +00:00
case Reader.next(rest) do
:eof -> true
{"]", _} -> true
{"$", new_rest} -> Reader.peek(new_rest) == "["
2022-07-23 17:15:08 +00:00
_ -> false
end
end
end