Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- defmodule MathInterpreter.Translator do
- alias MathInterpreter.Stack, as: Stack
- def translate_to_postfix_notation(tokens) do
- { :ok, pid } = Stack.start_link() # создаем стек
- _translate(tokens, [], pid)
- end
- defp _translate([ { :number, _ } = token | tail ], output, pid) do # если это число
- _translate(tail, [ token | output ], pid) # помещаем ее в выходную строку
- end
- defp _translate([ :l_bracket = token | tail ], output, pid) do # открывающая скобка
- Stack.push(pid, token) # помещаем ее в стек
- _translate(tail, output, pid)
- end
- defp _translate([ :r_bracket | tail ] = string, output, pid) do # закрывающая скобка
- top = Stack.pop(pid)
- case top do
- :l_bracket -> # если на вершине стека открывающая скобка
- _translate(tail, output, pid) # все токены до скобки вытолкнуты
- _ ->
- _translate(string, [ top | output ], pid) # иначе помещаем оператор в выходной список
- end
- end
- defp _translate([ operator | tail ] = string, output, pid) do # оператор
- top = Stack.peek(pid)
- case top do
- nil -> # если стек пустой
- Stack.push(pid, operator) # помещаем оператор в стек
- _translate(tail, output, pid)
- _ -> # стек не пустой
- if priority(operator) <= priority(top) do # если приоритет оператора меньше чем в стеке
- Stack.pop(pid) # достаем оператор из стека
- _translate(string, [top | output], pid) # и добавляем в выходной список
- else
- Stack.push(pid, operator) # иначе помещаем оператор в стек
- _translate(tail, output, pid)
- end
- end
- end
- defp _translate([], output, pid) do # если входной список закончился
- top = Stack.peek(pid)
- case top do
- nil -> # если стек пустой
- Enum.reverse(output) # реверс выходного списка
- _ ->
- Stack.pop(pid) # иначе достаем оператор из стека
- _translate([], [ top | output ], pid) # и добавляем в выходной список
- end
- end
- def priority(:l_bracket), do: 1
- def priority(:r_bracket), do: 1
- def priority(:plus), do: 2
- def priority(:minus), do: 2
- def priority(:mul), do: 3
- def priority(:div), do: 3
- def priority(:pow), do: 4
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement