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

0

11

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?
Schaal answered 5/5, 2020 at 20:57 Comment(2)
For a different spin on how to do this, see our DMS Software Reengineering Toolkit: semdesigns.com/Products/DMS/DMSToolkit.html. Grammars as models, auto AST building, surface-syntax directed rewriting constrained by semantic conditions, "scoping rules" (we call this "name resolution") and control-flow/dataflow analysis using attribute grammars.Gibran
Some related bits: Beautiful Racket which may be too elementary for you; Syntax Parse which you mentioned (though there are accessors for attributes, using eitherattribute or, under #', dot-notation); Syntax Spec which is relatively new but may fit your ideal workflow more closely.Tumer

© 2022 - 2024 — McMap. All rights reserved.