Интерпретатор псевдокода?


Как и многие из вас, ребята на SO, я часто пишу на нескольких языках. И когда дело доходит до планирования (или даже ответов на некоторые вопросы SO), я действительно думаю и пишу на каком-то неопределенном гибридном языке. Хотя раньше меня учили делать это с помощью блок-схем или UML-подобных диаграмм, в ретроспективе я нахожу, что " мой " язык псевдокодов имеет компоненты C, Python, Java, bash, Matlab, perl, Basic. Я, кажется, бессознательно выбираю идиому, наиболее подходящую для выражения концепция / алгоритм.

Распространенные идиомы могут включать Java-подобные фигурные скобки для scope, pythonic list Integrations или indentation, C++как наследование, c#-стиль lambdas, MATLAB-подобные срезы и матричные операции.

Я заметил, что на самом деле людям довольно легко распознать, что именно я пытаюсь сделать, и довольно легко для людей разумно перевести на другие языки. Конечно, этот шаг предполагает рассмотрение угловых случаев и моментов, когда каждый язык ведет себя своеобразно. Но на самом деле большинство этих языков объединяет подмножество ключевых слов и библиотечных функций, которые обычно ведут себя одинаково-математические функции, имена типов, while/for/if и т.д. Ясно, что я должен был бы исключить многие "странные" языки, такие как lisp, производные APL, но...

Итак, мои вопросы таковы:

  1. Существует ли уже код, который распознает язык программирования текстового файла? (Конечно, это должно быть менее сложным задача, чем синтаксические деревья eclipse или функция угадывания языка google translate, верно?) На самом деле, делает ли так синтаксический маркер что-нибудь подобное?

  2. Возможно ли теоретически создать единственный интерпретатор или компилятор, который распознает, какую языковую идиому вы используете в любой момент и (возможно, "разумно") выполняет или переводит в управляемую форму. И помечает угловые случаи, когда мой синтаксис неоднозначен в отношении поведения. Немедленный трудности я вижу следующие: зная, когда, чтобы переключиться между абзацный отступ-зависимые и лямками-зависимые режимы, признавая смешно операторов (например, *pointer против *kwargs) и, зная, когда использовать список против массивов представлений.

  3. Существует ли какой-либо язык или переводчик, который может управлять этим видом гибкого перевода?

  4. Неужели я упустил очевидное препятствие на пути к тому, чтобы это стало возможным?

Edit

Спасибо всем за ваш ответы и идеи. Я планирую написать эвристический переводчик на основе ограничений, который мог бы, потенциально , "решить" код для предполагаемого значения и перевести в реальный код python. Он заметит ключевые слова из многих распространенных языков и будет использовать синтаксические подсказки, чтобы устранить двусмысленность намерений человека - такие как интервалы, скобки, необязательные вспомогательные слова, такие как let или then, контекст того, как переменные ранее использовались и т. д., а также знание общих конвенций (например, заглавные имена, i для итерации и некоторого упрощенного ограниченного понимания именования переменных / методов, например, содержащих слово get, asynchronous, count, last, previous, my и т.д.). В реальном псевдокоде именование переменных так же информативно, как и сами операции!

Используя эти подсказки, он создаст предположения относительно реализации каждой операции (например, индексирование на основе 0/1, когда следует перехватывать или игнорировать исключения, какие переменные должны быть const / global / local, где начинать и заканчивать выполнение, и какие биты должны быть в отдельных потоках, обратите внимание, когда числовые единицы совпадают / нуждаются в преобразовании). Каждое предположение будет иметь заданную определенность - и программа будет перечислять предположения на каждом утверждении, поскольку она связывает то, что вы пишете в нечто исполняемое!

Для каждого предположения вы можете "уточнить" свой код, если вам не нравится первоначальная интерпретация. Вопрос библиотек очень интересен. Мой переводчик, как и некоторые IDE, будет читать все определения, доступные из все модули, используйте некоторую статистику о том, какие классы / методы используются наиболее часто и в каких контекстах, и просто угадайте! (добавляя заметку в программу, чтобы сказать, почему он угадал как таковой...) Я думаю, что он должен попытаться выполнить все, и предупредить вас о том, что ему не нравится. Он долженразрешить что-либо , но дать вам знать, каковы несколько альтернативных интерпретаций, если вы двусмысленны.

Конечно, пройдет некоторое время, прежде чем он сможет справиться с такими необычными примерами. например, пример @Albin Sunnanbo ImportantCustomer. Но я дам вам знать, как у меня дела!
7 14

7 ответов:

  1. чтобы определить, какой язык программирования используется: определение языка программирования из фрагмента
  2. я думаю, что это должно быть возможно. Подход в 1. думаю, для этого можно было бы использовать рычаги. Я бы попытался сделать это итеративно: определить синтаксис, используемый в первой строке/предложении кода, "скомпилировать" его в промежуточную форму на основе этого обнаружения, а также любой важный синтаксис (например, начальные / конечные оболочки). Затем следующая строка / предложение и т. д. В основном пишем парсер, который пытается распознавать каждый "кусок". Двусмысленность может быть отмечена тем же алгоритмом.
  3. я сомневаюсь, что это было сделано ... похоже, что когнитивная нагрузка от обучения написанию, например, совместимого с python псевдокода будет намного легче, чем пытаться отладить случаи, когда ваш интерпретатор терпит неудачу.
  4. A. я думаю, что самая большая проблема заключается в том, что большинство псевдокодов недопустимо в любом языке. Например, я мог бы полностью пропустить инициализацию объекта в блоке псевдокода, потому что для человека-читателя это почти всегда легко сделать вывод. Но в вашем случае это может быть совершенно недопустимо в синтаксисе языка выбора, и может быть невозможно автоматически определить, например, класс объекта (он может даже не существовать). И т.д.
    b. Я думаю, что лучшее, на что вы можете надеяться, - это интерпретатор, который "работает" (в соответствии с 4a) только для вашего псевдокода, и больше ни для кого.
