In my DSL variables are dynamic, they are created the first time a value is assigned to them. So this is a valid code:
a = 0
b = 2 // new variable created
a = 3 // existing variable reassigned
My naive approach is to have rules like this
Identifier:
ID; // ID from Terminals
Assignable:
{Assignable} ref=[Identifier|ID] |
{Assignable} newVar=Identifier;
It doesn't work, complaining "The following alternatives can never be matched: 2". It's understandable, because the generated Antlr debug grammar contains a rule:
ruleAssignable: ruleIdentifier | ruleIdentifier;
(The trick of [Identifier|ID]
comes from a response to a question on cross-referencing. I just copied it without fully understanding :) I also tried to grok how it's solved in the Xbase grammar:
{XAssignment} /* (declaringType=[types::JvmDeclaredType] '::')? */ feature=[types::JvmIdentifiableElement|ValidID] OpSingleAssign value=XAssignment
It seems to use only cross-referencing, and I can't see how new variable declaration is handled.