Вы пытаетесь ссылаться на целочисленный литерал вместо любой другой типизированной переменной. Для реализации с. как
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
.
Каков тип возврата 'VariableValue'? default - ecore :: EString. Но поскольку 'IntegerLiteral' возвращает ELON и' VariableReference' (я думаю), может быть только EString или, скорее всего, EReference, не будет общего супертипа ... Класс EMF ожидает 'VariableValue', но это не экземпляр! – user972851