Определение языка программирования по фрагменту - PullRequest
109 голосов
/ 24 января 2009

Как лучше всего определить, какой язык программирования используется во фрагменте кода?

Ответы [ 17 ]

1 голос
/ 24 января 2009

Хорошая головоломка.

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

Бен, много языков с похожим синтаксисом. Так что это зависит от размера фрагмента.

0 голосов
/ 16 февраля 2016

Установите случайный скремблер как

matrix S = matrix(GF(2),k,[random()<0.5for _ in range(k^2)]); while (rank(S) < k) : S[floor(k*random()),floor(k*random())] +=1;
0 голосов
/ 05 февраля 2016

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

У меня есть несколько советов. В настоящее время я пишу небольшой фрагмент кода для моего сайта, который можно использовать для определения языков программирования. Как и большинство других постов, может существовать огромный диапазон языков программирования, которые вы просто не слышали, вы не можете объяснить их все.

Что я сделал, так это то, что каждый язык можно определить по выбору ключевых слов. Например, Python может быть идентифицирован несколькими способами. Возможно, будет проще, если вы выберете «черты», которые также являются уникальными для языка. Для Python я выбрал черту использования двоеточий, чтобы начать набор утверждений, что я считаю довольно уникальной чертой (поправьте меня, если я ошибаюсь).

Если в моем примере вы не можете найти двоеточие для начала набора операторов, перейдите к другой возможной особенности, скажем, используя ключевое слово def, чтобы определить функцию. Теперь это может вызвать некоторые проблемы, поскольку Ruby также использует ключевое слово def для определения функции. Ключом к тому, чтобы отличить два (Python и Ruby) друг от друга, является использование различных уровней фильтрации для достижения наилучшего соответствия. Ruby использует ключевое слово end, чтобы завершить функцию, тогда как Python не имеет ничего, чтобы завершить функцию, только отступ, но вы не хотите туда идти. Но, опять же, end также может быть Lua, еще одним языком программирования, который можно добавить к миксу.

Вы видите, что языки программирования просто слишком сильно перекрывают друг друга. Одно ключевое слово, которое может быть ключевым словом на одном языке, может оказаться ключевым словом на другом языке. Использование комбинации ключевых слов, которые часто сочетаются друг с другом, например, public static void main(String[] args) в Java, помогает устранить эти проблемы.

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

0 голосов
/ 27 июля 2015

Лучшее решение, с которым я столкнулся, - это использование linguist gem в приложении Ruby on Rails. Это своего рода особый способ сделать это, но это работает. Это было упомянуто выше @nisc, но я расскажу вам свои точные шаги для его использования. (Некоторые из следующих команд командной строки относятся к ubuntu, но их легко перевести на другие ОС)

Если у вас есть какое-либо приложение rails, с которым вы не возражаете временно пообщаться, создайте в нем новый файл, чтобы вставить нужный фрагмент кода. (Если у вас не установлены рельсы, есть хорошее руководство здесь , хотя для Ubuntu я рекомендую this . Затем запустите rails new <name-your-app-dir> и перейдите в этот каталог. Все, что вам нужно для запуска приложение rails уже есть).

После того, как у вас есть приложение rails, чтобы использовать это, добавьте gem 'github-linguist' в ваш Gemfile (буквально просто называется Gemfile в каталоге вашего приложения, без ext).

Затем установите ruby-dev (sudo apt-get install ruby-dev)

Затем установите cmake (sudo apt-get install cmake)

Теперь вы можете запустить gem install github-linguist (если вы получите сообщение об ошибке, требующее icu, выполните sudo apt-get install libicu-dev и повторите попытку)

(Вам может потребоваться сделать sudo apt-get update или sudo apt-get install make или sudo apt-get install build-essential, если вышеописанное не сработало)

