Любой может порекомендовать достойный парсер Javascript для Java? Я считаю, что Rhino можно использовать, однако кажется, что это слишком сложно для синтаксического анализа или это единственное достойное решение? Любое предложение было бы весьма признательным. Благодарю.
Парсер Javascript для Java
Ответ 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:
- http://www.antlr.org/grammar/1206736738015/JavaScript.g (неполный?)
- http://www.antlr.org/grammar/1153976512034/ecmascriptA3.g (ошибка?)
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 больше внимания уделяет.
Ответ 6
EcmaScript 5 Parser для java https://github.com/DigiArea/es5-model