Комбинированный unparser генератор / анализатор

Обновить

November 2018

Просмотры

470 раз

15

Есть ли синтаксический анализатор генератор, который также реализует обратное направление, т.е. unparsing объекты домена (он же довольно-печать) из одной и той же спецификации грамматики? Насколько я знаю, ANTLR не поддерживает это.

pmf

4 ответы

0

Это не возможно вообще.

Что делает печать довольно? Отпечаток довольно, если пробелы, табуляции или перевода строки в тех позициях, которые делают печать глядя красиво.

Но большинство грамматик игнорировать пробелы, потому что в большинстве языков белые пространства не являются существенными. Есть исключения, как Python, но в целом вопрос, является ли это хорошая идея использовать пробелы как синтаксис, остается спорным. И для них большинство грамматик не используют пробелы в синтаксисе.

И если абстрактное синтаксическое дерево не содержит пробелы, потому что анализатор бросил их, не генератор не может использовать их довольно напечатать AST.

1

Our DMS Software Reengineering Toolkit does precisely this (and provides a lot of additional support for analyzing/transforming code). It does this by decorating a language grammar with additional attributes, producing what is called an attribute grammar. We use a special DSL to write these rules to make them convenient to write.

It helps to know that DMS produces a tree based directly on the grammar.

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

В качестве примера, можно записать следующее правило грамматики DMS и соответствия prettyprinting правилу:

statement = 'for' '(' assignment ';' assignment ';' conditional_expression ')'
            '{' sequence_of_statements '}' ;
<<PrettyPrinter>>: 
    { V(H('for','(',assignment[1],';','assignment[2],';',conditional_expression,')'),
        H('{', I(sequence_of_statements)),
        '}');

Это будет разобрать следующее:

    for ( i=x*2;
       i--;  i>-2*x ) {  a[x]+=3; 
      b[x]=a[x]-1; }

(С использованием дополнительных правил грамматики для операторов и выражений) и prettyprint его (используя дополнительные правила prettyprinting для тех дополнительных правил грамматики) следующим образом:

    for (i=x*2;i--;i>-2*x)
    {   a[x]+=3;
        b[x]=a[x]-1;
    }

DMS также фиксирует комментарии, прикрепляет их к Астам узлов и регенерирует их на выходе. Реализация немного экзотики, потому что большинство парсеров не обрабатывать комментарии, но использование легко, даже «свободное»; комментарии будут автоматически вставляться в результате в Аккуратно своих прежних местах.

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

Подробнее о том , что prettyprinters должны делать предоставляются в моем SO ответить на Компиляция AST обратно к исходному коду . DMS решает все эти темы чисто.

Эта возможность была использована DMS на некоторых 40+ реальных языков, в том числе полного IBM COBOL, PL / SQL, Java 1.8, C # 5.0, C (много диалектов) и C ++ 14.

Написав достаточно интересный набор правил prettyprinter, вы можете создавать вещи , как JavaDoc расширены , чтобы включить гиперссылка исходного кода .

1

Есть несколько генераторов парсеров , которые включают в себя реализацию в unparser. Одним из них является nearley анализатор генератор для контекстно-свободных грамматик.

Кроме того , можно реализовать двунаправленные преобразования исходного кода с использованием определенного Пункта грамматик . В SWI-Prolog, то phrase/2предикат может преобразовать входной текст в дерево разбора и наоборот.