Advertisement
Guest User

Untitled

a guest
Dec 10th, 2016
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.60 KB | None | 0 0
  1. defmodule MathInterpreter.Translator do
  2. alias MathInterpreter.Stack, as: Stack
  3.  
  4. def translate_to_postfix_notation(tokens) do
  5. { :ok, pid } = Stack.start_link() # создаем стек
  6. _translate(tokens, [], pid)
  7. end
  8.  
  9. defp _translate([ { :number, _ } = token | tail ], output, pid) do # если это число
  10. _translate(tail, [ token | output ], pid) # помещаем ее в выходную строку
  11. end
  12.  
  13. defp _translate([ :l_bracket = token | tail ], output, pid) do # открывающая скобка
  14. Stack.push(pid, token) # помещаем ее в стек
  15. _translate(tail, output, pid)
  16. end
  17.  
  18. defp _translate([ :r_bracket | tail ] = string, output, pid) do # закрывающая скобка
  19. top = Stack.pop(pid)
  20.  
  21. case top do
  22. :l_bracket -> # если на вершине стека открывающая скобка
  23. _translate(tail, output, pid) # все токены до скобки вытолкнуты
  24. _ ->
  25. _translate(string, [ top | output ], pid) # иначе помещаем оператор в выходной список
  26. end
  27. end
  28.  
  29. defp _translate([ operator | tail ] = string, output, pid) do # оператор
  30. top = Stack.peek(pid)
  31.  
  32. case top do
  33. nil -> # если стек пустой
  34. Stack.push(pid, operator) # помещаем оператор в стек
  35. _translate(tail, output, pid)
  36. _ -> # стек не пустой
  37. if priority(operator) <= priority(top) do # если приоритет оператора меньше чем в стеке
  38. Stack.pop(pid) # достаем оператор из стека
  39. _translate(string, [top | output], pid) # и добавляем в выходной список
  40. else
  41. Stack.push(pid, operator) # иначе помещаем оператор в стек
  42. _translate(tail, output, pid)
  43. end
  44. end
  45. end
  46.  
  47. defp _translate([], output, pid) do # если входной список закончился
  48. top = Stack.peek(pid)
  49.  
  50. case top do
  51. nil -> # если стек пустой
  52. Enum.reverse(output) # реверс выходного списка
  53. _ ->
  54. Stack.pop(pid) # иначе достаем оператор из стека
  55. _translate([], [ top | output ], pid) # и добавляем в выходной список
  56. end
  57. end
  58.  
  59. def priority(:l_bracket), do: 1
  60. def priority(:r_bracket), do: 1
  61. def priority(:plus), do: 2
  62. def priority(:minus), do: 2
  63. def priority(:mul), do: 3
  64. def priority(:div), do: 3
  65. def priority(:pow), do: 4
  66. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement