Языковые парсеры - PullRequest
       8

Языковые парсеры

3 голосов
/ 15 апреля 2010

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

Какие парсеры для этих языков предусмотрены?

Для C # я нашел http://csparser.codeplex.com/Wikipage, но для остальных я нашел группу синтаксических анализаторов, использующих эти языки, но не парсеры языков для них.

Ответы [ 4 ]

6 голосов
/ 15 апреля 2010

Для Python ситуация тривиальна: в стандартной библиотеке есть анализатор Python , а также более высокоуровневый модуль для управления AST .

Кроме того, Python имеет несколько простую грамматику (по крайней мере, если вы используете трюк, чтобы сохранить стек отступов в своем лексере и внедряете фальшивые токены BEGIN и END в свой поток токенов, так что вы можете рассматривать Python как простое ключевое слово, похожее на Algol-подобный язык в вашем парсере), поэтому его часто используют в качестве примера грамматики для генераторов парсеров, что означает, что вы можете найти буквально десятки парсеров Python практически для каждого генератора парсера, языка программирования и платформы. там. (Например, вот модуль Haskell, реализующий лексер и анализатор Python .)

Для Ruby доступно довольно много анализаторов.

Ruby невероятно трудно анализировать, поэтому, если вам нужна полная точность, вам в значительной степени придется использовать исходный файл грамматики YACC из реализации YARV Ruby. (parse.y в исходном каталоге верхнего уровня. ) Парсер JRuby является производным от этого файла, и это единственный из парсеров реализации, который был специально разработан для использования другие клиенты, а не только сам переводчик. (Например, плагин Eclipse RDT, плагин Eclipse DLTK / Ruby, плагин NetBeans Ruby и подсветка синтаксиса jEdit Ruby используют синтаксический анализатор JRuby.) Для этого парсер JRuby фактически был переупакован как отдельный проект .

Конечно, есть клоны YACC практически для каждого языка на планете. Однако следует помнить, что YARV не использует сгенерированный lex сканер. Он использует рукописный сканер на C, а также грамматика YACC содержит довольно много семантических действий на C. Эти части должны быть повторно реализованы (как они были в JRuby).

Компилятор XRuby является единственной полной реализацией Ruby, которая не использует YARV parse.y, она использует ANTLRv3 грамматику и ANTLRv3 древовидную грамматику , которые были разработаны с нуля. ANTLR может генерировать парсеры для целого ряда языков, включая, например, Java и C #. Однако его Ruby-сервер остро нуждается в некоторой работе.

RedParse - это синтаксический анализатор Ruby, написанный на Ruby, который утверждает, что способен правильно анализировать весь синтаксис Ruby. Например, он используется в инструменте документации YARD Ruby для извлечения имен методов.

ruby_parser - еще один анализатор Ruby в Ruby. Он генерируется из parse.y с помощью генератора синтаксических анализаторов racc, который является частью стандартной библиотеки Ruby.

YARV фактически содержит библиотеку синтаксического анализатора ripper, которая позволяет вам анализировать код Ruby. К сожалению, он полностью недокументирован, поэтому вам нужно разобраться, прочитав сообщений в блоге . За исключением, конечно, отсутствия документов, почти никто остальное еще не разобрался в этом, и написал в блоге.

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

RDoc , генератор документации Ruby, содержит синтаксический анализатор Ruby, который может анализировать достаточно Ruby для извлечения имен методов и некоторых других вещей.

Cardinal - это реализация Ruby для Parrot Virtual Machine . Он еще не запускает весь Ruby, но его парсер должен быть достаточно мощным, чтобы поддерживать все, что вам нужно. (Анализатор написан в движке грамматики Parrot, поэтому вам, очевидно, придется запустить его в Parrot, например, написав инструмент отчетности в Perl6.)

tinyrb - еще одна реализация Ruby, которая не запускает полный Ruby, но содержит лучше написанный синтаксический анализатор , чем YARV. В этом случае синтаксический анализатор использует Генератор синтаксического анализатора грамматики синтаксического анализа выражений leg Иана Пьюмарты .

6 голосов
/ 15 апреля 2010

Возможно, стоит взглянуть на ANTLR генератор синтаксических анализаторов .

На сайте ANTLR вы найдете грамматики для всех трех интересующих вас языков (хотя грамматика Ruby предназначена только для "упрощенной" версии языка).

Следующая трудность может заключаться в том, чтобы адаптировать эти грамматики для конкретного целевого языка , который вы хотите, т. Е. Языка, на котором будут генерироваться сами синтаксические анализаторы.
Язык грамматики ANTLR очень выразителен, что позволяет один для работы с различными контекстно-зависимыми языками. Это делается путем вставки различных фрагментов (на целевом языке) и / или семантических или синтаксических предикатов (также на целевом языке) среди грамматики, подобной EBNF; следовательно, грамматика немного сложнее и может потребоваться адаптация при изменении целевого языка. «Родным» целевым языком ANTLR является Java, но поддерживаются многие другие целевые языки.

В целом, ANTLR представляет собой немного усилий по настройке / кривой обучения , но, поскольку вам нужно иметь дело с 3 языками, это может стоить инвестиций, так как это позволит вам иметь единая структура (над которой у вас есть «полный» контроль), вместо того, чтобы пытаться собрать три, возможно, очень разных, и, возможно, более «заблокированных» парсера, как вы начали делать.

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

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

Еще одно предложение!
См. Larry Lustig ответ! Самоанализ также может упростить многие из ваших задач. Подразумевается, что вам нужно: а) написать свою логику на каждом из базовых языков; б) интегрировать / загружать программы, подлежащие проверке. Все зависит, но, опять же, возможный выход из-под честного - относительно больших инвестиций с помощью формальных грамматических инструментов.

2 голосов
/ 15 апреля 2010

Для Ruby и Python, вы не можете просто проанализировать класс, чтобы узнать имя методов? Вам придется писать одинаковую функциональность на каждом языке, но (по крайней мере, в Python) в этом нет ничего особенного.

1 голос
/ 16 апреля 2010

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

Ответ другого автора здесь говорит о том, что Ruby действительно сложно разобрать. С ++ также, как известно, трудно анализировать. DMS использовался для анализа около 30 других языков, включая полноценный C ++ на нескольких диалектах, поэтому Ruby кажется вполне выполнимым. Тем не менее, DMS не имеет готового синтаксического анализатора для Ruby.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...