Home » Modeling » TMF (Xtext) » About cross references & scoping
About cross references & scoping [message #1005813] |
Mon, 28 January 2013 15:15  |
Eclipse User |
|
|
|
Hi there!
I just signed up here as a person that is by now totally desperate! I've searched what felt like the entire internet for answers to what I think is a quite a simple question about xtext, but have yet to succeed. This is my last hope to find an answer
So what is it about: It's about cross references and scoping in xtext.
Okay so in my grammar, there are some cross-references, like:
SomeRule:
name = [SomeOtherRule];
But this doesn't always work in the generated language. It works in most cases, but sometimes, I get messages "couldn't resolve reference to SomeOtherRule x".
I've read everything what is written about scoping in the Xtext documentation. Maybe I'm just plain stupid, but that didn't help me AT ALL, as it just comes up with all kinds of different interfaces and classes and buzzwords, but it does not explain how the default scoping behaviour actually works in practice.
Aside from that I found a few blog entries where people have written stuff about the scoping. But that didn't help me either.
So then I tried to experiment with little self-created grammar examples to find out when exactly a cross-references works and when not. But I just don't get the rules behind the mechanism. For me it's just magic.
I spend hours to try to come up with an example, but because I don't understand it yet, I fail to do so. The only thing I can do is give you my entire concrete grammer where the problem occurs - without me understanding it. This is quite some code, and surely some things may not be relevant to the example I'll give you. But I don't know which are and which are not, and if it would change something semantically if I try to simplify it. So, don't get a heart attack, you won't need to think through all of this, but for the sake of completeness, I'll post everything
(by the way this grammar tries to implement the QVT Relations Language)
TopLevel:
(transformations+=Transformation)*;
Transformation:
'transformation' name=ID
'('
modelDeclarations+=ModelDeclaration (',' modelDeclarations+=ModelDeclaration)*
')'
('extends' superTransformation=[Transformation])?
'{'
(keyDeclarations+=KeyDeclaration)*
(relations+=Relation | functions+=Function)*
'}';
ModelDeclaration:
name=ID ':'
metaModelIds+=MetaModelId
|
('{' metaModelIds+=MetaModelId (',' metaModelIds+=MetaModelId)* '}');
MetaModelId:
name=ID;
KeyDeclaration:
'key' classId=ClassId
'{'
keyProperties+=KeyProperty (',' keyProperties+=KeyProperty)*
'}'
';';
ClassId:
name=ID;
KeyProperty:
PrimitiveKeyProperty | OppositeKeyProperty;
PrimitiveKeyProperty:
name=ID;
OppositeKeyProperty:
'opposite'
'('
classId=ClassId '.' name=ID
')';
Relation:
('top')? 'relation' name=ID
('overrides' superRelation=[Relation])?
'{'
(variableDeclarations+=VariableDeclaration)*
(domains+=Domain)+
(whenStatement=WhenStatement)?
(whereStatement=WhereStatement)?
'}';
VariableDeclaration:
name+=VariableName (',' name+=VariableName)* ':' type=TypeCS ';';
VariableName:
name=ID;
TypeCS:
name=ID;
Domain:
PrimitiveTypeDomain | ComplexDomain;
PrimitiveTypeDomain:
'primitive' 'domain' name=VariableName ':' type=TypeCS ';';
ComplexDomain:
('checkonly' | 'enforce')? 'domain'
modelId=[ModelDeclaration]
template=Template
('default_values' '{' (assignmentExpressions+=AssignmentExpression)+ '}')?
';';
AssignmentExpression:
name=ID '=' oclExpression=OclExpressionCS ';';
Template:
(name=VariableName)? ':' classId=ClassId
'{'
(propertyTemplateList=PropertyTemplateList)?
'}'
('{' oclExpression=OclExpressionCS '}')?;
PropertyTemplateList:
propertyTemplates+=PropertyTemplate (',' propertyTemplates+=PropertyTemplate)*;
PropertyTemplate:
PrimitivePropertyTemplate | OppositePropertyTemplate;
PrimitivePropertyTemplate:
name=ID '=' oclExpression=OclExpressionCS;
OppositePropertyTemplate:
'opposite'
'('
classId=ClassId '.' name=ID
')'
'=' oclExpression=OclExpressionCS;
WhenStatement:
{WhenStatement}
'when'
'{'
(oclExpressions+=OclExpressionCS ';')*
'}';
WhereStatement:
{WhereStatement}
'where'
'{'
(oclExpressions+=OclExpressionCS ';')*
'}';
Function:
'function' name=ID
'('
(parameters+=ParameterDeclaration (',' parameters+=ParameterDeclaration)*)?
')'
':' type=TypeCS
(';' | '{' oclExpression=OclExpressionCS '}');
ParameterDeclaration:
name=VariableName ':' type=TypeCS;
OclExpressionCS:
concatenatedOclExpressions+=ConcatenatedOclExpression
('=' concatenatedOclExpressions+=ConcatenatedOclExpression)?;
ConcatenatedOclExpression:
oclExpressionTerms+=OclExpressionTerm ('+' oclExpressionTerms+=OclExpressionTerm)*;
OclExpressionTerm:
'(' OclExpressionCS ')' | Template | IfExpCS | VariableExpCS | CallExpCS | LiteralExpCS;
IfExpCS:
'if' ifOclExpression=OclExpressionCS
'then' thenOclExpression=OclExpressionCS
'else' elseOclExpression=OclExpressionCS
'endif';
VariableExpCS:
name=[VariableName];
CallExpCS:
PropertyCallExpCS | CodeCallExp;
PropertyCallExpCS:
name=[VariableName] '.' properties+=Property ('.' properties+=Property)*;
Property:
name=ID;
CodeCallExp:
name=[CallableCode]
'('
(parameters+=CodeCallExpParameter)? (',' parameters+=CodeCallExpParameter)*
')';
CallableCode:
Relation | Function;
CodeCallExpParameter:
name=[VariableName];
LiteralExpCS:
StringLiteralExp | IntLiteralExp | FloatLiteralExp;
StringLiteralExp:
name=STRING;
IntLiteralExp:
name=INT;
FloatLiteralExp:
name=FLOAT;
terminal FLOAT returns ecore::EFloat:
('0'..'9')+ '.' ('0'..'9')+;
Ok still there? So, now here's a snippet of some example code where a problem with the scope arises:
transformation <...> {
<...>
top relation ClassToTable {
cn, prefix:String;
checkonly domain uml c:Class {
namespace = p:Package {},
kind = 'Persistent',
name = cn
};
enforce domain rdbms t:Table {
schema = s:Schema {},
name = cn,
column = cl:Column {
name = cn + '_tid',
type = 'NUMBER'
},
theKey = k:Key {
name = cn + '_pk',
column = cl ####### ERROR ########
}
};
when {
PackageToSchema (p, s); ####### ERROR ########
}
where {
prefix = '';
AttributeToColumn (c, t, prefix); ####### OKAY #######
}
}
<...>
}
I get errors "couldn't resolve reference to VariableName <x>" at the lines marked with ####### ERROR ########. So the VariableNames p, s and cl are not visible at those points.
However, it seems there's no problem with the variables c, t and prefix (See line marked with ####### OKAY ####### )
And THAT'S what I don't get. Whatever mechanism I think of that xtext might be using, these two incidents seem to be contradictory. Because regarding the hierarchy of the rule's relations, I don't really see a difference?!
...Puh, thanks so much for those of you who have read up to here! I would be so thankful if anyone can explain to me why exactly the references to c, t, and prefix are visible in the where-block, but the references to p and s in the when-block are not.
In one sentence, what I need to understand ist:
What is the default scope of a feature? where can it be references, where not?
Thanks again, Regards Thomas
|
|
| |
Re: About cross references & scoping [message #1006113 is a reply to message #1005813] |
Tue, 29 January 2013 19:12  |
Eclipse User |
|
|
|
I'm trying to solve something similar as I thought I understood the cross referencing and saw it working as I expected, until I tried getting my locally defined variables in one module to refer to properties of another class module. Then I got the same error.
Having a quick look at your code, it would seem that the line
should work with a cross ref of ID since there is no dot in cl.
The grammar is large so it's hard to tell which rule that is running but if the error is saying VariableName then it must be one that contains
However I think you may mean
name=[VariableDeclaration];
since VariableName is just an ID which is a terminal or token rather than a type that can be referenced. your cross ref needs to be to another type.
The OKAY ones c, t and prefix must work because they are actually just IDs (haven't been declared as a variable).
I expect I'll be posting my own problem in a day or two when I've shrunk it down to a simple example, so I hope anyone reading this will spare me some advice too. It is a problem of QualifiedNames where I can reference items in another module as Class.item but not as instance.item. Once I run out of ideas I'll post it up.
Ian
|
|
|
Goto Forum:
Current Time: Wed Jul 23 15:28:20 EDT 2025
Powered by FUDForum. Page generated in 0.26649 seconds
|