Создание экземпляров Xbase XExpressions программно

Я работаю над проектом Xtext, в котором используются части грамматики Xbase. В своем коде я анализирую программу DSL, чтобы сгенерировать код Java. Легко превратить существующий XExpression в код Java с помощью XbaseCompiler, но это не то, что мне нужно. Вместо этого мне нужно создать другую программу.

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

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


person Kirill Rakhman    schedule 08.07.2015    source источник
comment
я не знаю, хорошая ли это идея, но это трудно сказать из контекста, который у вас есть, поскольку все, что делается помимо написания jvmmodelinferrer, должно быть хорошо продумано, поскольку это может быть не так просто. но вы можете искать XbaseFactory.eInstance.createXXX, как это обычно делается со всеми материалами EMF.   -  person Christian Dietrich    schedule 08.07.2015


Ответы (1)


Я бы предпочел сгенерировать выражение как строку, а затем использовать анализатор Xtext, чтобы сделать за вас тяжелую работу, т.е. позволить ему проанализировать строку и создать для вас соответствующие объекты XExpression. То, как вы это сделаете, зависит от контекста, в котором вы находитесь (OSGI или автономный).

Вот отдельный пример (может быть запущен из простого метода main) для "Scripting Language" из Xtext документация:

public class StandaloneParser {

    @Inject
    private IParser parser;

    public StandaloneParser() {
        Injector injector = new ScriptingStandaloneSetup().createInjectorAndDoEMFRegistration();
        injector.injectMembers(this);
    }

    public EObject parse(String input) {
        IParseResult result = parser.parse(new StringReader(input));
        if (result.hasSyntaxErrors()) {
            throw new RuntimeException("Syntax errors");
        }
        return result.getRootASTElement();
    }

}

Пример для звонящего:

public class Main {

    public static void main(String[] args) {
        StandaloneParser parser = new StandaloneParser();
        EObject result = parser.parse("val answer = 7 * 6;");
        System.out.println(result);
    }

}

Если вы попытаетесь создать такое выражение программно, вам придется нелегко. Это может выглядеть так (код Xtend):

val factory = XbaseFactory.eINSTANCE
val expression = factory.createXVariableDeclaration => [
    name = "answer"
    right = factory.createXBinaryOperation => [
        leftOperand = factory.createXNumberLiteral => [
            value = "7"
        ]
        feature = // TODO retrieve the JvmOperation: org.eclipse.xtext.xbase.lib.IntegerExtensions.operator_multiply(int,int)
        rightOperand = factory.createXNumberLiteral => [
            value = "6"
        ]
    ]
]
person Franz Becker    schedule 08.07.2015
comment
Спасибо за Ваш ответ! Допустим, я проверяю выражение XBlockExpression, которое обращается к переменным, объявленным в другом месте. Как я могу указать синтаксическому анализатору использовать тот же контекст (т.е. область действия) для нового выражения, чтобы я мог получить доступ к тем же переменным? - person Kirill Rakhman; 09.07.2015
comment
Это сильно зависит от вашей конкретной модели/грамматики. Взяв в качестве примера язык сценариев, вы можете выполнить EcoreUtil.copyAll(...) для всей модели (или изменить существующую), удалить некоторые выражения и вставить свои собственные в нужных местах. Если это не дает вам достаточно информации для продолжения, отправьте новый вопрос с более подробной информацией о вашем прецеденте (обратите внимание, что я не буду доступен до вторника). - person Franz Becker; 10.07.2015
comment
Спасибо, посмотрю. - person Kirill Rakhman; 10.07.2015
comment
Я решил придерживаться ручной генерации кода Java. - person Kirill Rakhman; 15.07.2015