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

Парсер Javascript для Java

Любой может порекомендовать достойный парсер Javascript для Java? Я считаю, что Rhino можно использовать, однако кажется, что это слишком сложно для синтаксического анализа или это единственное достойное решение? Любое предложение было бы весьма признательным. Благодарю.

4b9b3361

Ответ 1

От https://github.com/google/caja/blob/master/src/com/google/caja/parser/js/Parser.java

Ниже приведенная ниже грамматика представляет собой контекстно-свободное представление грамматики анализирует парсер. Он не согласен с EcmaScript 262 Edition 3 (ES3), где реализация не согласуется с ES3. Правила вставки точки с запятой и возможный откат в выражениях, необходимых для правильной обработки backtracking тщательно прокомментированы в коде, поскольку вставка точки с запятой требует информации как от лексера, так и от парсера и не определяется с конечным взглядом.

Примечательные функции

  • Сообщает о предупреждениях в очереди, где ошибка не предотвращает дальнейших ошибок, поэтому мы можем сообщать о нескольких ошибках в одном компиляционном проходе, а не заставлять разработчиков играть в whack-a-mole.
  • Не анализирует стиль Firefox catch (<Identifier> if <Expression>), так как они не работают с IE и многими другими интерпретаторами.
  • Распознает const, поскольку многие интерпретаторы делают (не IE), но предупреждают.
  • Позволяет, но предупреждает, в концевых запятых в конструкторах Array и Object.
  • Позволяет использовать ключевые слова как имена идентификаторов, но предупреждает, поскольку разные интерпретаторы имеют разные наборы ключевых слов. Это позволяет использовать расширенный набор ключевых слов.

Чтобы разобрать строгий код, перейдите в PedanticWarningMessageQueue, чтобы преобразует MessageLevel#WARNING и выше в MessageLevel#FATAL_ERROR.


CajaTestCase.js показывает, как настроить парсер, и [fromResource] и [fromString] в том же классе показать, как получить вход нужного типа.

Ответ 2

При использовании Java V1.8 существует трюк, который вы можете использовать для синтаксического анализа реализации Nashorn, которая выходит из окна. Изучая модульные тесты в исходном коде OpenSDK, вы можете увидеть, как использовать только парсер, не делая всю дополнительную компиляцию и т.д.

Options options = new Options("nashorn");
options.set("anon.functions", true);
options.set("parse.only", true);
options.set("scripting", true);

ErrorManager errors = new ErrorManager();
Context context = new Context(options, errors, Thread.currentThread().getContextClassLoader());
Source source   = new Source("test", "var a = 10; var b = a + 1;" +
            "function someFunction() { return b + 1; }  ");
Parser parser = new Parser(context.getEnv(), source, errors);
FunctionNode functionNode = parser.parse();
Block block = functionNode.getBody();
List<Statement> statements = block.getStatements();

Как только этот код будет запущен, у вас будет абстрактное синтаксическое дерево (AST) для трех выражений в списке "statements".

Это можно затем интерпретировать или манипулировать вашими потребностями.

Предыдущий пример работает со следующими импортами:

import jdk.nashorn.internal.ir.Block;
import jdk.nashorn.internal.ir.FunctionNode;
import jdk.nashorn.internal.ir.Statement;
import jdk.nashorn.internal.parser.Parser;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ErrorManager;
import jdk.nashorn.internal.runtime.Source;
import jdk.nashorn.internal.runtime.options.Options;

Вам может потребоваться добавить правило доступа, чтобы сделать доступным jdk/nashorn/internal/**.


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


Nashorn доступен с Java SE 8.

Ссылка на информацию о получении исходного кода Nashorn находится здесь: https://wiki.openjdk.java.net/display/Nashorn/Building+Nashorn

Ответ 3

Вот два ANTLR более или менее работающих или полных (см. комментарии к этому сообщению) грамматик для EcmaScript:

Из ANTLR 5-минутное введение:

ANTLR читает файл описания языка, называемый грамматикой, и генерирует несколько файлов исходного кода и других вспомогательных файлов. Большинство применений ANTLR генерируют по крайней мере один (и нередко оба) из этих инструментов:

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

  • Parser: читает токен (обычно генерируемый лексером) и сопоставляет фразы на вашем языке с помощью правил (шаблонов), которые вы указываете, и обычно выполняет некоторые семантические действия для каждой фразы (или суб- фразу). Каждое совпадение может вызывать пользовательское действие, писать текст через StringTemplate или генерировать абстрактное дерево синтаксиса для дополнительной обработки.

Ответ 4

В предыдущем ответе описывается способ попасть под обложки JDK 8 для разбора javascript. Теперь они используют его в Java 9. Приятно!

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

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

http://openjdk.java.net/jeps/236

Резюме по ссылке выше:

Определите поддерживаемый API для абстрактного синтаксического дерева Nashorn ECMAScript.

Цели

  • Предоставить классы интерфейса для представления узлов синтаксиса дерева Nashorn.
  • Предоставьте factory для создания сконфигурированного экземпляра парсера, с конфигурацией, выполненной путем передачи опций командной строки Nashorn через API.
  • Предоставить API-интерфейс посетителя для посещения узлов AST.
  • Предоставлять примеры/тестовые программы для использования API.

Non-цели

  • Узлы AST будут по возможности представлять представления в спецификации ECMAScript, но они не будут точно такими же. По возможности интерфейсы API javac-дерева будут приняты для ECMAScript.
  • Не будет использоваться внешний парсер/дерево или API.
  • Не будет script -уровневого анализатора API. Это Java API, хотя скрипты могут вызывать Java и поэтому использовать этот API.

Ответ 5

Для меня лучшим решением является использование acorn - https://github.com/marijnh/acorn под носорогом.

Я просто не думаю, что caja больше внимания уделяет.