Skip to content

Instantly share code, notes, and snippets.

@rpechayr
Created April 12, 2016 08:36
Show Gist options
  • Save rpechayr/60f0c22dbcdccce96b02f2fe78701237 to your computer and use it in GitHub Desktop.
Save rpechayr/60f0c22dbcdccce96b02f2fe78701237 to your computer and use it in GitHub Desktop.
Erlang evaluation exercise
-module(exp).
-export([parse_expression/1, evaluate_expression/1]).
parse_expression(Exp) ->
parse_acc(Exp, {unknown, unknown, unknown}).
convert_operator(Char) ->
case Char of
$- -> minus;
$+ -> plus;
$* -> times;
Other -> Other
end.
parse_acc([Head|Tail], Current) ->
% io:format("~p / ~p / ~p~n", [parse_acc, [Head|Tail], Current]),
case Head of
$- -> parse_separator([Head|Tail], Current);
$+ -> parse_separator([Head|Tail], Current);
_ -> case string:to_integer([Head|Tail]) of
{error, no_integer} -> parse_separator([Head|Tail], Current);
{Number, Tail} -> parse_integer(Number, Current, Tail)
end
end;
parse_acc([], Current) -> Current.
parse_integer(Number, Current, Tail) ->
% io:format("~p / ~p / ~p~n", [parse_integer, Tail, Current]),
case Current of
{unknown, unknown, unknown} -> parse_acc(Tail, {unknown, {number, Number}, unknown});
{Opearator, Left, unknown} -> parse_acc(Tail, {Opearator, Left, {number, Number}});
{_,_,_} -> {error, expression_already_complete}
end.
parse_separator([Head|Tail], Current) ->
% io:format("~p / ~p / ~p~n", [parse_separator, [Head|Tail], Current]),
case convert_operator(Head) of
$( ->
{NewExpression, NewTail} = parse_acc(Tail, {unknown, unknown, unknown}),
case Current of
{unknown, unknown, unknown} -> parse_acc(NewTail, {unknown, NewExpression, unknown});
{Operator, Left, unknown} -> parse_acc(NewTail, {Operator, Left, NewExpression});
{_,_,_} -> {error, expression_already_complete}
end;
$) -> {Current, Tail};
Other -> {_,Left,Right} = Current,
parse_acc(Tail, {Other, Left, Right})
end;
parse_separator([], Current) ->
Current.
evaluate_expression({Operator,Left, Right}) ->
case Operator of
minus -> evaluate_expression(Left) - evaluate_expression(Right);
plus -> evaluate_expression(Left) + evaluate_expression(Right);
times -> evaluate_expression(Left) * evaluate_expression(Right)
end;
evaluate_expression({number, Number}) ->
Number.

Launch erlang shell from the directory containing exp.erl :

1>c(exp).
{ok, exp}
2> Exp = exp:parse_expression("(2-3)+(4+2)").
{plus,{minus,{number,2},{number,3}},
      {plus,{number,4},{number,2}}}
3> exp:evaluate_expression(Exp).
5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment