2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1 ... 3, 4, 5, 6, 7, 8, 9 ... 11  След.
 
 Re: Тьюринг-полон ли данный язык
Сообщение25.03.2020, 00:00 
Заслуженный участник


27/04/09
28128
Вот регистровая машина, которую можно было бы немного допилить и компилировать в неё высокоуровневый язык. Можно например сделать, чтобы она подсчитывала число шагов, за которые проделано вычисление. В свою очередь её саму можно было бы не выполнять как есть, а компилировать в например питоновский код, хотя лучше в него компилировать более высокоуровневое представление.

 Профиль  
                  
 
 Re: Тьюринг-полон ли данный язык
Сообщение25.03.2020, 09:27 


21/05/16
4292
Аделаида
Уф, сложновато ее понять.. А что она делает?

 Профиль  
                  
 
 Re: Тьюринг-полон ли данный язык
Сообщение25.03.2020, 17:51 
Заслуженный участник


27/04/09
28128
Там есть реализация регистровой машины и есть внизу маленький тест/пример, что она вообще хоть насколько-то работает и как.

Регистровая машина имеет какой-то набор состояний State, для простоты в коде это синоним int, в каждом из которых будет выполнена одна из допустимых команд Op над содержимым регистров, содержащих каждый по одному множеству. Команда также при выполнении выдаст, в какое следующее состояние надо перейти машине, и None означает, что пора остановиться. По тому, что позволяет исходная версия языка, я подобрал такие команды:

• Выполнить над значениями двух регистров операцию +, *, - или ~. Ради экономии и здравого смысла эти четыре команды представляются одной, к которой добавлен параметр—тип операции (его задаёт BinOpType).
• Скопировать значение из одного регистра в другой. Можно выразить через + или *, но пускай.

• Установить значение регистра в []. Опять же можно выразить через ~ или -, но опять же пускай, микрооптимизация не отпускает.
• Добавить к значению в регистре как элемент значение из другого регистра. Эта команда вместе с предыдущей позволят получать значения, представленные в коде литералами [x1, x2, ...]: взять пустое и надобавлять по очереди x1, x2 и т. д..

• Проверить, пустое ли множество в регистре, и перейти в одно или другое состояние в зависимости от этого.
• Попробовать разобрать множество в регистре на $\{x\}\cup s$, и если оно пустое, перейти в одно состояние, а если разбирается, присвоить $x$ одному регистру, $s$ другому и перейти в другое состояние. Опять же предыдущую команду можно было бы не вводить, ограничившись этой, но не хочется заставлять при каждом ife или whilene сначала вычислять $x, s$, а потом ещё вводить мусорный регистр, куда эти значения выкинуть.

• Сделать assert, и если он не выполняется, выдать ошибку; машина умеет показывать, что работа была прервана из-за ошибки и выдавать её, и эту команду я добавил, чтобы был пример команды, имеющей возможность ошибку вызвать (остальные в этом наборе всегда куда-нибудь дальше переходят).

Машину можно пускать (изначально с нулевых значений регистров) пошагово, сразу до конца (если она завершится), и наконец запустить её, придав переданные значения некоторым регистрам, которые будут считаться входными, и после окончания работы выдав значения из каких-то ещё регистров, которые будут таким образом выходными (один и тот же может быть и входным, и выходным, хотя для компиляции это будет нежелательно). Какие регистры при таком запуске считать входными и выходными и в каком порядке соотносить с передаваемыми значениями, задаёт IOSpec. И кстати я забыл добавить способ изменять значения регистров просто так, не как часть последнего метода, ну да ладно, он вряд ли будет нужен.

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

Машина-пример в самом низу реализует сложение натуральных чисел, закодированных моим способом, и выводит исходные числа и результат и в виде множеств, и в их численной интерпретации.

Комментарий в HFSet.deconstruct, если интересно, но не совсем ясно, о том, что если реализовать множества в явную кортежами, в которых значения отсортированы, то можно будет легко отсоединять наименьший или наибольший элемент и выдавать остаток, в то время как интерфейс стандартных множеств из библиотеки такой возможности не содержит (деревьями ли они реализованы или хеш-таблицами, это действительно не будет эффективной операцией, хотя может быть некоторые виды деревьев наверно что-то такое позволяют) (ну можно взять мутабельное множество, взять его копию, сделать с ней pop(), но это не то).

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

 Профиль  
                  
 
 Re: Тьюринг-полон ли данный язык
Сообщение25.03.2020, 21:13 


21/05/16
4292
Аделаида
Ага, т.е. это псевдоаппаратная реализация для нашего языка?

 Профиль  
                  
 
 Re: Тьюринг-полон ли данный язык
Сообщение25.03.2020, 21:18 
Заслуженный участник


27/04/09
28128
Ага.

 Профиль  
                  
 
 Re: Тьюринг-полон ли данный язык
Сообщение25.03.2020, 21:43 


21/05/16
4292
Аделаида
Круто. Значит, теперь надо написать компилятор языка в "машинный код". Попробую...

 Профиль  
                  
 
 Re: Тьюринг-полон ли данный язык
Сообщение25.03.2020, 21:47 
Заслуженный участник