Теперь все настроено. Теперь вы можете использовать это в любое время, когда хотите проверить фрагменты кода. В текстовом редакторе откройте созданный вами файл, чтобы вставить фрагмент кода (скажем, это app/test.tpl, но если вы знаете расширение своего фрагмента, используйте его вместо .tpl. Если расширение не известно не используйте один). Теперь вставьте свой фрагмент кода в этот файл. Перейдите в командную строку и запустите bundle install (должно быть в каталоге вашего приложения). Затем запустите linguist app/test.tpl (в более широком смысле linguist <path-to-code-snippet-file>). Он скажет вам тип, тип пантомимы и язык. Для нескольких файлов (или для общего использования с приложением ruby ​​/ rails) вы можете запустить bundle exec linguist --breakdown в каталоге вашего приложения.

Это кажется большой дополнительной работой, особенно если у вас еще нет рельсов, но вам на самом деле не нужно знать НИЧЕГО о рельсах, если вы выполните эти шаги, и я просто действительно не нашел лучшего способа определить язык файла / фрагмента кода.

0 голосов
/ 29 октября 2014

Интересно. У меня похожая задача распознать текст в разных форматах. Свойства YAML, JSON, XML или Java? Например, даже с синтаксическими ошибками я должен с уверенностью отличать JSON от XML.

Я понимаю, как мы моделируем проблему критически. Как сказал Марк, токенизация одного слова необходима, но, вероятно, недостаточно. Нам понадобятся биграммы или даже триграммы. Но я думаю, что мы можем пойти дальше, зная, что мы смотрим на языки программирования. Я заметил, что почти любой язык программирования имеет два уникальных типа токенов - символы и ключевые слова . Символы относительно легко распознать (некоторые символы могут быть литералами, не являющимися частью языка). Тогда биграммы или триграммы символов будут подбирать уникальные синтаксические структуры вокруг символов. Ключевые слова - еще одна легкая цель, если учебный набор достаточно большой и разнообразный. Полезной функцией могут быть биграммы вокруг возможных ключевых слов. Еще один интересный тип токена - пробел . На самом деле, если мы будем обычным образом токенизировать по пустому пространству, мы потеряем эту информацию. Я бы сказал, что для анализа языков программирования мы сохраняем пробелы, поскольку они могут содержать полезную информацию о структуре синтаксиса.

Наконец, если я выберу классификатор, такой как случайный лес, я буду сканировать github и собирать весь открытый исходный код. Большая часть файла исходного кода может быть помечена суффиксом файла. Для каждого файла я буду случайным образом разбивать его на пустые строки на фрагменты разных размеров. Затем я извлеку функции и обучу классификатор, используя помеченные фрагменты. После окончания обучения классификатор можно проверить на точность и вспомнить.

0 голосов
/ 28 ноября 2010

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

  • определения функций
  • объявления переменных
  • объявления класса
  • комментарии
  • для петель
  • в то время как петли
  • печать выписок

И, возможно, несколько других вещей, которые должны иметь большинство языков. Тогда используйте систему очков. Награда не более 1 балла за каждый элемент, если найдено регулярное выражение. Очевидно, что некоторые языки будут использовать один и тот же синтаксис (поскольку циклы часто пишутся как for(int i=0; i<x; ++i), так что каждый из нескольких языков может набрать одно очко за одно и то же, но, по крайней мере, вы уменьшаете вероятность того, что он будет совершенно другим языком) , Некоторые из них могут набрать 0 баллов по всем направлениям (например, фрагмент вообще не содержит функции), но это прекрасно.

Объедините это с решением Жюля, и оно должно работать довольно хорошо. Может также искать частоты ключевых слов для дополнительной точки.

0 голосов
/ 24 января 2009

Я бы не подумал, что будет легкий способ сделать это. Возможно, я бы сгенерировал списки символов / общих ключевых слов, уникальных для определенных языков / классов языков (например, фигурные скобки для языка C-стиля, ключевые слова Dim и Sub для языков BASIC, ключевое слово def для Python, ключевое слово let для функциональных языков) , Тогда вы сможете использовать базовые синтаксические функции, чтобы сузить его еще больше.

...