local scope, qualified name and Cyclic resolution of lazy links [message #707310] |
Mon, 01 August 2011 13:35 |
alex.ren2006 Messages: 46 Registered: June 2011 |
Member |
|
|
Hi all, I am currently building an IDE for ATS (www.ats-lang.org). With your help (http://www.eclipse.org/forums/index.php/t/226107/ http://www.eclipse.org/forums/index.php/t/226022/), I made progress dealing with local scope. Now I got into some problems dealing with both scope and cross-reference. For clarity, I use the following sample grammar for language "Myscope".
=================================================
grammar org.xtext.example.mydsl.MyScope with org.eclipse.xtext.common.Terminals
generate myScope "http://www.xtext.org/example/mydsl/MyScope"
Program:
body
;
body: {body}
mdec+=scopedec*
(mscope+=scope
| mdef+=def
)*
;
scopedec:
'extern' 'scope' ent=ID
;
scope: {scope}'scope' entity=[scopedec | ID] mbody=body 'end';
def: name=ID '=' (mint=INT | mval=[def | ID]); =================================================
The corresponding source code would be something like this
=================================================
extern scope sz
xx = 3
ze = 4
scope sz
xx = 3
qq = 4
rr = xx
ze = 4
ff = ze
end =================================================
I bind my own "MyScopeQualifiedNameProvider" to the runtime. The code goes as follows
=======================================
public class MyScopeQualifiedNameProvider extends
DefaultDeclarativeQualifiedNameProvider {
@Inject
private IQualifiedNameConverter converter = new IQualifiedNameConverter.DefaultImpl();
private int counter = 3;
private Hashtable<EObject, String> nametable = new Hashtable<EObject, String>();
public QualifiedName getFullyQualifiedName(final EObject obj) {
QualifiedName t = super.getFullyQualifiedName(obj);
if (obj instanceof scope) {
String name = nametable.get(obj);
if (name == null) {
name = ((scope)obj).getEntity().getEnt();
// name = Integer.toString(counter++);
System.out.println("====================" + name);
nametable.put(obj, name);
}
t=converter.toQualifiedName(name);
}
if (t != null) {
System.out.println("====================" + t.toString());
}
return t;
}
} =====================================
But when I run the eclipse application, I got the following error
====================
An internal error occurred during: "XtextReconcilerJob".
Cyclic resolution of lazy links : scope.entity->scope.entity =====================
I guess it has something to do with the cross-reference which I didn't understand very well. In my code, I really want to get the corresponding string of scope. How can I do it? Thanks a lot.
|
|
|
|
|
Re: local scope, qualified name and Cyclic resolution of lazy links [message #707383 is a reply to message #707341] |
Mon, 01 August 2011 15:26 |
alex.ren2006 Messages: 46 Registered: June 2011 |
Member |
|
|
The following is my new "MyScopeQualifiedNameProvider". It works well.
=============================================
package org.xtext.example.mydsl.naming;
import java.util.Collections;
import java.util.Hashtable;
import org.eclipse.xtext.nodemodel.BidiIterator;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.naming.DefaultDeclarativeQualifiedNameProvider;
import org.eclipse.xtext.naming.IQualifiedNameConverter;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.util.IResourceScopeCache;
import org.eclipse.xtext.util.PolymorphicDispatcher;
import org.eclipse.xtext.util.SimpleAttributeResolver;
import org.eclipse.xtext.util.Strings;
import org.eclipse.xtext.util.Tuples;
import org.xtext.example.mydsl.myScope.scope;
import org.xtext.example.mydsl.myScope.scopedec;
import com.google.common.base.Function;
import com.google.inject.Inject;
import com.google.inject.Provider;
public class MyScopeQualifiedNameProvider extends
DefaultDeclarativeQualifiedNameProvider {
private PolymorphicDispatcher<QualifiedName> qualifiedName = new PolymorphicDispatcher<QualifiedName>(
"qualifiedName", 1, 1, Collections.singletonList(this),
PolymorphicDispatcher.NullErrorHandler.<QualifiedName> get()) {
@Override
protected QualifiedName handleNoSuchMethod(Object... params) {
return null;
}
};
@Inject
private IQualifiedNameConverter converter = new IQualifiedNameConverter.DefaultImpl();
@Inject
private IResourceScopeCache cache = IResourceScopeCache.NullImpl.INSTANCE;
private Function<EObject, String> resolver = SimpleAttributeResolver
.newResolver(String.class, "name");
protected Function<EObject, String> getResolver() {
return resolver;
}
private int counter = 0;
private Hashtable<EObject, String> nametable = new Hashtable<EObject, String>();
public QualifiedName getFullyQualifiedName(final EObject obj) {
return cache.get(Tuples.pair(obj, "fqn"), obj.eResource(),
new Provider<QualifiedName>() {
public QualifiedName get() {
EObject temp = obj;
String name = null;
if (temp instanceof scope) {
name = nametable.get(temp);
if (name == null) {
// name = ((scope)temp).getEntity().getEnt();
ICompositeNode cnode = NodeModelUtils
.findActualNodeFor(temp);
BidiIterator<INode> iter = cnode.getChildren()
.iterator();
int k = 0;
while (iter.hasNext()) {
name = NodeModelUtils.getTokenText(iter
.next());
// System.out.println("===================="
// + name + "_" + k);
if (4 == k) {
break;
}
k++;
}
nametable.put(temp, name);
}
} else if (temp instanceof scopedec) {
name = ((scopedec) obj).getEnt();
} else {
QualifiedName qualifiedNameFromDispatcher = qualifiedName
.invoke(temp);
if (qualifiedNameFromDispatcher != null)
return qualifiedNameFromDispatcher;
name = getResolver().apply(temp);
if (Strings.isEmpty(name))
return null;
}
QualifiedName qualifiedNameFromConverter = converter
.toQualifiedName(name);
while (temp.eContainer() != null) {
temp = temp.eContainer();
QualifiedName parentsQualifiedName = getFullyQualifiedName(temp);
if (parentsQualifiedName != null) {
qualifiedNameFromConverter = parentsQualifiedName
.append(qualifiedNameFromConverter);
break;
}
}
System.out.println("===================="
+ qualifiedNameFromConverter.toString());
return qualifiedNameFromConverter;
}
});
}
}
=======================
The only thing which makes me to feel uncomfortable is the hard coded comparison "if (4 == k)". But in the end, something has to be hard coded.
[Updated on: Mon, 01 August 2011 15:30] Report message to a moderator
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03408 seconds