Java. Вычисление арифметического выражения из строки методом рекурсивного спуска.

preview_player
Показать описание
Разбираемся как написать на Java код, который позволяет вычислить значение выражения, записанного в строке. Для этого создаем нисходящий синтаксический анализатор, реализующий метод рекурсивного спуска на основе правил соответствующей грамматики.

#ArhiTutorialsJava #ityoutubersru

Следующее видео:

Оглавление по алгоритмам:

Исходники:

Поддержать канал💰:

Метод рекурсивного спуска:
Рекомендации по теме
Комментарии
Автор

Отличное объяснение, кстати если кто-то хочет добавить степень (например: 2^3), то добавьте метод:
public static double pow(LexemeBuffer lexemes) { double value = factor(lexemes);
while (true) { Lexeme lexeme = lexemes.next();
switch (lexeme.type) { case OP_POW -> value = Math.pow(value, factor(lexemes));
case EOF, RIGHT_BRACKET, OP_MUL, OP_DIV, OP_PLUS, OP_MINUS -> { lexemes.back();
return value; }
default -> throw new RuntimeException("Unexpected token: " + lexeme.value + " at position: " + lexemes.getPos());
} }
}
А в методе public static int multdiv(LexemeBuffer lexemes) замените все вызовы factor(LexemeBuffer lexemes) на pow(LexemeBuffer lexemes)

YoungRembo
Автор

Большое спасибо за замечательную лекцию! Хочу дать одну полезную модификацию: в таком виде программа не сможет вычислить выражения на подобие "-5 + 10". Достаточно дописать в методе public static int factor(LexemeBuffer lexemes) еще один кейс в начале свича:
"case OP_MINUS:
return -factor(lexemes);"
после этого программа поймет выражения вроде "(-5 * -(-5))"

ПашаНплей
Автор

5:39 Удалось объяснить! Сергей, давно на Вас подписан, и периодически поглядывал ролики связанные с работой структур в языке. Теперь я усиленно взялся за программирование, и вот уже на протяжении недели я нахожу всё, что мне нужно для написания приложения. Огромное спасибо! Вы замечательный учитель!

СавелийШипков
Автор

Пишу парсер с плюсов на питон, не мог найти как мне сделать разбор выражения для построения АСТ, в итоге повторил за тобой чуть поменяв код под свое кодовое окружение, мужик знай ты лучший!

altq
Автор

Видео получилсь лаконичным и при этом очень понятным, с важными для новичков отступлениями. Спасибо!

sgkng
Автор

в курсе javarush есть схожая задача. и во многих комментариях к этой задаче есть ссылка на это видео. 
у этих комментариев много лайков) спасибо вам большое.

asunali
Автор

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

luyt
Автор

Автор, вы просто Мега человек! Спасибо вам большое!

Роман-кюь
Автор

Спасибо за объяснение, все очень понятно и информативно. Успехов!

zmagamadov
Автор

Полезно, спасибо.

Вроде все то же самое читал в умных книжках, но доходило тяжко. После просмотра видео написал свою реализацию часа за 2.
Только вместо расчета подвыражений на месте строю дерево выражения, потом уже его вычисляю. Естественно, все в double с заданной точностью. Осталось дописать мелочи: поддержку функций и переменных, унарные операторы уже сделал.

Главное было на практике понять подход к программированию грамматики.


Еще раз спасибо.

petervakulin
Автор

Спасибо. Очень полезно. На С в рамках обучения выполнял проект, где нужно было в польской нотации написать анализатор функций и вывести в терминал их примитивный график. Этот тип анализа выражения гораздо удобнее в понимании

shluhogon_
Автор

Огромное спасибо! Информативный и полезный ролик! Всего хорошего Вам!

nikinou
Автор

Спасибо огромное, наконец нашёл годную инфу!=)

mikhailtrebenko
Автор

Спасибо, лёгкие 3 балла по ЯиМПу и 4 по Дискре на ИУ-9 в Бомонке

fabio_kind
Автор

Спасибо за видео! Сейчас попробую сам реализовать.

MrTheMaks
Автор

Задачки - это интересно... Сейчас же посмотрю)

funnymoment
Автор

Делал это на питоне. Разбивал выражение на строки если есть скобки, и приваивал им номера. Потом решал строки в обратном порядке.

alexanderivanov
Автор

Сергей, привет. Вот смотри - у тебя в грамматике написано: "expr : plusminus* EOF", а в реализации цикла нет. Причем во всех других местах если звездочка в грамматике, то в реализации - цикл. Так что тут, по-моему, или грамматику надо исправить или реализацию. Потому что в expr ты вызываешь plusminus 1 раз, а надо - любое количество раз.

yashureg
Автор

Я собираюсь парсить логическое выражение, где у меня местами будет текст "column". Логичнее сделать также в switch-case цикл, который будет char собирать в стрингу, когда встретит или почитать про Pattern, Matcher и использовать их для парсинга(я не работал с reGex в Java пока, поэтому не знаю есть ли там что-то, что мне может помочь упростить парсинг)?

СавелийШипков
Автор

Хорошее видео, только режет слух, что вы числа называете "номером"

gosunov