2015-07-06 3 views
0

A [any type]Realisation Инициализация правила грамматики должна быть значением или ссылкой на предопределенную переменную. Для Integer он похож, как то, что вы знаете из Java:Определение/ссылка переменной грамматической переменной Xtext

public int i = 3; 

Почему следующая грамматика сгенерировано исключение?

Integer returns ecore::ELong: 
    (Plus|Minus)? INT; 

IntegerRealisation: 
    {Integer} Integer | 
    ref=[Integer]; 

Исключение:

Caused by: java.io.IOException: Generated EMF Model incomplete: The context 'IntegerRealisation' is not valid for type 'Integer' 
Recommended contexts for type 'Integer': 
Other valid contexts for type 'Integer': .... The context 'IntegerRealisation' is valid for types: Integer, IntegerRealisation 

Почему первая и последняя строка той же ошибки не согласны друг с другом?

Что здесь не так?

ответ

0

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

public int i = 5; // 5 is a value 
public int j = i; // i reference to a predefined variable 

ваше определение грамматики должно выглядеть

VariableDeclaration: 
    modifiers+=Modifier* type=Type name=ID ('=' value=VariableValue)? ';'; 

VariableValue: 
    TypedLiteral | VariableReference; 

TypedLiteral: 
    IntegerLiteral | ...; 

IntegerLiteral: 
    value=INTVAL; 

terminal INTVAL returns ecore::ELong: 
    (Plus|Minus)? INT; 

VariableReference: 
    ref=[VariableDeclaration|QualifiedName]; 

Как вы можете видеть, она начинается с правила для определения переменной. Эта переменная имеет атрибут , который очень важен для ссылочной реализации позже. Фактическое распределение значений не является обязательным (потому что я бы сделал это так!) Важно на данный момент: правилоVariableValue, которое будет моделировать буквальное значение (или постоянное значение) или ссылку на любую другую переменную.

Если вы хотите ссылаться на любую предопределенную переменную, вы будете использовать другое имя переменных, но не его значение. По этой причине нам также понадобится VariableReference, который определяет, что мы ссылаемся на любую другую переменную (перед оператором трубы) с помощью (квалифицированного) имени (для оператора трубы |).

Для обеспечения безопасности типов вам необходимо реализовать класс yourdsl.validation.YourDslValidator, чтобы проверить, совместим ли литерал с типом и соответствует ли тип ссылочной переменной типу.

Редактировать: Я немного оптимизировал грамматику. Первая версия была немного неясной.

Ответ на Ваши дополнительные вопросы:

Что возвращаемый тип VariableValue?

VariableValue сам по себе является общим (но абстрактным) возвратом типа всех возможных значений. Это как java.lang.Number который является супер тип java.lang.Integer, java.lang.Double ...

Проблема здесь состоит в том, что слово тип сам неоднозначен здесь. тип значения будет int (IntegerLiteral extends TypedLiteral extends VariableValue), но тип узла AST - IntegerLiteral или VariableReference.

Чтобы определить тип значения в VariableReference вы должны смотреть в атрибут ссылочного VariableDeclaration (((VariableReference)vd1.getValue()).getRef().getValue()) value. Никогда не будет типа значения EString!

Чтобы установить значение в атрибут VariableDeclaration.value, вам нужен либо IntegerLiteral (наиболее явный Типичный литерал), либо VariableReference.

+0

Каков тип возврата 'VariableValue'? default - ecore :: EString. Но поскольку 'IntegerLiteral' возвращает ELON и' VariableReference' (я думаю), может быть только EString или, скорее всего, EReference, не будет общего супертипа ... Класс EMF ожидает 'VariableValue', но это не экземпляр! – user972851

Смежные вопросы