parser — Доступ к деревьям разбора Python


Модуль parser предоставляет интерфейс внутреннему парсеру Python’а и компилятору байта-кода. Основная цель для этого интерфейса состоит в том, чтобы позволить коду Python редактировать дерево разбора выражения Python и создавать выполнимый код из него. Это лучше, чем пытаться разобрать и модифицировать произвольный фрагмент Python кода как строку, потому что парсинг выполняется таким же образом, как и код, формирующие приложение. Это тоже быстрее.

Примечание

Начиная с Python 2.5 и позже, намного более удобно вмешаться в поколении Abstract Syntax Tree (AST) и стадии компиляции, используя модуль ast.

В этом модуле необходимо отметить несколько моментов, важных для использования созданных структур данных. Это не учебное пособие по редактированию деревьев разбора для Python кода, но представлены некоторые примеры использования модуля parser.

Самое главное, требуется хорошее понимание грамматики Python, обрабатываемой внутренним парсер. Полную информацию о синтаксисе языка см. в разделе Справочник по языку Python. Сам парсер создается из грамматической спецификации, определенной в файле Grammar/Grammar в стандартном распределении Python. Деревья синтаксического анализа, сохраненные в объектах ST, созданных этим модулем, являются фактическими выходными данными внутренних парсер, созданных функциями expr() или suite(), описанными ниже. Объекты ST, созданные sequence2st(), точно моделируют эти структуры. Знайте, что значения последовательностей, которые считают «правильными», изменится от одной версии Python другому, поскольку формальная грамматика для языка пересмотрена. Однако перенос код из одной версии Python в другую в качестве исходного текста всегда позволяет создавать правильные деревья синтаксического анализа в целевой версии, при этом единственным ограничением является то, что миграция в более старую версию интерпретатор не будет поддерживать более поздние языковые конструкции. Деревья разбора не типично совместимы от одной версии до другого, хотя источник код обычно был совместим с форвардом в главном ряде выпусков.

Каждый элемент последовательностей возвращенный st2list() или st2tuple() имеет простую форму. Последовательности, представляющие нетерминальные элементы в грамматике, всегда имеют длину больше единицы. Первый элемент является целым числом, которое идентифицирует производство в грамматике. Эти целые числа имеют символические имена в файле заголовка C Include/graminit.h и модуле Python symbol. Каждый дополнительный элемент последовательности представляет компонент производства, распознаваемый во входных строка: это всегда последовательности, имеющие ту же форму, что и родительские. Важным аспектом этой структуры, который следует отметить, является то, что ключевые слова используемый для идентификации типа родительского узла, такого как ключевой if в if_stmt, включаются в дерево узлов без какой-либо специальной обработки. Например, if ключевой представлен кортежем (1, 'if'), где 1 - числовой значение, связанный со всеми токенами NAME, включая имена переменных и функций, определенные пользователем. В альтернативной форме возвращенный при запросе информации о номере строки тот же маркер может быть представлен как (1, 'if', 12), где 12 представляет номер строки, на которой был найден символ терминала.

Терминальные элементы представлены практически таким же образом, но без каких- либо дочерних элементов и добавления исходного текста, который был идентифицирован. Пример if ключевой выше является репрезентативным. Различные типы символов терминала определяются в файле заголовка C Include/token.h и модуле Python token.

Объекты ST не требуются для поддержки функциональности этого модуля, но предоставляются для трех целей: чтобы позволить заявлению амортизировать стоимость обработки комплекса разбирают деревья, чтобы обеспечить представление дерева разбора, которое сохраняет место в памяти по сравнению со списком Python или представлением кортежа, и ослабить создание дополнительных модулей в C, которые управляют деревьями разбора. Простой класс «обертки» может быть создан в Python, чтобы скрыть использование объектов ST.

Модуль parser определяет функции для нескольких различных целей. Самые важные цели состоят в том, чтобы создать объекты ST. и преобразовать объекты ST. в другие представления, такие как деревья разбора и собрали объекты код, но есть также функции, которые служат, чтобы подвергнуть сомнению тип дерева разбора, представленного объектом ST.

