В моих DSL-переменных они динамические, они создаются при первом назначении им значения. Так что это действительный код:
a = 0
b = 2 // new variable created
a = 3 // existing variable reassigned
Мой наивный подход - иметь такие правила
Identifier:
ID; // ID from Terminals
Assignable:
{Assignable} ref=[Identifier|ID] |
{Assignable} newVar=Identifier;
Это не работает, жалуясь: «Следующие альтернативы никогда не могут быть сопоставлены: 2». Это понятно, потому что сгенерированная отладочная грамматика Antlr содержит правило:
ruleAssignable: ruleIdentifier | ruleIdentifier;
(Уловка [Identifier|ID]
основана на ответе на вопрос о перекрестных ссылках . Я просто скопировал его, не понимая полностью :) Я также попытался понять, как это решается в грамматике Xbase:
{XAssignment} /* (declaringType=[types::JvmDeclaredType] '::')? */ feature=[types::JvmIdentifiableElement|ValidID] OpSingleAssign value=XAssignment
Кажется, он использует только перекрестные ссылки, и я не вижу, как обрабатывается объявление новой переменной.