This chapter describes the basic MPS notions: nodes, concepts, and languages. These are key to proper understanding of how MPS works. They all only make sense when combined with the others and so we must talk about them all together. This section aims to give you the essence of each of the elements. For further details, you may consider checking out the sections devoted to nodes, concept (structure language), and languages (project structure).
Abstract Syntax Tree (AST)
MPS differentiates itself from many other language workbenches by avoiding the text form. Your programs are always represented by an AST. You edit the code as an AST, you save it as an AST you compile it as, well, as an AST. This allows you to avoid defining grammar and building a parser for your languages. You instead define your language in terms of types of AST nodes and rules for their mutual relationships. Almost everything you work with in the MPS editor is an AST-node, belonging to an Abstract Syntax Tree (AST). In this documentation we use a shorter name, node, for AST-node.
Nodes form a tree. Each node has a parent node (except for root nodes), child nodes, properties, and references to other nodes.
The AST-nodes are organized into models. The nodes that don't have a parent, called root nodes. These are the top-most elements of a language. For example, in BaseLanguage (MPS' counterpart of Java), the root nodes are classes, interfaces, and enums.
Nodes can be very different from one another. Each node stores a reference to its declaration, its concept. A concept sets a "type" of connected nodes. It defines the class of nodes and coins the structure of nodes in that class. It specifies which children, properties, and references an instance of a node can have. Concept declarations form an inheritance hierarchy. If one concept extends another, it inherits all children, properties, and references from its parent.
Since everything in MPS revolves around AST, concept declarations are AST-nodes themselves. In fact, they are instances of a particular concept, ConceptDeclaration.
A language in MPS is a set of concepts with some additional information. The additional information includes details on editors, completion menus, intentions, typesystem, dataflow, etc. associated with the language. This information forms several language aspects.
Obviously, a language can extend another language. An extending language can use any concepts defined in the extended language as types for its children or references, and its concepts can inherit from any concept of the extended language. You see, languages in MPS form fully reusable components.
While languages allow their users to create code, which is stored in models, generators can transform these source models into target models. Generators perform model-to-model conversion on AST models. The target models use different languages than the source models and serve one or more purposes:
- can be converted to text source files and then compiled with standard compilers (Java, C, etc.)
- can be converted to text documents and used as such (configuration, documentation - property files, xml, pdf, html, latex)
- can be directly interpreted
- can be used for code analysis or formal verification by a third party tool (CBMS, state-machine reachability analysis, etc.)
- can be used for simulation of the real system
Generators typically rely on a Domain framework - a set of libraries that the generated code calls or inherits from. The framework encodes the stable part of the desired solution, while the variable part is contained in the actual generated code.
Generation in MPS is done in phases - the output of one generator can become the input for another generator in a pipeline. An optional model-to-text conversion phase (TextGen) may follow to generate code in a textual format. This staged approach helps bridge potentially big semantics gaps between the original problem domain and the technical implementation domain. It also encourages re-use of generators.