27/04/09
28128
(Но вообще неплохо было бы компилировать, раз тут у нас циклы, условные операторы и прочее, в уже питоновский байткод. Там был какой-то модуль чтобы сразу порождать синтаксическое дерево, ast вроде, и верхнеуровневые compile и exec, eval дальше. Однако эту цель стоит признать отдельной.)

 Профиль  
                  
 
 Re: Тьюринг-полон ли данный язык
Сообщение26.03.2020, 17:42 


21/05/16
4292
Аделаида
Я пока еще раз прочитал https://ruslanspivak.com/lsbasi-part1. Попробую завтра БНФ написать и начать писать (на самом деле, почти полностью скопировать и чуть-чуть поправить) лексер и парсер. Сам компилятор попробую написать позже.

 Профиль  
                  
 
 Re: Тьюринг-полон ли данный язык
Сообщение26.03.2020, 18:47 
Заслуженный участник


27/04/09
28128
Я бы предложил лексер писать, опираясь на регулярные выражения. Вкратце можно сделать так:
• Для каждого вида токена пишется регэксп, которому только такие токены соответствуют (и для оптимизации каждый регэксп заранее компилируется, чтобы не надеяться на пул скомпилированных).
• Они упорядочиваются так, чтобы спорные случаи типа ife обрабатывались правильно (сначала проверяем, подходит ли ключевое слово, а потом уже считаем произвольным идентификатором).
• Потом когда лексер просят выдать токен из ожидаемого парсером множества токенов, он перебирает их в порядке как выше и каждый пытается поматчить с того места входной строки (ровно с него, используя match(s, pos)), на котором он сейчас остановился. Если найдено совпадение, выдаём токен соответствующего типа с соответствующим текстом и информацией о положении в строке; если мы всё перебрали и ничего не вышло, выдаём ошибку, хотя можно на такой случай придумать специальные ошибочные токены наименьшей возможной длины, которые можно было бы пропускать и, хотя и выдавать ошибку, но продолжить разбор дальше и выдать возможно ещё какие-то оставшиеся ошибки, чтобы не держать пользователя в неведении.

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

Похожая идея стоит за примером лексера в документации к модулю re, но там нельзя дать возможность иметь неоднозначность в выборе токенов, снимаемую тем, что хочет парсер, а не только порядком их пробования. Хотя такое поведение нужно не очень часто.

 Профиль  
                  
 
 Re: Тьюринг-полон ли данный язык
Сообщение26.03.2020, 20:16 


21/05/16
4292
Аделаида
Не совсем уверен, что понял, но попробую...

 Профиль  
                  
 
 Re: Тьюринг-полон ли данный язык
Сообщение27.03.2020, 14:03 


21/05/16
4292
Аделаида
Кстати, вот вопрос возник: если у нас есть функция, которая запрашивает у пользователя ввод, то должен ли компилятор добавить машине еще регистр для ввода? А то ведь он не может узнать, сколько раз запуститься функция...

 Профиль  
                  
 
 Re: Тьюринг-полон ли данный язык
Сообщение27.03.2020, 16:55 


21/05/16
4292
Аделаида
Написал такую БНФ:
https://github.com/LeviPesin/S1-compile ... s1_bnf.txt
arseniiv, проверьте, пожалуйста, нет ли там ошибок.

-- 28 мар 2020, 00:52 --

Я не очень понимаю, как отличать предложенным вами лексером FID, ACTVID и FORMVID...

 Профиль  
                  
 
 Re: Тьюринг-полон ли данный язык
Сообщение27.03.2020, 18:20 


21/05/16
4292
Аделаида
И еще вопрос: каким будет регексп, обрабатывающий множества?

-- 28 мар 2020, 01:57 --

kotenok gav в сообщении #1447679 писал(а):
Я не очень понимаю, как отличать предложенным вами лексером FID, ACTVID и FORMVID...

А, понял ваше сообщение, кажется. Парсер будет давать лексеру определнный список токенов, один из которых он должен искать.

-- 28 мар 2020, 02:18 --

Буду дописывать лексер в ближайшие дни. Проверьте пока ошибки в БНФ и ответьте на
kotenok gav в сообщении #1447701 писал(а):
каким будет регексп, обрабатывающий множества?
, пожалуйста.

 Профиль  
                  
 
 Re: Тьюринг-полон ли данный язык
Сообщение28.03.2020, 00:17 
Заслуженный участник


27/04/09
28128
kotenok gav в сообщении #1447652 писал(а):
Кстати, вот вопрос возник: если у нас есть функция, которая запрашивает у пользователя ввод, то должен ли компилятор добавить машине еще регистр для ввода?
Логичнее по-моему в команде ввода указать регистр, куда вводить, не делая специального вводного регистра для машины. Тогда можно вводить то туда, то сюда по желанию.

Множества я бы не предполагал считать отдельными токенами. Пусть будут [ и ], а собирать из них корректные литералы задача как раз грамматики. Посмотрю БНФ завтра. :-)

 Профиль  
                  
 
 Re: Тьюринг-полон ли данный язык
Сообщение28.03.2020, 09:10 


21/05/16
4292
Аделаида
Лучше все же считать. Если, скажем, мы это будем делать на уровне парсера, у нас получится нетривиальная задача о скобочных послед
довательностях с запятыми и пробелами.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 160 ]  На страницу Пред.  1 ... 3, 4, 5, 6, 7, 8, 9 ... 11  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group