In this final chapter we briefly present Xbase, a reusable expression language completely interoperable with the Java type system. By using Xbase in your DSL, you will inherit all the Xbase mechanisms for performing type checking according to the Java type system and the automatic Java code generation. Xbase also comes with many default implementations of UI aspects. The Xbase expression language is rich and has all the features of a Java-like language, such as object instantiation, method invocation, exceptions, and so on, and more advanced features such as lambda expressions and type inference. The Xtend programming language itself is built on Xbase.
You're reading from Implementing Domain-Specific Languages with Xtext and Xtend
As we saw throughout the examples of this book, it is straightforward to implement a DSL with Xtext. This is particularly true when you only need to care about structural aspects; in the Entities DSL of Chapter 2, Creating Your First Xtext Language, we only need to define the structure of entities. Things become more complicated when it comes to implementing expressions in a DSL; as we saw in Chapter 8, An Expression Language, we need to define many rules in the grammar using left factoring to avoid left recursion, even when we only deal with a limited number of expressions. Besides the grammar, the validation part also becomes more involved due to type checking. When we mix structures and expressions, like in the SmallJava DSL, the complexity increases again; besides advanced type checking (Chapter 9, Type Checking) we also need to take care of scoping (Chapter 10, Scoping) that is implied by relations such as inheritance. An inheritance relation also requires...
For the first example of the use of Xbase, we implement a DSL similar to the Expressions DSL that we presented in Chapter 8, An Expression Language, which we call as Xbase Expressions DSL; this DSL is inspired by the Scripting Language DSL of the 7 languages examples.
First of all, we create the project:
Navigate to File | New | Project..., in the dialog navigate to the Xtext category and select Xtext Project.
In the next dialog you should specify the following names:
Project name:
org.example.xbase.expressions
Name:
org.example.xbase.expressions.Expressions
Extensions:
xexpressions
Uncheck the option Create SDK feature project
The wizard will create three projects and it will open the grammar file Expressions.xtext
.
Before running the MWE2 generator for the first time, you should modify the grammar so that it uses the Xbase
grammar, not the Terminals
grammar as we did in all previous chapters' examples:
grammar org.example.xbase.expressions...
We will ow implement a modified version of the Entities DSL we implemented in Chapter 2, Creating Your First Xtext Language using Xbase. This will allow us to implement a more involved DSL where, inside entities, we can also write operations apart from attributes (this is inspired by the Xtext Domain-Model example).
As usual we create the Xtext project by performing the following steps:
Navigate to File | New | Project..., in the dialog go to the Xtext category and select Xtext Project.
In the next dialog you should specify the following names:
Project name:
org.example.xbase.entities
Name:
org.example.xbase.entities.Entities
Extensions:
xentities
Uncheck the option Create SDK feature project
The wizard will create three projects and it will open the grammar file Entities.xtext
.
Before running the MWE2 generator for the first time, you should modify the grammar so that it uses the Xbase
grammar:
grammar org.example.xbase.entities.Entities with...
Depending on the complexity of your DSL, you might want to customize the default implementation of several components of Xbase, such as scoping and validation. This can be achieved by subclassing the corresponding Xbase classes and by specifying the bindings in the Guice module. Note that the Xbase scope provider implementation is not based on AbstractDeclarativeScopeProvider
, thus, you cannot rely on the convention for method names that we used in Chapter 10, Scoping; you will have to redefine the getScope
method. Moreover, you will have to inspect the implementation of Xbase scope provider and validator to understand which method to override.
It is also possible to override some rules of the Xbase grammar in order to change the syntactic shape of some expressions. Moreover, you can change an Xbase expression rule in order to add syntax for new expressions which are specific to your DSL. In this case, you also need to provide custom implementations for some classes of Xbase...
Xbase can add a powerful Java-like expression language to your DSL, and by implementing the model inferrer, you will automatically reuse the Xbase Java type system implementation and the generation of Java code. This does not imply that all the concepts described in all the previous chapters (validation, code generation, scoping, and so on) are useless. In fact, knowing the main concepts underlying Xtext is required to effectively implement a DSL even when using Xbase. Moreover, in case you need to modify or add expressions to a DSL that uses Xbase, you may have to provide a custom scoping and validation as well. When using Xbase, your DSL will be tightly coupled with Java, which might not always be what you need. Your DSL could be used only for writing specifications or simpler structures and in that case you will not need Xbase expressions; these would only add unwanted complexity. Alternatively, your DSL might not be bound to Java and might require code generation into another...