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
-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. | |