Какой инструмент использовать для анализа языков программирования в Python?
Какой инструмент Python вы можете порекомендовать для разбора языков программирования? Это должно позволить читаемое представление языковой грамматики внутри источника, и оно должно быть способным масштабироваться до сложных языков (что-то с грамматикой столь же сложной, как, например, сам Python).
Когда я ищу, я в основном нахожу pyparsing, который я буду оценивать, но, конечно, меня интересуют другие альтернативы.
Изменить: бонусные точки, если они содержат хорошие отчеты об ошибках и местоположения исходного кода, прикрепленные к элементам дерева синтаксиса.
Ответы
Ответ 1
Мне действительно нравится pyPEG. Его отчет об ошибках не очень дружелюбен, но он может добавлять местоположения исходного кода в AST.
pyPEG не имеет отдельного лексера, что сильно затруднит синтаксический анализ Python (я думаю, что CPython распознает отступ и разделитель в lexer), но я использовал pyPEG для создания парсера для подмножества С# с удивительно маленькой работой.
Пример, адаптированный из fdik.org/pyPEG/: простой язык:
function fak(n) {
if (n==0) { // 0! is 1 by definition
return 1;
} else {
return n * fak(n - 1);
};
}
Парсер pyPEG для этого языка:
def comment(): return [re.compile(r"//.*"),
re.compile("/\*.*?\*/", re.S)]
def literal(): return re.compile(r'\d*\.\d*|\d+|".*?"')
def symbol(): return re.compile(r"\w+")
def operator(): return re.compile(r"\+|\-|\*|\/|\=\=")
def operation(): return symbol, operator, [literal, functioncall]
def expression(): return [literal, operation, functioncall]
def expressionlist(): return expression, -1, (",", expression)
def returnstatement(): return keyword("return"), expression
def ifstatement(): return (keyword("if"), "(", expression, ")", block,
keyword("else"), block)
def statement(): return [ifstatement, returnstatement], ";"
def block(): return "{", -2, statement, "}"
def parameterlist(): return "(", symbol, -1, (",", symbol), ")"
def functioncall(): return symbol, "(", expressionlist, ")"
def function(): return keyword("function"), symbol, parameterlist, block
def simpleLanguage(): return function
Ответ 2
pyPEG (инструмент, который я создал) имеет средство отслеживания отчетов об ошибках.
Просто установите pyPEG.print_trace = True
, и pyPEG даст вам полный след того, что происходит внутри.
Ответ 3
Antlr - это то, что вы должны посмотреть на http://www.antlr.org
Взгляните на это http://www.antlr.org/wiki/display/ANTLR3/Antlr3PythonTarget
Ответ 4
Для более сложного анализатора я буду использовать pyparsing.
Pyparsing
Вот приведенный пример из домашней страницы
from pyparsing import Word, alphas
greet = Word( alphas ) + "," + Word( alphas ) + "!" # <-- grammar defined here
hello = "Hello, World!"
print hello, "->", greet.parseString( hello )
Ответ 5
Я бы порекомендовал вам проверить мою библиотеку: https://github.com/erezsh/lark
Он может анализировать ВСЕ контекстно-свободные грамматики, автоматически создает AST (с номерами строк и столбцов) и принимает грамматику в формате EBNF, который считается стандартным.
Он легко анализирует язык, такой как Python, и может делать это быстрее, чем любая другая библиотека синтаксического анализа, написанная на Python.
Ответ 6
Если вы оцениваете PyParsing, я думаю, вы должны посмотреть на funcparserlib: http://pypi.python.org/pypi/funcparserlib
Это немного похоже, но по моему опыту результирующий код намного чище.
Ответ 7
Ned Batchelder сделал обзор инструментов анализа python, которые, по-видимому, он постоянно обновляется (последнее обновление в июле 2010 года):
http://nedbatchelder.com/text/python-parsers.html
Если бы мне понадобился синтаксический анализатор сегодня, я бы либо сгенерировал собственный рекурсивный парсер спуска, либо, возможно, использовал PLY или LEPL - в зависимости от моих потребностей и был ли я готов ввести внешнюю зависимость. Я бы лично не использовал PyParsing для чего-то очень сложного.
Ответ 8
Для простой задачи я склонен использовать модуль shlex.
См. http://wiki.python.org/moin/LanguageParsing для оценки синтаксического анализа языка в python.
Ответ 9
Antlr генерирует парсы LL (*). Это может быть хорошо, но иногда удаление всей левой рекурсии может быть громоздким.
Если вы LALR (1) -savvy, вы можете использовать PyBison. Он имеет аналогичный синтаксис для Yacc, если вы знаете, что это такое. Кроме того, есть много людей, которые знают, как работает yacc.