Domain-Specific Languages in Racket compared to Model-Driven frameworks such as Xtext

Viewed 384

Racket and Xtext are both considered as language workbenches, but they are based on different concepts and workflows.

As an experienced Xtext user, I find it difficult to adapt my thought process to Racket.

In Xtext, the grammar of a language is converted into, or mapped to, a set of classes (also called a metamodel). Xtext also generates a parser that converts a source file into a set of instances of those classes. A scoping API allows to resolve named references, so that the result is an object graph (also called a model) rather than an abstract syntax tree (AST). Such a model can be queried, transformed, or fed into a template engine to generate code.

In Racket, the reader produces an AST in the form of a syntax object. However, most examples that I have found seem to make an ad-hoc use of this syntax object. Either they are toy languages that do not need a complete object graph, or they are too complex and it is difficult to infer a general methodology.

For my current language project, after struggling with syntax objects, I have created the equivalent of a metamodel using Racket structs. Then it was fairly easy to convert a syntax object into an object graph that I could manipulate as if it were a model in EMF. However, I feel like I am not using syntax objects the way they are intended to be.

Here are my questions:

  • What tools or APIs are available to work on syntax objects and achieve a similar ease-of-use as a model-driven framework?
  • Are there documents that describe a general language development methodology in Racket, that could be applied to non-trivial languages?
  • Are there documents that explain the Racket way, compared to Xtext or any other model-driven language framework?

EDIT:

Based on the documentation for Metaprogramming helpers, syntax classes can be used to specify and compose syntax patterns, and attach attributes to their elements. They can achieve a similar purpose as the classes of a metamodel. However, as far as I can see, syntax classes are not classes, and syntax objects are not linked to syntax classes in a class-instance relationship. This has the following consequences:

  • Syntax classes do not support inheritance directly, but we can achieve a similar effect with ~or* and attribute declarations for subclasses.
  • Syntax classes do not come with accessors for their attributes: you have to call syntax-parse every time you want to read an attribute.

At this point, there are still two missing features that are not addressed in the documentation that I have found:

  • Traversing a syntax tree from child to parent: how can I get a reference to the syntax object enclosing a given syntax object?
  • Scoping: how can I define specific scoping rules for my language?
0 Answers
Related