Дайте инструкции для парсера / лексера Java - PullRequest
2 голосов
/ 23 февраля 2011

Есть ли способ дать инструкции напрямую парсеру и лексару с уровня кода Java? Если нет, то как вообще можно это делать?

Проблема в том, что я хочу, чтобы синтаксический анализатор оценил переменную, сделал резервную копию, а затем назначил значение этой переменной в качестве имени объекта. Как это:

String s = "text";

SomeClass (s) = new SomeClass();

парсер читает -> хорошо, s оценивается как "текст" ... парсер возвращает назад, удерживая «текст» в памяти и назначая «текст» в качестве имени нового экземпляра SomeClass, так что теперь можно сделать следующее:

text.callSomeMethod();

Мне нужно сделать это, потому что мне нужно создать произвольное количество объектов SomeClass. У каждого должно быть уникальное имя, и было бы идеально сделать что-то вроде этого:

while (someArbitrarySet.hasNext()) {
    String s = "token" + Math.random();
    SomeClass (s) = new SomeClass();
    (s).callSomeMethod();
}

Надеюсь, это имеет смысл ...

Ответы [ 5 ]

1 голос
/ 23 февраля 2011

То, что вы описываете (создание новых именованных переменных во время выполнения), возможно на интерпретируемых языках, таких как JavaScript, Lua, Bash, но не на скомпилированном языке, таком как Java.Когда цикл выполняется, там нет исходного кода для манипулирования, и все именованные переменные должны быть определены ранее.

Кроме этого, вашим переменным не нужно «уникальное» имя, если выиспользуя их последовательно (один за другим), вы можете написать цикл так же, как этот:

while (someArbitrarySet.hasNext()) {
    SomeClass sC = new SomeClass();
    sC.callSomeMethod();
}

Если вам действительно нужны ваши объекты одновременно, поместите их в некую структуру данных.Простейшим был бы массив, вы можете использовать Collection (например, ArrayList) или Map (как писал CajunLuke), если вы хотите найти их снова по ключу.

Фактически, массив (в Java) это не что иное, как набор переменных (все одного типа), которые вы можете индексировать с помощью целого числа.

(А языки сценариев, которые позволяют создавать новые переменные во время выполнения, реализуют это также с помощью некоторого видаmap String → (что угодно), где эта карта либо метод / script-local, либо принадлежит некоторому окружающему объекту.)


Вы написали в комментарии к вопросу (лучше добавьте эти вещи в вопроссама она имеет кнопку «редактировать»):

Не вдаваясь в подробности, я пишу приложение, которое запускается в более крупной программе.Обычно объекты собирают мусор после того, как я с ними покончу, но более крупная программа поддерживает их, поэтому для каждого требуется уникальное имя.Если я не дам каждому уникальное имя, старый объект будет перезаписан, но он все еще необходим в контексте большой программы.

Итак, вы хотите сохранить объекты, чтобы избежатьвывоз мусора?Используйте массив (или List, или что-нибудь еще).

Дело в том, что если вы хотите, чтобы ваша более крупная программа могла использовать эти объекты, вам как-то нужно передать их этому большая программа в любом случае.И тогда этой программе придется сохранять ссылки на эти объекты, тем самым избегая сбора мусора.Похоже, вы хотите решить проблему, которая не существует средствами, которых не существует: -)

1 голос
/ 23 февраля 2011

То, что вы просите, это то, что некоторые языки называют MACROS. Их также иногда называют определениями препроцессора или просто «определяет».

Было принято решение не включать в Java include, макросы и тому подобное, потому что это вводит дополнительные проблемы обслуживания кода, которые, как заключили дизайнеры, вызовут код, который не будет соответствовать желаемому стилю.

Однако тот факт, что он не встроен в компилятор, не означает, что вы не можете добавить его в свой скрипт сборки.

В процессе сборки вы копируете все файлы в каталог src-comp и заменяете свои токены, как они определены.

Я не рекомендую делать это, но это не значит, что это невозможно.

0 голосов
/ 23 февраля 2011

Ответ дан в Как вы используете Java 1.6 Annotation Processing для выполнения ткачества во время компиляции? .

Короче говоря, есть инструмент обработки аннотаций, который позволяет расширять синтаксис Java и создавать DSL, которые компилируются в аннотации Java.

В JDK 1.5 вы должны были использовать apt вместо javac, но под 1.6 на них влияет флаг -processor до javac. От javac -help:

-processor <class1>[<class2>,<class3>...]Names of the annotation processors to run; bypasses default discovery process
-processorpath <path>      Specify where to find annotation processors
0 голосов
/ 23 февраля 2011

Нет. Это невозможно.

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

Таким образом, варианты описаны в CanjuLuke или для создания вашего собственного java-парсера, возможно, используя ANTRL образец грамматики Java и подключите то, что вам нужно.

Рассмотрим решение на карте.

0 голосов
/ 23 февраля 2011

Не совсем ответ на заданный вами вопрос, но возможное решение вашей проблемы: использование карты.

Map variables = new HashMap();
while (someArbitrarySet.hasNext()) {
    String s = "token" + Math.random();
    variables.put(s, new SomeClass());
    variables.get(s).callSomeMethod();
}

Таким образом, вы можете использовать «имя переменной» в качестве ключей вкарта, и вы можете обойтись без возни с лексером / парсером.

Я действительно надеюсь, что есть способ сделать именно то, что вы заявляете в Java - это было бы действительно здорово.

...