Javascript.RU

Вывод синтаксического дерева кода

Синтаксическое дерево - внутренняя структура, которую интерпретатор javascript создает из исходного кода.

Обычно синтаксическое дерево создается для выполнения, но также может использоваться и для оптимизации, чем, собственно, и занимается google closure compiler.

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

Так как синтаксическое дерево заточено под выполнение, то оно содержит все значимые элементы - без лишних пробелов, комментариев и т.п.

Поэтому чтение файла в синтаксическое дерево, а потом генерация кода по этому дереву - само по себе является оптимизацией. Это соответствует значению флага --compilation_level, равному WHITESPACE_ONLY.

Простейший способ получить синтаксическое дерево - это использовать флаг --print_tree.

Например, для скрипта ast.js:

function Animal(speed) {
  /** @type {number} */
  this.speed = speed
}

Печать дерева:

java -jar compiler.jar  --js ast.js  --use_only_custom_externs --print_tree
Флаг --use_only_custom_externs при печати дерева необходим, иначе дерево будет также содержать все стандартные экстерны.

Результат:

BLOCK [synthetic: 1]
    BLOCK [synthetic: 1]
        SCRIPT [source name: null] [encoded source length: 0] [base line: -1] [end line: -1] 1 [sourcename: /dev/null] [synthetic: 1]
    BLOCK [synthetic: 1]
        SCRIPT [source name: null] [encoded source length: 0] [base line: -1] [end line: -1] 1 [sourcename: ast.js] [synthetic: 1]
            FUNCTION Animal 1 [sourcename: ast.js]
                NAME Animal 1
                LP 1
                    NAME a 1
                BLOCK 1
                    EXPR_RESULT 3
                        ASSIGN 3 [jsdoc_info: JSDocInfo]
                            GETPROP 3
                                THIS 3
                                STRING speed 3
                            NAME a 3

Как видите, выводится основная информация. Сверху - несколько служебных строк, а ниже - наша функция.

Аннотация /** @type {number} */ превратилась во внутреннюю структуру JSDocInfo.

Обратите внимание, дерево печатается для уже откомпилированного кода, со всеми оптимизациями и заменами. Поэтому, в частности, локальная переменная speed в дереве называется a.

Вы также можете получить дерево в более красивом виде, используя флаг --print_ast:

java -jar compiler.jar  --js ast.js  --use_only_custom_externs --print_ast >ast.dot

Полученный текст - граф в формате DOT, для просмотра которого обычно используется утилита graphviz, работающая под основными ОС.

Запустив эту утилиту и преобразовав в ней файл ast.dot, получим картинку:

Выглядит красивее, но в тестовом дереве --print_tree содержится больше информации, поэтому обычно удобнее использовать текстовый формат, а графический - больше для диаграмм. Вдруг кто-нибудь решит диплом или диссертацию написать по оптимизации javascript


Автор: Dunyatka (не зарегистрирован), дата: 19 февраля, 2010 - 12:22
#permalink

Спасибо! Для диплома кое что у Вас тут забрал.


Автор: Lekcion (не зарегистрирован), дата: 7 декабря, 2012 - 01:22
#permalink

Как то, слабо описано... Но спасибо и за такое...


Автор: redactle (не зарегистрирован), дата: 29 марта, 2023 - 12:35
#permalink

Как-то неадекватно описано... Но и это я ценю...


 
Текущий раздел
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние темы на форуме
Forum