Mathos

Mathos

О разборе и создании языков программирования. Я в ВК: https://vk.com/kot_miyao В Telegram: https://t.me/kot_miyao Иногда бывает и всякая всячина.
На Пикабу
9383 рейтинг 33 подписчика 24 подписки 99 постов 15 в горячем
Награды:
Сборщик Пыли
6

Обратная польская нотация, получение и вычисление

Предыдущая статья: Включения действий при разборе и итог пройденных тем в vk.com

Статья для повторения: От перепутья к перепутью, часть вторая: Разбор языка арифметики

Для тех кто спешит увидеть код вот (С#) или псевдокод вот, кому нужна ясность в них читаем далее.

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

Ниже показаны ещё примеры:

Обратная польская нотация, получение и вычисление Опрос, Программирование, Разбор, Парсер, Переводчик, IT, Урок, Длиннопост

Префиксная и постфиксная запись также именуются прямая и обратная польская нотация (далее ОПН), в честь её изобретателя польского логика Яна Лукасевича. Отличительная их черта, то что в них не используются скобки для обособления вычисления.

Получение ОПН из инфиксной записи

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

Грамматика с унарным минусом и плюсом:
Г: В -> ДС
С -> ε | +ДС | -ДС
Д -> РП | -Д | +Д
П -> ε | *РП | /РП
Р -> ч | (В)

Звенья цепочки ОПН опишем набором трёх типов:
1. Операнд - целые числа.
2. Одноместный оператор - однооп, это унарный минус и плюс.
3. Двуместный оператор - двуоп, это минус, плюс, умножить, делить.

Ниже представлено полное описание звена ОПН:

Обратная польская нотация, получение и вычисление Опрос, Программирование, Разбор, Парсер, Переводчик, IT, Урок, Длиннопост

Соберём звенья в список, который будет представлять нашу ОПН. Для этого отметим 3 действия на отделах рисунка порядка:
Д1 - Создать хрон. Переменная хранящая звено до момента добавления в список.
Д2 - Запомнить. Помещаем встреченное звено в хрон.
Д3 - Добавить. Записываем в список ОПН.

Ниже показаны отделы и процедуры со встроенными действиями в разбор:

Так мы добавляем в первую очередь операнды, затем операторы в порядке их приоритетов. Всмотритесь в процедуру «Дополнениее». В качестве хрона используется стог (англ. stack), так как запоминаются несколько знаков сразу, их следует вспомнить в обратном порядке.

Осмыслим следующее: рекурсивный разборщик выступает теперь не только в качестве распознавателя, но и переводчика. Ведь мы получили цепочку принадлежащую другому формальному языку, который можно описать так:

Грамматика обратной польской нотации:
Г:В -> ч | П`П
П`-> чПО
П -> ВОП | ε

где:

В - ВЫРАЖЕНИЕ
О - ОПЕРАТОР
П - ПРАВОЕ_ПОДВЫРАЖЕНИЕ
П`- ПОДВЫРАЖЕНИЕ
ч - ЧИСЛО

Остановитесь на минутку, осмыслите.

Вычисление ОПН

Ниже изображена схема устройства вычисления ОПН - Стог-машина (Stack machine), а на следующем её описание. Для примера использована ОПН:

1 2 3 * + 4 -

Которая получена из инфиксной записи:

1 + 2 * 3 - 4

Стог-машина состоит из:

  1. Стога - в котором хранятся промежуточные значения.

  2. Набора двухместных и одноместных операций.

  3. Движка - который читает ОПН, управляет стогом и обращается к набору операций.

ОПН обладает свойством: действия применяются последовательно при её чтении, на чём и основана работа стог-машины:

  1. Если звено операнд, то кладём число в стог.

  2. Если звено однооп, снимаем верхнее число обрабатываем, итог кладём в стог.

  3. Если звено двуоп, снимаем два верхних числа и применяем операцию. Причём первое значение операции - второе верхнее, а второе - первое верхнее. Итог кладём в стог.

  4. По окончанию чтения ОПН, итог вычисления оказывается на дне стога, одним.

В заключении

Не стоит думать, что рассмотренный способ единственный для получения ОПН. Есть так же алгоритм Дейкстры перевода выражения в ОПН, но я не знаю стоит ли его разобрать или сразу перейти к обсуждению включения действий в «Провидца», ранее нами рассматриваемого.

Поэтому решение будет зависить от вас:

Какую тему разобрать следующей?
Всего голосов:
Обратная польская нотация, получение и вычисление Опрос, Программирование, Разбор, Парсер, Переводчик, IT, Урок, Длиннопост

Ну на это всё, быть добру, хорошего настроения. Подписывайся. =)
Точно! Для любознательных и внимательных читателей, ещё одна не позиционная система счисления.

Показать полностью 8 1
2

От перепутья к перепутью, часть третья, итоговая: Требования к предопределённому распознанию языка

Предыдущая статья: От перепутья к перепутью, часть вторая: Разбор языка арифметики в vk.com

Перед тем как читать изложение, ознакомьтесь с двумя прошлыми статьями и определением, что такое разбор, в этом порядке: раз, два, три. Прочли? Замечательно! В противном случае вы ничего не поймёте. Приступим.

Левая и правая рекурсия правил вывода.

Пусть у нас есть некоторая цепочка α - состоящая из конечных и неконечных символов, тогда если при выводе некоторого неконечного А, через один и более вывод мы приходим к виду А => … => Aα, где А находится слева от цепочки α, говорят что такая грамматика содержит левую рекурсию, и соответственно при А => … => αА, где А справа от α, правую рекурсию.

О правой рекурсии уже упоминалось, в теме «Рисунок порядка КС-языка», она позволяет легко свести рекурсию к циклу. При построении рекурсивного спуска требуются праворекурсивные грамматики, в противном случае возможна бесконечная рекурсию, затем переполнения стэка (стога) вызовов, как мы любим.

Леворекурсивная грамматика всегда может быть преобразована в эквивалентную праворекурсивную.

Направляющие символы, маяки.

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

От перепутья к перепутью, часть третья, итоговая: Требования к предопределённому распознанию языка Программирование, Урок, Грамматика, Парсер, Разбор, ВКонтакте (ссылка)

Перед - множество конечных направляющих символов.

LL-грамматика

LL(k)-грамматикой называется КС-грамматика, в которой выбор правила в ходе левостороннего разбора однозначно определяется не более чем k очередным символом входной цепочки, считываемой слева на право.

Своё название она получила из двух слова left left. что имеется ввиду левосторонее чтение, левостороний разбор.

Самой удобной для распознавания является грамматика которая позваляет опередлить правило по первому прочтённому символу, то есть LL(1)-грамматика.

Под рекурсивным спуском обычно подразумевают, предопределённый способ нисходящего разбора КС-языков, порождаемых ЛЛ(1)-грамматиками.

ЛЛ-грамматика праворекурсивна и множества направляющих символов в её правилах не пересекаются, что соответствует вышеуказанным требованиям.

Заключение

Эти правила касаются только лишь для метода рекурсивного спуска и ЛЛ-разбора по табелю (табличный анализатор), который рассмотрим в следующих статьях.

UPD:

Читать далее...

Показать полностью 1
1

От перепутья к перепутью, часть вторая: Разбор языка арифметики

Предыдущая статья: От перепутья к перепутью, часть первая: Порядковый разбор КС-языков методом рекурсивного спуска в vk.com

Г: В → ДС
С → ε | +ДС | -ДС
Д → РП
П → ε | *РП | /РП
Р → ч | (В)

Представляю вам грамматику языка арифметики, давайте построим рисунок порядка и обозначим понятиями все неконечные, ε - записываем так '' (между кавычками ничего нет):

Выражение → Дополнение Сумма
Сумма → '' | ''+' Дополнение Сумма | '-' Дополнение Сумма
Дополнение → Результат Произведение
Произведение →'' | '*' Результат Произведение | '/' Результат Произведение
Результат → Целое | '(' Выражение ')'

В качестве чисел у нас выступят только целые, уже нами рассмотренные. Поэтому мы их включим в наш рисунок:

От перепутья к перепутью, часть вторая: Разбор языка арифметики Программирование, Урок, Арифметика, Грамматика, ВКонтакте (ссылка), Длиннопост

Не упрощённый рисунок.

Заметим, что в понятиях «Сумма» и «Произведение» у нас имеется правая рекурсия. Поэтому следует заменить рекурсию на циклы, но ещё видим, что после конечных у нас рассматриваются одноименные понятия, посему объединим в один общий цикл, где кон будет сверяться со множеством:

От перепутья к перепутью, часть вторая: Разбор языка арифметики Программирование, Урок, Арифметика, Грамматика, ВКонтакте (ссылка), Длиннопост

Рисунок порядка языка арифметики (Арифметических выражений)

Рисунок готов, теперь мы можем приступить к описанию процедур:

От перепутья к перепутью, часть вторая: Разбор языка арифметики Программирование, Урок, Арифметика, Грамматика, ВКонтакте (ссылка), Длиннопост

Псевдокот

Конечно у нас есть несколько допущений: 1. Алгоритм рассматривает строки без пробелов, думаю не сложно реализовать их пропуск на вашем любимом языке. 2.Понятие «Сумма» включает в себя вычитание, а «Произведение» деление, надеюсь читатель простит мне это допущение, так как можно представить вычитание и деление в виде их обратных операций. 3. Процедура «Результат», так как отдел рисунка порядка ветвится только на две ветви, я не стал проверять соответствует ли кон символам маякам, коими являются {+, -, цифра}.

Хорошо когда есть готовая и верная грамматика, для рекурсивного спуска по ней достаточно легко написать распознаватель. Какими она должна обладать свойствами? Об этом мы поговорим в следующий раз и вы поймете почему грамматика G(см.ниже) не подходит, хотя она и однозначна и даёт верное семантическое дерево:

G:
E → T | E + T | E – T
T → M|T * M| T / M
M → x | (E)

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

Грамматика с унарным минусом и плюсом:
Г: В → ДС
С → ε | +ДС | -ДС
Д → РП | -Д | +Д
П → ε | *РП | /РП
Р → ч | (В)

UPD:

Читать далее...

Показать полностью 3

Как я за ножом ходил

Чясом задумал я сделать салат из шявеля. Смотрю нож куда-то затерялся. Пошол значит в магазин. Вижу на полке лежыт овошерезка, думаю лучшэ её купить. Взял, иду дальшэ, вспомнил, что салат-то я из шявеля хочю приготовить. Возврашяюсь смотреть ножы. Выбрал такой большой шырокий нож. Взял и его, ешё подложку взял, а то старая совсем изношэна. Посмотрел на чясы, времени ешё хватает до прихода гостей, так-что день тогда у меня вышэл хорошый.

Как будьэт въигльадьэть тьэкст йэсли убрать комбинаторнъийэ аллофонъи и оставить только аллофон и?

Тьэкст изрьадно увьэличивайэтсьа, получайэтсьа наши прьэдки создали самъий оптимизированнъий алфавит дльа нашэго йазъика. Кстати из-за того что буквъи "ы" и "и" йэсть аллофон одной фонэмъи [i], мы пишэм "и" посльэ ш и ж.

3

От перепутья к перепутью, часть первая: Порядковый разбор КС-языков методом рекурсивного спуска

Предыдущая статья:Синтаксические диаграммы КС-языков - Рисунок порядка КС-языков в vk.com.

В правилах вывода неконечные символы по своей сути являются некоторыми языковыми понятиями. Условимся что конечные символы записываются в ' (одинарные кавычки), неконечные курсивом, тогда язык целых чисел мы можем записать так:

целое → '+' хотя_бы_одна | '-' хотя_бы_одна | цифра ещё_или_конец
хотя_бы_одна → цифра ещё_или_конец
ещё_или_конец → цифра
ещё_или_конец | '⊥'
цифра → '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'

В дальнейшем изложении термин понятие будет тождественен неконечному символу. Приступи к описанию метода рекурсивного спуска:

  1. Для каждого понятия создаётся отдельная распознающая процедура.

  2. До начала работы процедуры текущим является первый символ разбираемого понятия, назовём его кон (сокр. от конечный и от смыслов «партия в игре», «черта», «граница»).

  3. Исполняя процедуру считываем входящие символы относящиеся к понятию, либо говорим об ошибке. Если понятие содержит в себе другие понятия, то вызываем их процедуры.

  4. По завершению процедуры коном становится первый символ выходящий за рамки понятия.

От перепутья к перепутью, часть первая: Порядковый разбор КС-языков методом рекурсивного спуска Рекурсия, Спуск, Урок, Программирование, ВКонтакте (ссылка), Длиннопост

Кон в начале и конце работы процедуры понятия «целое».

Первой вызывается процедура стартового понятия, то есть стартового неконечного символа грамматики. Первый кон - первый символ входящей цепочки. По окончанию процедуры поток символов должен быть завершён. Общий вид можно описать так:

От перепутья к перепутью, часть первая: Порядковый разбор КС-языков методом рекурсивного спуска Рекурсия, Спуск, Урок, Программирование, ВКонтакте (ссылка), Длиннопост

Псевдокот

Название «рекурсивный спуск» исходит из того, что при наличии самовложения в грамматике вызовы процедур будут рекурсивными. Распознавание начинается со стартового неконечного, поэтому разбор нисходящий.

На прошлом уроке мы рассматривали рисунок порядка, так вот каждый его отдел представляет из себя схему алгоритма отдельной процедуры. Ниже в таблице участки отдела обозначены: У, У₁, У₂, …, Уₙ. Их соответствующие фрагменты процедуры: Ф(У), Ф(У₁), Ф(У₂), … Ф(Уₙ), будем считать что они вынесены в свои процедуры:

От перепутья к перепутью, часть первая: Порядковый разбор КС-языков методом рекурсивного спуска Рекурсия, Спуск, Урок, Программирование, ВКонтакте (ссылка), Длиннопост

Следуя по отделу рисунка.

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

В следующей статье мы рассмотрим разбор арифметических выражений.

З. Ы. Минутка этимологии: Слово процедура происходит от лат. procedere, которое состоит из pro и cedere. Сedere значит «идти» или «двигаться», pro - «вперёд», от сюда procedere - продвигаться, проходить. Слово рекурсия происходит от лат. recursio, re - указывает на повторность действия, так же как «пере», cursio однокоренное с cursus - курс, путь, то есть recursio - это перепутье, только в том узком смысле, что пересечение дороги ведёт к той же дороге.
Не забудь подписаться.

UPD:

Читать далее...

Показать полностью 3
383

Горячие клавиши пикабу

D или В - перейти к посту ниже.
A или Ф - перейти к посту выше.
C или С - прокрутить вниз.
Z или Я - прокрутить вверх.
X или Ч - к началу поста.
S или Ы - поставить посту минус.
W или Ц - поставить посту плюс.
F или А - раскрыть длинопост.

Поставь Ц или Ы если пост так себе. Верните отображение Ы!

2

Синтаксические диаграммы КС-языков - Рисунок порядка КС-языков

Предыдущая статья: Автомат с магазинной памятью (стог-памятью) и КС-языки в vk.com

Статья для повторения:Синтаксические диаграммы автоматных языков - рисунок порядка автоматных языков в vk.com

Чтобы построить рисунок порядка по КС-грамматике следует соблюдать:

  1. Каждому неконечному строится свой отдел, помеченный именем символа.

  2. Неконечные из правил вывода вписывают в прямоугольники, а конечные в круги или овалы.

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

  4. Ветви образованные одним неконечным, соединяются параллельно и образуют один отдел.

Рассмотрим правила: А → БвГд | а

Синтаксические диаграммы КС-языков - Рисунок порядка КС-языков Программирование, Урок, Грамматика, Синтаксис, ВКонтакте (ссылка), Длиннопост

А → а

Простейший случай А→ а, имеем ветвь из одного конечного символа а.
Продолжим:

Синтаксические диаграммы КС-языков - Рисунок порядка КС-языков Программирование, Урок, Грамматика, Синтаксис, ВКонтакте (ссылка), Длиннопост

А → БвГд

Тут описана ветвь А → БвГд, Б и Г неконечные символы поэтому заключены в прямоугольники, в и д конечные поэтому в круги. Обе ветви следует объединить параллельно:

Синтаксические диаграммы КС-языков - Рисунок порядка КС-языков Программирование, Урок, Грамматика, Синтаксис, ВКонтакте (ссылка), Длиннопост

А → БвГд | а

Отдел А завершён. Но мы имеем ещё два неконечных Б и Г, поэтому следует отобразить и их отделы. Пусть Б описывает Б → в | дБ , а Г → eБГ | ε. Отобразим их:

Синтаксические диаграммы КС-языков - Рисунок порядка КС-языков Программирование, Урок, Грамматика, Синтаксис, ВКонтакте (ссылка), Длиннопост

Б → дБ|в , Г → еБГ|ε

Почти закончили, обратите внимание на правила Б → дБ и Г → еБГ, что между ними общего? Внутри этих правил встречается одноименный неконечный символ и он находится справа от всех символов. Такие правила называют праворекурсивными. Для этих неконечных у нас есть альтернативы Б → в , Г → ε, что нам говорит о необязательности вхождения левых символов праворекурсивных правил. Мы можем упростить отделы избегая рекурсии (перепутья), заменяя на циклы:

Синтаксические диаграммы КС-языков - Рисунок порядка КС-языков Программирование, Урок, Грамматика, Синтаксис, ВКонтакте (ссылка), Длиннопост

Упрощённые отделы

Отобразим полный рисунок и на этом урок завершён.

Синтаксические диаграммы КС-языков - Рисунок порядка КС-языков Программирование, Урок, Грамматика, Синтаксис, ВКонтакте (ссылка), Длиннопост

Рисунок порядка КС-языка.

З.Ы. ε (эпсилон) - это пустая цепочка, теперь более понятно воспринимаю книгу «О дивный новый мир». Подписывайся, пройденный урок поможет нам разобраться в рекурсивном спуске.

UPD:

Читать далее...

Показать полностью 6
Отличная работа, все прочитано!