Esprima — парсер для javascript, написанный на javascript

    В сети и на github появилась разработка парсера Esprima, позиционированного на парсинг вообще и для javascript в частности. Он написан на Javascript и переводит скармливаемый текст в структуру JSON, которую затем можно анализировать, например, для препроцессирования кодов, создания сахарных обёрток для JS, автоматизированного поиска ошибок без запуска кода, преобразования языков (кросс-компиляции), преобразования серверного JS в клиентский или наоборот, для минификации кода или наоборот, для разбора обфусцированного. Но это — всё идеи для будущего. Появился архив совсем недавно (в середине ноября — первый коммит с 2000 строк кода), но уже приобрёл своих иследователей, судя по форкам. Формат парсинга совместим с Mozilla SpiderMonkey Parser API.

    Проверить работу парсера в текущем состоянии можно, даже не скачивая библиотеку из хранилища — на сайте есть демо-страница. Вносим в её поле ввода небольшой кусок скрипта (чтобы результат был обозреваемым) — и смотрим полученное дерево-хеш. (Что с этим деревом делать дальше — уже другой вопрос.) Видим, что в дереве отмечены и распознаны синтаксические конструкции языка. Кстати, поле ввода использует онлайн-среду редактирования CodeMirror с подсветкой синтаксиса и поддерживает работу с табами, групповым добавлением пробелов к строкам по выделению, отступы при вводе скобок, поэтому довольно удобно код набирать прямо в браузере. Парсинг выполняется в реальном времени и немедленно реагирует на ошибки в коде, по крайней мере, когда кода в окне мало. Однако, работает он очень резво, как чистый парсинг, так и отображение на странице. Например, перерисовка всего парсинга исходного кода jQuery (250 КБ) занимает около секунды (Fx8\Linux\i7-2600 CPU, embed. video intel), а чистый парсинг, как утверждает автор программы — менее 0.1 с. (В этой статье много любопытных данных о скорости парсинга на разных JS-движках.)

    Поддерживаются, как минимум, такие браузеры: IE 8+, Firefox 3.5+, Safari 4+, Chrome 7+ и Opera 10.5+ и nodeJS+npm.

    Разработчик (Ariya Hidayat) на своём сайте запустил программу онлайнового тестирования различных парсеров, действующую прямо на вашем клиентском компьютере. В забегах участвуют 4 библиотеки исходных кодов и 4 парсера: Esprima, Narcissus, parse-js, ZeParser. Как подчёркивает разработчик, все цифры не следует воспринимать слишком серьёзно (потому что данные выводятся в разных форматах и у каждого есть пути оптимизации), а лишь для того, чтобы убедиться, что новый парсер стоит в одном ряду с другими и не даёт слишком плохих результатов, скромно умалчивая о том, что он в тестах обходит всех остальных. Вот что получилось у меня:


    Вот — визуализированные результаты тестов в сравнении с одним из лучших парсеров, полученные разработчиком:


    Парсеры JS, написанные на JS: Narcissus (используется в движке Mozilla JS), parse-js (используется в минификаторе UglifyJS), ZeParser. Несколько ключевых слов и ссылок можно найти на stackoverflow, по поиску и на сайтах разработчиков.

    Разработчик, опять же, в онлайне, поддерживает юнит- и прочее тестирование своего кода. Хороший ход, потому что он сможет получить сообщения от различных пользователей о результатах проведённых тестов в различных окружениях.

    На некотором этапе реализации Esprima стал поддерживать выделение комментариев в виде отдельного массива comments[] в конце дерева, с номерами строк, что может тоже найти применение для автоматического создания документации.

    В планах у разработчика — поддержка особенностей языка типа 8-ричных чисел, более полная поддержка IE, улучшение собственного сайта и представления тестов на нём.

    Такие проекты интересны ещё тем, что, используя только JS, можно поддерживать разработку связки фронтенда и nodeJS на более высоком уровне, чем переписывая адаптируя код для сервера вручную. Но действительно удобные системы для такого подхода появятся в недалёком будущем, и есть шанс внести свою лепту и занять место под солнцем уже сейчас, глядя на становление серверных JS-технологий.
    Поделиться публикацией
    Похожие публикации
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 10
      +1
      А где можно почитать о том, как с помощью такого парсера совмещать клиентский и серверный код? У меня обычно получилось только делать базовые модели и от них отдельно наследовать клиентские и серверные модели.
        0
        Это моё свободное фантазирование о сферах применения, которых, видимо, нигде ещё нет. Пока что мы имеем то, что имеем на Гитхабе у этого парсера и ещё одного. Представляю, что нужно парсить специфические для браузера конструкции и выкусывать их или обращать внимание в интерактиве. Например, находим DOM-зависимые участки и выкусываем их. Хуже, если в DOM хранятся данные. В общем, очень большое поле для будущей деятельности.
          0
          Я недавно представлял себе смесь идей PhantomOS (построенная на объектах) + JavaScript. Думаю такой парсер в такой смеси найдет себе очень хорошее применение =)
          +2
          А в чем проблема, сделать одну модель на сервер и клиент? Если ее абстрагировать от доступа к данным, вывода на экран, обращения к API, работы с сетью и с файлами, то есть, оставить именно бизнес-логику и данные объекта, то проблем не вижу.
          +1
          Отлично!
          Аххх… если бы он еще мог этот JSON загонять обратно в JavaScript…
            +1
            А чем данный парсер отличается, например, от этого?
            Парсер JS, написанный на JS это само по себе не новость.
              0
              Может быть, новый быстрее работает и оптимизирован для современных браузеров.
              Парсер JS, написанный на JS это само по себе не новость.

              Вы не читали текст статьи, там приводятся названия 3 более современных парсеров на JS и даже сравнение их в тестах.
                0
                " Этот " «парсер» неработает и давится вот, например, на таком коде
                  
                Array.prototype.group = function(field, clear)
                {
                   var g = {};
                   
                   if(typeof field == "function")
                   {
                      var fun = field;
                      var scope = clear;
                      
                      this.each(function(ix, it, f)
                      {
                         if((f = f.call(scope, it)) in this){
                            this[f].push(it);}
                         else{
                            this[f] = [it];}   
                      }, g, fun);
                   }
                   else
                   {
                      this.each(clear ? (
                         function(ix, it, f)
                         {
                            it = _extend({}, it);
                            var t = it[f];
                            delete it[f];
                            if(t in this){
                               this[t].push(it);}
                            else{
                               this[t] = [it];}   
                         }) : (
                         function(ix, it, f)
                         {
                            if((f = it[f]) in this){
                               this[f].push(it);}
                            else{
                               this[f] = [it];}   
                         }), 
                         g, field);
                   }
                   
                   return g;
                };
                  

                  0
                  «Этот» парсер используется здесь, и такие вещи его не смущают.
                  В ссылке приведенной выше облегченная версия этого парсера.
                    0
                    Так, пока существенное различее: назначение парсера и оформление кода ;-)

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

              Самое читаемое