From 4ac065fbe57ed19760dbb55453e5875b3c0c188d Mon Sep 17 00:00:00 2001 From: Anhgelus Morhtuuzh Date: Tue, 4 Nov 2025 12:30:35 +0100 Subject: feat(parser): default parser --- .gitignore | 2 ++ lib/elixir_math_parser.ex | 47 +++++++++++++++++++++++++++++++++++++++-------- lib/main.ex | 28 ++++++++++++++++++++++++++++ mix.exs | 3 ++- 4 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 lib/main.ex diff --git a/.gitignore b/.gitignore index c556df8..af52a17 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ erl_crash.dump # Ignore package tarball (built via "mix hex.build"). elixir_math_parser-*.tar +src/elixir_math_parser*.erl + diff --git a/lib/elixir_math_parser.ex b/lib/elixir_math_parser.ex index cd300e9..1f147aa 100644 --- a/lib/elixir_math_parser.ex +++ b/lib/elixir_math_parser.ex @@ -3,16 +3,47 @@ defmodule ElixirMathParser do Documentation for `ElixirMathParser`. """ - @doc """ - Hello world. + defp reduce_to_value({:int, _line, value}, _state) do + value + end + + defp reduce_to_value({:add_op, lhs, rhs}, state) do + reduce_to_value(lhs, state) + reduce_to_value(rhs, state) + end - ## Examples + defp reduce_to_value({:sub_op, lhs, rhs}, state) do + reduce_to_value(lhs, state) - reduce_to_value(rhs, state) + end - iex> ElixirMathParser.hello() - :world + defp reduce_to_value({:mul_op, lhs, rhs}, state) do + reduce_to_value(lhs, state) * reduce_to_value(rhs, state) + end - """ - def hello do - :world + defp reduce_to_value({:div_op, lhs, rhs}, state) do + reduce_to_value(lhs, state) / reduce_to_value(rhs, state) end + + defp reduce_to_value({:atom, _line, atom}, state) do + state[atom] + end + + defp evaluate_tree([{:assign, {:atom, _line, lhs}, rhs} | tail], state) do + rhs_value = reduce_to_value(rhs, state) + evaluate_tree(tail, Map.merge(state, %{lhs => rhs_value})) + end + + defp evaluate_tree([], state) do + state + end + + def process_tree(tree) do + evaluate_tree(tree, %{}) + end + + def parse_file(filename) do + text = File.read!(filename) + {:ok, tokens, _line} = :elixir_math_parser_lexer.string(String.to_charlist(text)) + {:ok, tree} = :elixir_math_parser.parse(tokens) + process_tree(tree) + end end diff --git a/lib/main.ex b/lib/main.ex new file mode 100644 index 0000000..ca73cb5 --- /dev/null +++ b/lib/main.ex @@ -0,0 +1,28 @@ +defmodule ElixirMathParser.Main do + def process_parse({:error, result}) do + IO.puts "\nParse error" + IO.inspect result + end + + def process_parse({:ok, tree}) do + IO.puts "\nParse tree" + IO.inspect tree, pretty: true + state = ElixirMathParser.process_tree(tree) + IO.puts "\nFinal state" + IO.inspect state, pretty: true + end + + def main(args) do + filename = Enum.fetch!(args, 0) + + IO.puts "Parsing #{filename}" + text = File.read!(filename) + + {:ok, tokens, line} = :elixir_math_parser_lexer.string(String.to_charlist(text)) + IO.puts "Parsed #{filename}, stopped at line #{line}" + IO.puts "\nTokens:" + IO.inspect tokens, pretty: true + + process_parse(:elixir_math_parser.parse(tokens)) + end +end diff --git a/mix.exs b/mix.exs index a138d8b..3b7e2dd 100644 --- a/mix.exs +++ b/mix.exs @@ -7,7 +7,8 @@ defmodule ElixirMathParser.MixProject do version: "0.1.0", elixir: "~> 1.19", start_permanent: Mix.env() == :prod, - deps: deps() + deps: deps(), + escript: [main_module: ElixirMathParser.Main], ] end -- cgit v1.2.3