Какой самый простой пример объясняет разницу между деревьями разбора и деревьями абстрактного синтаксиса?

14

Насколько я понимаю, парсер создает дерево разбора, а затем отбрасывает его. Тем не менее, он также может вызвать абстрактное синтаксическое дерево, которое предположительно использует компилятор.

У меня сложилось впечатление, что и дерево синтаксического анализа, и абстрактное синтаксическое дерево создаются на этапе синтаксического анализа. Тогда кто-то может объяснить, почему они разные?

Combinator Logic
источник
3
Почему они должны быть разными? Разве они не могут быть одинаковыми с двух немного разных точек зрения?
S.Lott
1
Не уверен, что понимаю эти две «немного разные точки зрения» :-(
Логика Combinator
В этом-то и дело. Это одно и то же, отсюда и путаница. У вас просто разные слова в зависимости от вашей точки зрения: Парсинг или Генерация кода (или Выполнение, в случае интерпретатора).
S.Lott
Нет никакой разницы. Приложив немного воображения, можно придумать синтаксическое представление для любого возможного абстрактного синтаксического дерева. При недостатке воображения S-выражения в Lisp были бы синтаксисом по умолчанию, подходящим для всего.
SK-logic
1
Вы все должны были прочитать ответ, прежде чем комментировать. Разница есть, но проблема их реализации - разделение или объединение.
Пол

Ответы:

20

Дерево разбора также известно как конкретное синтаксическое дерево.

По сути, абстрактное дерево содержит меньше информации, чем конкретное дерево. Конкретное дерево содержит каждый элемент языка, в то время как абстрактное дерево отбрасывает неинтересные фрагменты.

Например выражение: (2 + 5) * 8

Бетон выглядит так

  ( 2  + 5 )  * 8
  |  \ | / |  | |
  |   \|/  |  | |
   \___|__/   | |
       \______|/

В то время как абстрактное дерево имеет:

2  5 
 \/   
  +  8
   \/
   *

В конкретных случаях круглые скобки и все части языка были включены в дерево. В абстрактном случае скобки исчезли, потому что их информация была включена в древовидную структуру.

Уинстон Эверт
источник
Вы забыли упомянуть, в каком компиляторе для какого языка это реализовано таким образом. Потому что, вы знаете, вам не нужно ... синтаксический анализатор мог бы сразу же выбросить скобки.
Инго
1
@ Инго, в моем ответе ничего не сказано о том, когда компилятор выбрасывает скобки. Он спрашивает, в чем разница между конкретным деревом разбора и абстрактным деревом разбора.
Уинстон Эверт
Так, конечно, вы можете назвать источник для вашей претензии? Или это только ваше личное определение?
Инго
1
@ingo, docs.google.com/document/d/…
Уинстон Эверт
0

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

Например, следующий язык:

prog:
      definition 
    | definition ';' prog
    ;

definition: .....

может быть представлен в виде списка определений. (Nitpickers укажет, что список является вырожденным деревом, но в любом случае.)

Во-вторых, нет необходимости держать дерево синтаксического анализа (или какую-либо структуру данных, возвращенную анализатором). Напротив, компиляторы обычно конструируются как последовательность проходов, которые преобразуют результаты предыдущего прохода. Следовательно, общая компоновка компилятора может быть такой:

parser :: String             -> Maybe [Definitions]      -- parser
pass1  :: [Definitions]      -> Maybe DesugaredProg      -- desugarer
pass2  :: DesugaredProg      -> Maybe TypedProg          -- type checker
pass3  :: TypedProg          -> Maybe AbstractTargetLang -- code generation
pass4  :: AbstractTargetLang -> Maybe String             -- pretty printer

compiler :: String           -> Maybe String    -- transform source code to target code
compiler source = do
   defs  <- parser source
   desug <- pass1 defs
   typed <- pass2 desug
   targt <- pass3 typed
   pass4 targt

Итог: если вы слышите, как люди говорят о деревьях разбора , абстрактных синтаксических деревьях , конкретных синтаксических деревьях и т. Д., Всегда заменяйте их структурой данных, подходящей для данной цели , и все в порядке.

Инго
источник
2
Как это ответ на вопрос?
Уинстон Эверт
@WinstonEwert Я утверждаю, что «дерево разбора» и «абстрактное синтаксическое дерево» являются абстракциями и означают не что иное, как «подходящие структуры данных». Таким образом, ответ заключается в том, что вопрос в его общности не имеет смысла, если только вы не спросите разницу между типом возвращаемого значения синтаксического анализатора и типом возвращаемого значения другого прохода в компиляторе XY языка L.
Ingo