См.также

Модуль symbol
Полезные константы, представляющие внутренние узлы дерева синтаксического анализа.
Модуль token
Полезные константы, представляющие конечные узлы дерева синтаксического анализа и функции для тестирования узла значения.

Создание ST-объектов

Объекты ST могут быть созданы из источника код или из дерева синтаксического анализа. При создании объекта ST из источника используемый различные функции для создания форм 'eval' и 'exec'.

parser.expr(source)

Функция expr() анализирует параметр source так, как если бы он был входом в compile(source, 'file.py', 'eval'). Если синтаксический анализ завершается успешно, создается ST объект, содержащий внутреннее представление дерева синтаксического анализа, в противном случае возникает соответствующее исключение.

parser.suite(source)

Функция suite() анализирует параметр source так, как если бы он был входом в compile(source, 'file.py', 'exec'). Если синтаксический анализ завершается успешно, создается ST объект, содержащий внутреннее представление дерева синтаксического анализа, в противном случае возникает соответствующее исключение.

parser.sequence2st(sequence)

Эта функция принимает дерево синтаксического анализа, представленное в виде последовательности, и по возможности создает внутреннее представление. Если это может утвердить это, дерево соответствует грамматике Python, и все узлы - действительные типы узла в версии хозяина Python, объект ST. создан из внутреннего представления и возвращенный к названному. Если возникла проблема с созданием внутреннего представления или дерево не может быть проверено, возникает исключение ParserError. Созданный таким образом ST-объект не следует считать правильно скомпилированным; нормальные исключения, порождаемые компиляцией, могут быть инициированы при передаче объекта ST compilest(). Это может указывать на проблемы, не связанные с синтаксисом (например, исключение MemoryError), но также может быть вызвано конструкциями, такими как результат парсинг del f(0), который выходит из Python парсер, но проверяется компилятором байт-кода.

Последовательности, представляющие маркеры терминала, могут быть представлены либо в виде двухэлементных списков формы (1, 'name'), либо в виде трехэлементных списков формы (1, 'name', 56). Если присутствует третий элемент, предполагается, что он является допустимым номером строки. Номер строки может быть задан для любого подмножества символов клемм во входном дереве.

parser.tuple2st(sequence)

Это та же функция, что и sequence2st(). Эта точка входа поддерживается для обратной совместимости.

Преобразование ST-объектов

ST объекты, независимо от входа используемый, чтобы создать их, может быть преобразован, чтобы разобрать деревья, представленные как список - или кортеж - деревья, или может быть собран в выполнимые объекты код. Деревья синтаксического анализа могут быть извлечены с информацией о нумерации строк или без нее.

parser.st2list(st, line_info=False, col_info=False)

Эта функция принимает объект ST от вызывающего абонента в st и возвращает список Python, представляющий эквивалентное дерево синтаксического анализа. Результирующее представление списка может быть используемый для проверки или создания нового дерева разбора в форме списка. Эта функция не выходит из строя до тех пор, пока имеется память для построения представления списка. Если дерево разбора только будет используемый для контроля, st2tuple() должен быть используемый вместо этого, чтобы уменьшить потребление памяти и фрагментацию. Когда требуется представление списка, эта функция значительно быстрее, чем получение представления кортежа и преобразование его во вложенные списки.

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

parser.st2tuple(st, line_info=False, col_info=False)

Эта функция принимает объект ST. от посетителя в st и возвращает кортеж Python, представляющий эквивалентное дерево разбора. Эта функция, кроме возврата кортежа вместо списка, идентична функции st2list().

Если line_info верен информация о номере линии будет включена для всех предельных символов как третий элемент списка, представляющего символ. Эта информация пропускается, если флаг является ложным или пропущен.

parser.compilest(st, filename='<syntax-tree>')

Компилятор Python байтов может быть вызван на объекте ST для создания объектов код, которые могут быть используемый как часть вызова встроенных функций exec() или eval(). Эта функция предоставляет интерфейс компилятору, передавая внутреннее дерево синтаксического анализа из st в парсер, используя имя исходного файла, указанное параметром filename. значение по умолчанию, поставляемый для filename, указывает, что источник был объектом ST.

