Интерпретатор псевдокода? - PullRequest
16 голосов
/ 14 сентября 2010

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

Распространенные идиомы могут включать в себя Java-подобные скобки для области видимости, понимания или отступа в Python-списках, C ++ -подобное наследование, лямбда-символы в стиле C #, matlab-подобные фрагменты и матричные операции.

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

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

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

  1. Уже существует код, который распознает язык программирования текстового файла? (Конечно, это должно быть менее сложной задачей, чем синтаксические деревья затмения или функция угадывания языка Google Translate, не так ли?) В действительности, подсветка синтаксиса SO делает что-то подобное?

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

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

  4. Я пропустил очевидное препятствие для возможности этого?

редактировать

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

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

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

Ответы [ 8 ]

3 голосов
/ 14 сентября 2010
  1. Чтобы определить, какой язык программирования используется: Определение языка программирования по фрагменту
  2. Я думаю, это должно быть возможно. Я думаю, что подход 1. может быть использован для этого. Я бы попытался сделать это итеративно: определить синтаксис, использованный в первой строке / предложении кода, «скомпилировать» его в промежуточную форму, основанную на этом обнаружении, вместе с любым важным синтаксисом (например, обертки begin / end). Затем следующая строка / предложение и т. Д. В основном напишите синтаксический анализатор, который пытается распознать каждый «кусок». Неоднозначность может быть помечена тем же алгоритмом.
  3. Я сомневаюсь, что это было сделано ... похоже на когнитивную нагрузку обучения письму, например. Python-совместимый псевдокод будет намного проще, чем пытаться отлаживать случаи, когда ваш интерпретатор не работает.
  4. а. Я думаю, что самая большая проблема заключается в том, что большинство псевдокодов является недействительным на любом языке. Например, я мог бы полностью пропустить инициализацию объекта в блоке псевдокода, потому что для читателя-человека это почти всегда просто сделать вывод. Но для вашего случая это может быть совершенно недопустимым в выбранном синтаксисе языка, и может оказаться невозможным автоматическое определение, например, класс объекта (он может даже не существовать). И т.д.
    б. Я думаю, что лучшее, на что вы можете надеяться, это интерпретатор, который «работает» (при условии 4a) только для вашего псевдокода, а не для кого-либо еще.

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

3 голосов
/ 14 сентября 2010

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

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

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


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

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

Редактировать:

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

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

2 голосов
/ 14 сентября 2010

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

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

2 голосов
/ 14 сентября 2010

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

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

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

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

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

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

1 голос
/ 03 апреля 2019

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

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

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

Аналогично, язык программирования Seed7 может быть расширен для анализа «псевдокода» с помощью « определений структурированного синтаксиса ». Цикл while в Seed7 определяется следующим образом:

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

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

1 голос
/ 17 сентября 2010

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

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

(Конечно, это должно быть менее сложной задачей, чем синтаксические деревья затмения или функция угадывания языка в Google Translate, не так ли?) Фактически, подсветка синтаксиса 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 предполагает, что // запускает комментарий в стиле C ++, но в Python это оператор целочисленного деления.

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

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

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

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

= Y + Z

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

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

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

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

«Гибкий синтаксический анализ» - не всегда хорошая вещь.

1 голос
/ 14 сентября 2010

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

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

1 голос
/ 14 сентября 2010

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

...