Псевдокод-интерпретатор?

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

Общие идиомы могут включать в себя Java-подобные фигурные скобки для области видимости, интерпретации pythonic-списка или отступов, С++-подобный наследование, С# -строчные лямбды, матлаб-подобные срезы и операции с матрицами.

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

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

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

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

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

    /li >
  • Существует ли какой-либо язык или интерпретатор, который может управлять подобным гибким интерпретацией?

  • Я пропустил очевидное препятствие на пути к этому?

изменить

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

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

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

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

Ответ 1

  • Чтобы определить, какой язык программирования используется: Обнаружение языка программирования из фрагмента
  • Я думаю, это должно быть возможно. Я думаю, что подход в 1. может быть использован для этого. Я бы попытался сделать это итеративно: определить синтаксис, используемый в первой строке/разделе кода, "скомпилировать" его в промежуточную форму на основе этого обнаружения вместе с любым важным синтаксисом (например, begin/end wrappers). Затем следующая строка/предложение и т.д. В основном пишите парсер, который пытается распознать каждый "кусок". Неоднозначность может быть отмечена одним и тем же алгоритмом.
  • Я сомневаюсь, что это было сделано... похоже, что когнитивная нагрузка обучения писать, например. python-совместимый псевдокод будет намного проще, чем пытаться отлаживать случаи, когда ваш интерпретатор терпит неудачу.
  • а. Я думаю, самая большая проблема в том, что большинство псевдокодов недействительно на любом языке. Например, я мог бы полностью пропустить инициализацию объекта в блоке псевдокода, потому что для человека-читателя почти всегда можно сделать вывод. Но для вашего случая это может быть совершенно недействительным в синтаксисе языка выбора, и может быть невозможно автоматически определить, например. класс объекта (он может даже не существовать). Etc.
    б. Я думаю, что лучшее, на что вы можете надеяться, - это интерпретатор, который "работает" (с учетом 4a) только для вашего псевдокода, никого другого.

Заметим, что я не думаю, что 4a, 4b обязательно являются препятствиями для этого. Я просто думаю, что это не будет полезно для каких-либо практических целей.

Ответ 2

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

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

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

< субъективная >
Были попытки объединить языковые конструкции разных языков с "унифицированным синтаксисом". Это называется 4GL и никогда не принималось. </& субъективная GT;

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

Edit:

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

Теперь скажите мне, на каком языке он, и напишите для этого переводчика.

Ответ 3

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

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

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

И, предполагая, что вы преодолели все эти препятствия, насколько вы уверены в том, что псевдокод интерпретируется так, как вы думаете?

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

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

Ответ 4

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

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

Ответ 5

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

Ответ 6

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

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

-Neil

Ответ 7

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

Да, команда Unix file.

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

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

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 highlighter предполагает, что // запускает комментарий в стиле С++, но в Python это оператор целочисленного деления.

Это будет серьезной проблемой, если вы попытаетесь объединить несколько языков в один. Что вы делаете, если один и тот же токен имеет разные значения на разных языках? Аналогичные ситуации:

  • Является выражением ^, как в BASIC, или побитовым XOR, как в C?
  • Является ли || логическим ИЛИ как в C, или конкатенацией строк, как в SQL?
  • Что такое 1 + "2"? Число, преобразованное в строку (дающее "12" ), или строка преобразуется в число (давая 3)?

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

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

= Y + Z

Компилятор распознает, что переменная отсутствовала, и автоматически конвертирует оператор в X = Y + Z, независимо от того, был ли у вас X в вашей программе или нет.

У этого программиста было соглашение о начале блоков комментариев с линией дефисов, например:

C ----------------------------------------

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

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

Ответ 8

Чтобы создать "интерпретатор псевдокода", может потребоваться разработка языка программирования, который допускает пользовательские расширения его синтаксиса. Уже есть несколько языков программирования с этой функцией, такие как Coq, Seed7, Agda и Lever. Особенно интересным примером является язык программирования Inform, поскольку его синтаксис по сути является "структурированным английским".

Язык программирования Coq допускает " расширения синтаксиса ", поэтому язык может быть расширен для анализа новых операторов:

Notation "A/\ B" := (and AB).

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

syntax expr:.while.().do.().end.while is → 25;

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