Компиляция объекта ST может привести к исключениям, связанным с компиляцией; примером может служить SyntaxError, вызванная деревом синтаксического анализа для del f(0): эта инструкция считается законной в формальной грамматике для Python, но не является правовой языковой конструкцией. SyntaxError, поднятый для этого условия, на самом деле обычно производится компилятором байта Python, который является, почему это может быть поднято в этой точке модулем parser. Большинство причин сбоя компиляции можно диагностировать программно путем проверки дерева синтаксического анализа.

Запросы по объектам ST

Предусмотрены две функции, которые позволяют приложению определить, был ли ST создан как выражение или набор. Ни одна из этих функций не может быть используемый для определения того, был ли ST создан из источника код через expr() или suite() или из дерева синтаксического анализа через sequence2st().

parser.isexpr(st)

Когда st представляет форму 'eval', эта функция возвращает True, в противном случае она возвращает False. Это полезно, так как код объекты обычно не могут быть запрошены для этой информации с помощью существующих встроенных функций. Обратите внимание, что объекты код, созданные compilest(), не могут быть подвергнуты сомнению как это также и идентичны созданным встроенной функцией compile().

parser.issuite(st)

Эта функция отражает isexpr(), в котором она сообщает, представляет ли объект ST. форму 'exec', обычно известную как «номер люкс». Небезопасно предполагать, что эта функция эквивалентна not isexpr(st), так как в будущем могут поддерживаться дополнительные синтаксические фрагменты.

Исключения и обработка ошибок

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

exception parser.ParserError

Исключение, возникшее при сбое в модуле парсер. Это обычно производится для неудач проверки, а не встроенный SyntaxError поднял во время нормального парсинг. Аргумент исключения является либо строка, описывающим причину сбоя, либо кортежем, содержащим последовательность, вызывающую сбой из дерева разбора, переданного sequence2st() и пояснительному строка. Требования к sequence2st() должны быть в состоянии обращаться с любым типом исключения, в то время как требования к другим функциям в модуле должны будут только знать о простом строка значения.

Обратите внимание, что функции, compilest(), expr() и suite() могут поднять исключения, которые обычно поднимаются процессом компиляции и парсинг. К ним относятся встроенные исключения MemoryError, OverflowError, SyntaxError и SystemError. В этих случаях эти исключения имеют все значения, обычно связанные с ними. Для получения подробной информации см. описание каждой функции.

ST-объекты

Между объектами ST поддерживаются упорядоченные сравнения и сравнения равенства. Также поддерживается пиклинг (pickling) объектов ST (с помощью модуля pickle).

parser.STType

Тип объектов возвращенный expr(), suite() и sequence2st().

Объекты ST имеют следующие методы:

ST.compile(filename='<syntax-tree>')

То же, что и compilest(st, filename).

ST.isexpr()

То же, что и isexpr(st).

ST.issuite()

То же, что и issuite(st).

ST.tolist(line_info=False, col_info=False)

То же, что и st2list(st, line_info, col_info).

ST.totuple(line_info=False, col_info=False)

То же, что и st2tuple(st, line_info, col_info).

Пример: эмуляция compile()

В то время как много полезных операций могут произойти между парсинг и bytecode поколением, самая простая операция ничего не должна делать. Для этой цели использование модуля parser для создания промежуточной структуры данных эквивалентно код:

>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10

Эквивалентная операция с использованием модуля parser несколько длиннее и позволяет сохранить промежуточное внутреннее дерево синтаксического анализа в качестве объекта ST:

>>> import parser
>>> st = parser.expr('a + 5')
>>> code = st.compile('file.py')
>>> a = 5
>>> eval(code)
10

Применение, для которого нужны и ST. и в объекты код, может упаковать этот код в легко доступные функции:

import parser

def load_suite(source_string):
    st = parser.suite(source_string)
    return st, st.compile()

def load_expression(source_string):
    st = parser.expr(source_string)
    return st, st.compile()