Current section
Files
Jump to
Current section
Files
lib/modules/lexer.ex
defmodule Lexer do
@moduledoc """
Breaks the source code string (SCS) into an output list of tokens (OTL).
"""
@doc """
Returns an output list of tokens (OTL) by breaking the source code string (SCS).
## Specs
```arg``` is a tuple that contains the following elements:
+ **source_code_string**: source code string.
+ **general_token_list**: target language's valid token list. Refer to
`Reader.read_code_and_tokens/3` for more information.
## Examples
iex> source = Reader.read_code_and_tokens("examples/test_s2.c",
"specification_files/c_tokens.xml")
iex> Lexer.tokenize(source)
"""
def tokenize({source_code_string, general_token_list}) do
lex(source_code_string, general_token_list, [])
end
defp lex("", _, output_token_list) do
error_token = Enum.find(output_token_list, fn x -> x.tag == "error" end)
if error_token == nil do
{output_token_list, :ok}
else
{error_token, :error}
end
end
defp lex(source_code_string, general_token_list, output_token_list) do
# source_code_string = source code without '\n' and '\t' chars.
{token, match} = Enum.reduce_while(
general_token_list,
{"",""},
fn token, _ ->
if (regex_matches =
Regex.run(~r/^\s*#{token.expression}\s*/, source_code_string)
) == nil,
do: {:cont, {token, :error}},
else: {:halt, {token, Enum.at(regex_matches,0)}}
end
)
t = %{token | expression: String.trim(match)}
lex(
#remove from source_code_string the matched token
String.replace_prefix(source_code_string, match, ""),
general_token_list,
output_token_list ++ [t]
)
end
end