This tutorial presents the Xtext framework, a toolsuite for the generation of plain text based model editors. Such textual editors provide syntax highlighting, content assist (ctrl-space), an outline, and much more out-of-the-box. You will start by creating a textual syntax for Turing Machines.
An Xtext grammar is always related to a specific EMF meta model. The grammar defines a concrete syntax in which instances of the meta model (the abstract syntax) can be serialized and stored. Xtext supports two ways of linking a grammar with a meta model: either creating a grammar for an existing meta model, or creating a grammar first and generating a meta model out of it. Here we will use the former approach, reusing the meta model for Turing Machines that you already defined earlier.
"platform:/resource/de.cau.cs.rtprak.login.turingmodel/model/turing.ecore"
Use ctrl + space for getting content assist to create a valid model following the predefined grammar. The syntax will probably look similar to this:
TuringMachine { states { State blub { }, State blah { outgoing { Transition { target blub } } } } } |
The predefined grammar is not very nice. That's why now your creative part comes into play. Change the Xtext grammar file to a grammar of your liking, which should support a simple and readable syntax for Turing Machines. All required documentation for this task is found at http://www.eclipse.org/Xtext/.
Some hints:
enum
grammar rule (see documentation). This is not correct in the predefined grammar and is marked with a TODO note.org.eclipse.xtext.common.Terminals
at the top of the document and hit F3 to see those terminal definitions.Test the new grammar by re-generating the code (after the first time, the GenerateTuring workflow should be available in the run configurations menu) and starting a test instance of Eclipse. Use your newly designed textual syntax for writing a Turing Machine that copies the input word infinitely often.
Xtext supports automatic formatting, which is available in the text editor with right-click → Format or ctrl+shift+F. However, the formatter must be configured in order to generate good results. Write a formatter configuration that fits well to your syntax by editing the generated file TuringFormatter
in the formatting
subpackage. Learn how this is done by reading the Xtext reference documentation → Runtime Concepts → Formatting.
The generated code includes some automatic validation of models with respect to syntactic issues. If the token sequence in a text file does not conform to the grammar, error markers are shown at appropriate points in the text. However, this should be augmented by semantic validation by checking high-level properties of the model. Implement such a semantic validation by editing the generated file TuringJavaValidator
in the validation
subpackage. Learn how this is done by reading the Xtext reference documentation → Runtime Concepts → Validation → Custom Validation. You should implement at least the following checks:
The generated code includes a parser for text files in your syntax. This parser is simply used with the same interface as for any other EMF models: resource sets (see the Xtext reference documentation → Integration with EMF and Other EMF Editors). Your final task for this tutorial is to reuse the Turing controller you implemented in the EMF tutorial for simulating Turing Machine models, this time applying it to .tuxt
text files. However, instead of using a fixed path to your model file, we will now use a menu contribution in order to set the file path dynamically. This contribution will be put into the popup menu of the Navigator / Project Explorer view by configuring a visibility expression that tests the currently selected (right-clicked) elements. The contribution shall only be visible if the selected files have the extension tuxt, which is assigned to our mighty textual syntax.
TuringHeadController
, the Turing Machine simulator. Open plugin.xml
→ Dependencies and add org.eclipse.ui if not on the list yet. Go to Extensions and add org.eclipse.ui.menus.SetFileHandler
and put it into some package of that plugin. Remove the suggested interface and set org.eclipse.core.commands.AbstractHandler
as superclass instead.Use the following method stub for SetFileHandler
(this requires a plugin dependency to org.eclipse.core.resources):
/** * {@inheritDoc} */ @Override public Object execute(ExecutionEvent event) throws ExecutionException { ISelection selection = HandlerUtil.getCurrentSelection(event); if (selection instanceof IStructuredSelection) { Object element = ((IStructuredSelection) selection).getFirstElement(); if (element instanceof IFile) { IFile file = (IFile) element; // TODO update the static reference to the simulation file } } return null; } |
modelFile
to TuringHeadController
and directly set that field in the TODO part of the execute
method shown above.modelFile
in the initialize
method.