ASDL используется, когда вам нужно сгенерировать дерево в модуле и ввести такое же дерево в другой модуль (или почти такое же дерево, как-то оптимизированное).
Для этого нужно иметь функции построения (в идеале с проверкой типов), функцию печати дерева, чтобы визуализировав его, вы были уверены, что сгенерировали его правильно.
ASDL принимает на вход некоторое дерево, написанное в синтаксисе, почти идентичном синтаксису алгебраического типа данных (например, в haskell или ml), или синтаксисе в BNF, но гораздо более упрощенном, и автоматически генерирует все конструкторы, печатая функции, начиная с простое описание дерева.
Например, если у вас есть лексер, он должен будет генерировать лексемы, имеющие тип. Вам также нужно увидеть выходной поток лексем (это в линейной форме, поэтому очень простое дерево). Вместо того, чтобы писать функции для печати, конструируя лексемы, вы определяете их как-то так
lexeme=
ID(STRING)
| INT(num_integer)
| FLOAT(num_float)
attributes(int coord_x, int coord_y)
num_integer:
....
num_float:
....
и вы вызываете конструкторы ID, INT, FLOAT и т. д. из вашего лексера. ASDL преобразует этот простой синтаксис во все функции, которые вам нужны, либо для создания узлов для AST, либо для печати, либо для всего, что вам нужно. ASDL не накладывает ограничений на генерируемый код.
Если вы добавляете attributes
к типу, например к координатам токена, такие атрибуты добавляются к параметрам каждого конструктора из этого типа.
Более сложное дерево, созданное парсером, будет выглядеть так
expr: SUM(expr, expr)
|PRODUCT(expr, expr)
|number
number: num_integer
В этом случае asdl проверит, что вызов SUM(_ _), сделанный синтаксическим анализатором, пройдет к узлам суммы, созданным с помощью одного из конструкторов expr. num_integer
определяется извне, возможно, деревом asdl для лексера.
Обратите внимание, что вам не разрешено определять конструкторы, содержащие регулярные выражения, такие как number: [0-9]+
. ASDL проще, чем EBNF.
Эти конструкторы будут определены таким образом, что для создания того, что вам нужно, и более того, они будут проверять тип, чтобы убедиться, что ваш лексер/парсер/генератор кода выводит деревья, которые соответствуют языку, определенному asdl.
Чтобы хорошо понимать ASDL, вам нужно написать 3-4 парсера и посмотреть, что общего в коде, который они генерируют. Эта общая часть на самом деле является ASDL, так что это абстракция, в частности, для вывода парсеров.
person
alinsoar
schedule
06.12.2016