具有后视功能的 XText DSL

XText DSL with lookbehind

我一直在使用 XText 编写 DSL。让我们假设我想解析这样的东西:

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

它应该由类型 Model 和 Class 表示,其中 Model 包含 类.

的列表

我目前拥有的是:

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

如果 类 必须用逗号分隔,这将起作用,与它们是否具有 sub类 无关。但是,由于 Class 可以用花括号括起子 类,因此在右花括号后逗号不是必须的。

这意味着我需要一个表达以下内容的语法:

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

由于我无法引用包含规则,因此 Class 中的 Class 规则引用将不起作用。我相信这个问题有一个我看不到的简单解决方案。

编辑:我相信回顾会是一个解决方案。但是,在我看来,XText 不支持这一点。

您可以尝试以下操作(+ 最后一个逗号的验证)

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
;