Pull to refresh

Comments 15

UFO just landed and posted this here

Унарный минус эо признак числа, а не оператор. Такие вещи должны быть выявлены на этапе разбиения на лексемы исходного выражения

UFO just landed and posted this here

Короче нужен рекурсивный спуск или взрослые табличные парсеры

А как насчет "-(2 + 3 — 4*5)" или в общем виде "-(a + b — c*d)" и ему подобных?
Все парсится и вычисляется правильно
Описание типов
image

Обработка унарной операции в парсере
image

Результат вычисления
image

Язык древний, но работает

Можно использовать 0 - (2 + 3 - 4*5) в инфиксной записи. В постфиксной записи:

0 2 3 + 4 5 * - -

UFO just landed and posted this here

Легко: если встретился минус, а перед ним не было операндов (т.е. начало выражения или перед этим была скобка) то пушим ноль в качестве операнда.

Альтернатива: заводим (внутреннюю) операцию «унарный минус» с соответствующим приоритетом (выше умножения), и пушим её, если не было операнда и был минус.

Конечно, тут приходится новую яйчейку памяти заводить под «не было операндов». А всё потому, что один знак «минус» использован для разных операций. Логически они одинаковые, но имеют разное число аргументов.

С унарными операциями, имеющими свой собственный знак, такой проблемы нет. Правда, нас спасает то, что математические унарные операции - префиксные и имеют высокий приоритет. Благодаря этим свойствам, они вписываются в алгоритм.

Учитывайте, что при нормализации вашего выражения, мы получаем -1 * (a + b - c*d), где - становится признаком числа.

Я, кстати, делал программу для вычисления математических выражений. Если в начале выражения встречается знак минуса, то в ответ записывается 0, а минус кладется в стэк, т.е. происходит преобразование унарного минуса в бинарный.

А также в математических выражениях ещё есть степени и функции.

степени и функции (одной переменной) - это унарные операторы. думаю, в такой записи бинарные и унарные операторы надо четко различать. Вот что делать с унарным минусом, чтобы его н путать с бинарным? лучше наверное переименовать, чтобы "-" был только бинарным (ну или отказаться от унарного минуса вовсе, заменив его на "0 -" )

Как вариант, можно усложнить алгоритм парсинга выражения, написав грамматику с учетом унарных, бинарных операторов, их приоритетов.

При правильной грамматике, унарный и бинарный минусы в процессе разбора по грамматике, будут различаться автоматически.

степень это оператор выше умножения.

а функции надо выделять на этапе разбора лексем первоначального выражения и выписывать их как унарный оператор на самом высоком уровне. Т.е. у нас есть выражение:

exp(1+x)*-2

Его надо распарсить на 2 массива

f1 = exp . [1, +, x]
[f1, *, -2]

далее преобразуем оба массива в обратную польскую

f1 = exp . [1, x, +] = 1 x + exp
f1 -2 *

И во втором выражении подменяем f1

1 x + exp -2 *

Алгоритм сортировочной станции жеж. Все кристально ясно

Sign up to leave a comment.

Articles