Tricks for implementing scoping
In this blog, I’ll demonstrate a few tricks which can help during implementation of the scoping.
Visualizing the AST
One of the basic problems we face when implementing a DSL, is that there’s sometimes a sort of a ‘mental gap’ between the grammar definition and the ASTs it is going to produce on a parsed DSL text. This is especially true when you’re using more advanced features like (un-)assigned actions and unassigned rule calls, e.g. when creating languages with nested expressions.
With Xtext, there’s a very simple way to visualize the abstract syntax in tree-form because Xtext is EMF-based. In particular, this means that each object in the AST is an EObject contained in an instance of the XtextResource class which is a sub type of Resource. So, we can open the DSL file in any EMF model editor, not just the generated Xtext editor or the simple text editor. Eclipse EMF happens to come bundled with the ‘Generic EMF Form Editor’ as well as the ‘Sample Reflective Ecore Model Editor’ both of which present a folded-tree view of the AST. Just select the DSL file, rightclick and select “Open With > Other…” and select any of the two editors mentioned to visualize the AST. By splitting the editor pane (just click-hold the EMF tree editor and drag far enough to some other area of the Eclipse window), you’ll even have a parallel/simultaneous view of both the text as well as the tree.
Using debugging mode
Running your DSL inside an Eclipse instance in debug mode is a nicely interactive way of implementing the scoping, because the Eclipse Java debugger is capable of ‘hot deploying’ the class inside the secondary VM and re-starting the debugging from a convenient spot. This means that, while in debug mode, you can change the code and have it re-started (usually from the start of the method you’ve changed) without having to re-deploy or even having to re-trigger the event -in our case, usually a Ctrl-Space to invoke content assist.
Using println()-style debugging
This statement holds true as long as the class’ signature doesn’t change. Assuming that the custom scope provider inherits fromAbstractDeclarativeScopeProvider, you still have to find out what methods would be called, before you can use Here’s a simple trick: override the getScope method from IScopeProvider to print out some useful debugging info as follows.
This will print the method predicates/signatures the Xtext runtime tries to call (through the Java-based polymorphic dispatch mechanism shipped with Xtext) on the console of the primary Eclipse instance. It doesn’t take into account the second type of method predicates/signatures which is only class-based, but I find that’s something you use less often and is easier to predict. Nevertheless, it’s easy to add that to the code above as well: a quick look at the AbstractDeclarativeScopeProvider class and line 112 (at least, in Xtext 1.0.1/SR1) of its polymorphicFindScopeForClassName method will probably do the trick. (Let me know if it doesn’t!)