0
votes

I am stuck in writing a DSL using XText. Let us assume that I want to parse something like this:

A {
  B, //this comma is needed
  C, 
  D {E}, //comma is optional after a closing curly brace
  F {G}
  H
}
I,
J

It should be represented by the types Model and Class, where Model contains a list of classes.

What I do have currently is:

Model: (classes += Class)*
Class: name = ID ('{' (subclasses += Class) (',' subclasses += Class)* '}')?

This would work if classes must be delimited by a comma, independent from them having subclasses or not. However, since a Class can have subclasses bracketed by curly braces, a comma is not a must after a closing curly brace.

This means I need a grammar expressing the following:

Class: ID (',' Class | '{' subclasses += Class '}' ','? Class)?

Since I am not able to reference the containing rule, the Class rule reference inside Class will not work. I believe that there is a simple solution for this issue which I just can not see.

Edit: I belive a lookbehind would be a solution. However, it seems to me like this is not suppoerted in XText.

1

1 Answers

2
votes

you can try something like the following (+ a validation for the very last comma)

Model:
    ((classes+=ClassWithBraces|classes+=ClassWithComma)* classes+=ClassAtEnd?);

ClassWithComma returns Class:
    name=ID ","
;

ClassWithBraces returns Class:
    name=ID =>("{" ((classes+=ClassWithBraces|classes+=ClassWithComma)* classes+=ClassAtEnd?) "}") ","?
;

ClassAtEnd returns Class:
    name=ID
;