Расширение алгоритма маневровой станции для поддержки условного тернарного оператора

Как расширить алгоритм маневровой станции, изначально предназначенный для бинарных операторов, для поддержки условного тернарного оператора ("a ? b: c")? Я не видел ответа на этот вопрос здесь, и он у меня есть, поэтому я публикую его.


person Yuval    schedule 24.02.2016    source источник


Ответы (2)


Я сделал это, добавив три новых оператора:

  • "?" троичный-открытый-если
  • ":" троичное-иначе
  • тернарно-закрыто-если

Только первые два будут созданы непосредственно при чтении исходного выражения.
Однако в выходных данных будет существовать только третий (RPN исходного выражения).
Тернарный-open-if помещается в операторы складываются всякий раз, когда "?" виден.
Троичное-else никогда не помещается в стек. Скорее, стек выталкивается до тех пор, пока не будет найдено троичное открытое условие, после чего троичное открытое условие заменяется троичным закрытым условием (таким образом указывая, что мы находимся в другой части условного оператора).< br> Все три оператора имеют более высокий приоритет, чем все остальные операторы (более высокий приоритет означает, что они оцениваются ПОСЛЕ других операторов).
Тернарные операторы if имеют такой же приоритет и правильную ассоциативность (как в C), что означает, что троичный- if никогда не вызовет появление другого троичного-if.
Троичное-else имеет более высокий приоритет, чем троичное-ifs, и его ассоциативность не имеет значения (поскольку оно никогда не помещается в стек). Таким образом, при встрече с троичным открытым-если он преобразует его в закрытый, как упоминалось ранее.
При встрече с троичным закрытым-если он извлекает его.

Примеры (тройное-закрытое-если обозначено как "?:"):

  • "a ? b : c" -->
    "a b c ?:"
  • "a ? b : x ? y : z" -->
    "a b x y z ?: ?:"
  • "a ? x ? y : z : b" -->
    "a x y z ?: b ?:"

Этот метод сложнее объяснить, чем реализовать, и он вносит небольшое изменение в алгоритм, поэтому, если у кого-то есть более простое решение, опубликуйте его.

person Yuval    schedule 24.02.2016

Для тех, кто все еще ищет здесь, условный тернарный оператор также может быть реализован как функция ЕСЛИ с тремя аргументами:

IF([boolean], [expr_if_true], [expr_if_false])

Например, чтобы преобразовать IF(5 > 4, 9, 8) в обратную польскую нотацию путем расширения алгоритма маневровой станции, выполните следующие действия:

+-------+---------------------------------------------------+--------------+----------------+
| Token | Action                                            | RPN Output   | Operator stack |
+-------+---------------------------------------------------+--------------+----------------+
| IF    | Push token to stack                               |              | IF             |
| (     | Push token to stack                               |              | IF (           |
| 5     | Add token to output                               | 5            | IF (           |
| >     | Push token to stack                               | 5            | 15 ( >         |
| 4     | Add token to output                               | 5 4          | IF ( >         |
| ,     | Pop from stack onto output until left parenthesis | 5 4 >        | IF (           |
| 9     | Add token to output                               | 5 4 > 9      | IF (           |
| ,     | Pop from stack onto output until left parenthesis | 5 4 > 9      | IF (           |
| 8     | Add token to output                               | 5 4 > 9 8    | IF (           |
| )     | Pop from stack onto output until left parenthesis | 5 4 > 9 8    | IF             |
| end   | Pop entire stack onto output                      | 5 4 > 9 8 IF |                |
+-------+---------------------------------------------------+--------------+----------------+

Постфикс оценивается как:

+-------+------------------------------------------------------------------------------------------+-------+
| Token | Action                                                                                   | Stack |
+-------+------------------------------------------------------------------------------------------+-------+
| 5     | Push to stack                                                                            | 5     |
| 4     | Push to stack                                                                            | 4     |
| >     | Pop from stack twice (5, 4), evaluate (5 > 4) and push onto stack                        | TRUE  |
| 9     | Push onto stack                                                                          | 9     |
| 8     | Push onto stack                                                                          | 8     |
| IF    | Pop from stack thrice (TRUE, 9, 8), evaluate (IF TRUE THEN 9 ELSE 8) and push onto stack | 9     |
+-------+------------------------------------------------------------------------------------------+-------+
person Chidi Williams    schedule 22.10.2019