Подтвердить что ты не робот

Легкий javascript для парсера javascript

Как я могу написать легкий javascript для парсера javascript. Что-то простое, что может конвертировать некоторые фрагменты кода.

Я бы хотел, чтобы внутренние объекты области в публичных функциях.

Итак, что-то вроде этого

var outer = 42;
window.addEventListener('load', function() {
   var inner = 42;
   function magic() {
       var in_magic = inner + outer;
       console.log(in_magic);
   }
   magic();
}, false);

Скомпилируется

__Scope__.set('outer', 42);
__Scope__.set('console', console);
window.addEventListener('load', constructScopeWrapper(__Scope__, function(__Scope__) {
    __Scope__.set('inner', 42);
    __Scope__.set('magic',constructScopeWrapper(__Scope__, function _magic(__Scope__) {
        __Scope__.set('in_magic', __Scope__.get('inner') + __Scope__.get('outer'));
        __Scope__.get('console').log(__Scope__.get('in_magic'));
    }));
    __Scope__.get('magic')();
}), false);

Пример демонстрации

Мотивация заключается в том, чтобы сериализовать состояние функций и замыканий и синхронизировать их на разных компьютерах (клиент, сервер, несколько серверов). Для этого мне понадобилось бы представление [[Scope]]

Вопросы:

  • Могу ли я сделать этот компилятор без написания полного JavaScript → (немного другого) компилятора JavaScript?
  • Как я могу написать такой компилятор?
  • Можно ли повторно использовать существующие компиляторы js → js?
4b9b3361

Ответ 1

Если вы хотите что-то с простым интерфейсом, вы можете попробовать node -burrito: https://github.com/substack/node-burrito

Он генерирует AST, используя парсер uglify-js, а затем рекурсивно ходит по узлам. Все, что вам нужно сделать, это дать один обратный вызов, который проверяет каждый node. Вы можете изменить те, которые вам нужно изменить, и выводит полученный код.

Ответ 2

Я не думаю, что ваша задача проста или коротко, если вы хотите получить доступ и восстановить все состояние программы. Одна из проблем заключается в том, что вам может потребоваться захватить состояние программы в любой момент во время вычисления, не так ли? Это означает, что приведенный пример не совсем прав; который захватывает вид состояния перед выполнением этого кода (за исключением того, что вы предварительно вычислили сумму, которая инициализирует магию, и этого не произойдет до того, как код будет запущен для исходного JavaScript). Я предполагаю, что вы захотите захватить состояние в любой момент во время выполнения.

Как вы заявили о своей проблеме, вам нужен JavaScript-парсер в JavaScript. Я предполагаю, что вы воображаете, что ваш существующий JavaScript-код J включает в себя такой парсер JavaScript и все, что необходимо для генерации полученного в результате кода G, и что при запуске J он загружает копии себя в G, производя код сериализации S и как-то загрузив это. (Я думаю, что G довольно большой и седой, если он может обрабатывать все Javascript) Таким образом, ваш JavaScript-образ содержит J, большой G, S и выполняет дорогостоящую операцию (подача J-G) при запуске.

То, что, по-моему, могло бы послужить вам лучше, - это инструмент G, который обрабатывает ваш исходный код JavaScript J в автономном режиме и генерирует код сериализации состояния программы/закрытия S (для сохранения и восстановления этого состояния), который можно добавить/заменить J для выполнения, J + S отправляются клиенту, который никогда не видит G или его исполнение. Это отделяет поколение S от выполнения J исполнения, сохраняя время и пространство выполнения клиента.

В этом случае вам нужен инструмент, который сделает генерацию такого кода проще всего. Чистый парсер JavaScript - это начало, но маловероятно; вам понадобится поддержка таблиц символов, чтобы узнать, к какому функциональному коду подключен вызов функции F (...), и какое определение переменной, в котором область соответствует назначению или доступа к переменной V. Возможно, вам придется изменить свой исходный код J, чтобы вставить точки доступа, в которых можно зафиксировать состояние программы. Вам может понадобиться анализ потока, чтобы узнать, куда пошли некоторые значения. Настаивая на этом все в JavaScript, сузите спектр решений.

Для этих задач вы, вероятно, найдете инструмент программа преобразования. Такие инструменты содержат синтаксические анализаторы для интересующей группы, создают АСТ, представляющие программу, позволяют создавать карты идентификатора к определению ( "таблицы символов" ), могут выполнять модификации АСТ, представляющих вставку точек доступа, или синтез АСТ представляющий ваш демонстрационный пример, а затем регенерирует действительный код JavaScript, содержащий модифицированный J и дополнения S. Из всех программных систем преобразования, о которых я знаю (включая все те, которые находятся на сайте Wikipedia), ни один из них не реализован в JavaScript.

Наш DMS Software Reengineering Toolkit - такая система преобразования программ, предлагающая все функции, которые я только что описал. (Да, его большой и седой, он должен справляться с сложностями реальных компьютерных языков). Он имеет переднюю панель JavaScript, которая содержит полный парсер JavaScript для АСТ, и механизм для обновления кода JavaScript из модифицированных или синтезированных АСТ. (Также большой и седой, хорошо, что седой + седой все еще просто седой). Если это будет полезно, DMS также обеспечивает поддержку для управления зданием и анализа потока данных.

Ответ 3

Я попытаюсь найти существующий парсер для изменения. Возможно, вы можете адаптировать JSLint/JSHint?

Ответ 4

Проблема с переписыванием выше, вы не поднимаете инициализацию магии до вершины области.

Там есть несколько проектов, которые обрабатывают JavaScript.

  • Crock Pratt parser, который хорошо работает на JavaScript, который подходит в "Хороших частях" и менее хорошо на других JS.
  • es-lab парсер, основанный на ometa, который обрабатывает полную грамматику, включая много угловых случаев, которые пропускает анализатор Crock. Он может не работать так же хорошо, как и Crock's.
  • narcissus парсер и оценщик. У меня нет большого опыта в этом.

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

My es5-lexer - тщательно продуманный и эффективный лексер для EcmaScript 5, который обеспечивает возможность токенизации JavaScript. Это эвристика, где грамматика JavaScript не лексически правильная, но эвристика очень хороша и обеспечивает средство для преобразования потока токенов, чтобы интерпретатор мог интерпретировать его так, как лексер интерпретировал токены, поэтому, если вы не доверяете своим вход, вы все равно можете быть уверены, что интерпретация, лежащая в основе преобразований безопасности, является звуковой, даже если она неверна в соответствии со спецификацией для некоторых причудливых входов.

Ответ 5

Ваша проблема заключается в том, чтобы быть в том же семействе проблем, что и в случае с JS Opfuscators и JS Compressors - они также должны быть способны анализировать и переформатировать JS эквивалентно script;

Было хорошее обсуждение obfuscators здесь, и возможное решение вашей проблемы могло бы состоять в том, чтобы использовать часть синтаксического анализа и генератора из одной из версий FOSS.

Одна выноска, ваш примерный код не учитывает области видимости переменных, которые вы хотите установить /get, и это в конечном итоге станет проблемой, которую вам придется решать.

Добавление

Учитывая проблему с областью действия для определенных функций закрытия, вы вряд ли сможете решить эту проблему как проблему статического анализа, поскольку переменные области вне закрытия должны быть импортированы/экспортированы для разрешения/создать экземпляр. Следовательно, вам может понадобиться вникнуть в сам механизм оценки и, возможно, получить двигатель V8 и сделать взлом для самого интерпретатора - предполагается, что вам не нужно, чтобы это было универсальным перекрестным движком всех script, и вы можете привяжите его к одной реализации, которую вы контролируете.