Обратите внимание,что я не думаю, что 4a, 4b обязательно препятствуют тому, чтобы это было возможно. Я просто думайте, что это не будет полезно для какой-либо практической цели.

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

В C# У вас есть .NET Framework, в C++ У вас есть STL, в Java у вас есть некоторые библиотеки Java и т. д.

Разница между этими библиотеками слишком велика, чтобы будьте просто синтаксическими нюансами.


Предпринимались попытки унифицировать языковые конструкции разных языков до "единого синтаксиса". Это называлось4gl языком и никогда не принималось всерьез.
субъективное>

В качестве дополнительной заметки я видел пример кода длиной в страницу, который был действителен как код c#, Java и Java script. Это может служить примером того, где невозможно определить фактический язык. использованный.

Правка:

Кроме того, вся цель псевдокода состоит в том, что он не нуждается в компиляции каким-либо образом. Причина, по которой вы пишете псевдокод, заключается в создании "эскиза", каким бы небрежным он вам ни нравился.
foreach c in ImportantCustomers{== OrderValue >=$1M}
    SendMailInviteToSpecialEvent(c)
Теперь скажите мне, что это за язык, и напишите для него переводчика.

Распознавание языка, на котором написана программа, на самом деле не так уж и важно. Распознавать язык фрагмента сложнее, а распознавать фрагменты, которые не имеют четких границ (что делать, если четыре строки-Python, а следующая-C или Java?) будет очень трудно.

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

Более того, когда вы пишете псевдокод, вы не беспокоитесь о синтаксисе. (Если да, то вы делаете это неправильно.) Вы получите код, который просто не может быть скомпилирован, потому что он неполон или даже противоречив. И если предположить, что вы преодолели все эти препятствия, насколько вы уверены, что псевдокод интерпретируется так, как вы думаете?

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

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

Программы, интерпретирующие человеческий ввод, должны иметь возможность сказать: "я не знаю."Язык PL / I-это известный пример системы, предназначенной для поиска разумной интерпретации чего-либо, напоминающего компьютерную программу, которая может вызвать хаос, когда она ошибается: см. http://horningtales.blogspot.com/2006/10/my-first-pli-program.html

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

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

Интересным подходом был бы интерпретатор псевдокода типа "type-as-you-go". То есть вы бы заранее настроили язык для использования, а затем попытались бы преобразовать псевдокод в реальный код, в реальном времени, как вы набираете. Интерактивное средство может быть использовано для прояснения неоднозначных вещей и внесения коррективов. Частью механизма могла быть библиотека кода, которую преобразователь пытался сопоставить. Со временем он мог бы изучить и адаптировать свой перевод, основанный на привычках человека. конкретный пользователь.

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

- Нил

Существует ли уже код, который распознает язык программирования из текстового файла?

Да, Unix file командование.

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

Насколько я могу судить, так же есть универсальный синтаксический маркер, который пытается объедините ключевые слова и синтаксис комментариев каждого основного языка. Иногда он ошибается:

def median(seq):
    """Returns the median of a list."""
    seq_sorted = sorted(seq)
    if len(seq) & 1:
        # For an odd-length list, return the middle item
        return seq_sorted[len(seq) // 2]
    else:
        # For an even-length list, return the mean of the 2 middle items
        return (seq_sorted[len(seq) // 2 - 1] + seq_sorted[len(seq) // 2]) / 2
Обратите внимание, что маркер SO предполагает, что // запускает комментарий в стиле C++, но в Python это оператор целочисленного деления. Это будет серьезной проблемой, если вы попытаетесь объединить несколько языков в один. Что делать, если одна и та же лексема имеет разное значение в разных языках? Аналогичные ситуации:
  • - это ^ возведение в степень, как в Базовый или побитовый XOR, как в C?
  • является ли || логическим или как в C, или конкатенация строк, как в SQL?
  • Что такое 1 + "2"? Преобразуется ли число в строку (давая "12"), или строка преобразуется в число (давая 3)?

Есть ли какой-либо язык или переводчик в существовании, которое может управлять этим своего рода гибкий перевод?

На другом форуме я услышал историю компилятора (IIRC, для FORTRAN), который будет компилировать любая программа, независимо от синтаксических ошибок. Если бы у вас была строка

= Y + Z
Компилятор распознает, что переменная отсутствует, и автоматически преобразует оператор в X = Y + Z, независимо от того, есть ли X в вашей программе или нет. У этого программиста было соглашение о начале блоков комментариев со строкой дефисов, например:
C ----------------------------------------
Но однажды они забыли ведущую строку C, и компилятор захлебнулся, пытаясь добавить десятки переменных. между тем, что он считал операторами вычитания.

"гибкий синтаксический анализ" - это не всегда хорошо.