Я пытаюсь написать Pyparsing код, способный разбора кода Python (я знаю, что модуль AST существует, но это будет лишь отправной точкой. - Я в конечном счете хочу разобрать больше, чем просто код Python)Анализ кода Python с помощью PyParsing?
в любом случае, я полагаю, я просто начать писать что-то, способное анализировать классический
print("Hello World!")
Так вот что я писал:
from pyparsing import (alphanums, alphas, delimitedList, Forward,
quotedString, removeQuotes, Suppress, Word)
expr = Forward()
string = quotedString.setParseAction(removeQuotes)
call = expr + Suppress('(') + Optional(delimitedList(expr)) + Suppress(')')
name = World(alphas + '_', alphanums + '_')
expr <<= string | name | call
test = 'print("Hello World!")'
print(expr.parseString(test))
Когда я сделать это, хотя, это просто выплевывает:
['print']
Какая технически действительная expr
- вы можете ввести ее в REPL, и нет никакой проблемы в ее анализе, даже если это бесполезно.
Так что я подумал, может быть, что я хочу, чтобы перевернуть вокруг name
и call
в моем expr
определению, поэтому предпочел бы возвращение call
с до name
с, как это:
expr <<= string | call | name
Теперь я получаю максимум глубина рекурсии превысила ошибку. Это также имеет смысл:
- Проверяет, является ли это
expr
.- Проверяет, является ли это
string
, это не так. - Проверяет, является ли это
call
.- Необходимо набрать
expr
, вернитесь к началу внешнего списка.
- Необходимо набрать
- Проверяет, является ли это
Так что мой вопрос ... как я могу определить call
и expr
так, что я не в конечном итоге с бесконечной рекурсии, но и так, что он не останавливается, когда он видит имя и игнорирует аргументы?
Является ли код Python слишком сложным для обработки PyParsing? Если нет, существует ли ограничение на то, что PyParsing может обрабатывать?
(Примечание. - Я включил общие тег parsing, abstract-syntax-tree и bnf, потому что я подозреваю, что это общерекурсивная проблема определения грамматики, а не что-то обязательно специфично для pyparsing)
Моя догадка, что ваш код не используя терминалы, и поэтому будет анализировать один и тот же токен снова и снова, что приведет к бесконечной рекурсии. Я не знаю pyparsing, но этот [образец анализатора Python] (http://pyparsing.wikispaces.com/file/view/pythonGrammarParser.py/30100174/pythonGrammarParser.py) на домашней странице PyParsing потребляет разобранные терминалы , – msw
Разбор произвольного (более чем просто Python) исходного кода на самом деле тяжелый; вам приходится иметь дело со многими, многими вопросами, наименьшее из которых состоит в том, что атомы составляют ваш язык. Когда вы «разобрали» что-то, тогда вам не будет достаточно, чтобы сделать много полезного на практике. Посмотрите мою биографию на тему «Life After Parsing» (в которой также говорится о проблемах синтаксического анализа). –
@IraBaxter - Ваша жизнь после анализа предполагает, что я хочу делать более сложные вещи, чем я. Я ищу, чтобы писать инструменты, чтобы идти назад и вперед между АСТ и Струнами - ничего больше. Я не хочу анализировать его. Кроме того, мне нужно бесплатно распространять все в исходной форме - я не покупаю ваш продукт, независимо от того, насколько он отлично работает, что мне нужно. – ArtOfWarfare