在xtext语法中定义基元

时间:2013-10-18 23:24:58

标签: java xtext

我想使用xtext创建一个非常简单的DSL,具有以下功能:

  • 它将有两种基本类型:Number和String
  • 用户可以定义自己的类,这些类由字段声明
  • 组成
  • 字段声明将名称与类型相关联,其中类型可以是类或基元

以下是我对DSL的尝试,类定义和引用工作正常,但我无法弄清楚如何使用原始类型。 'String'和'Number'文字不起作用:

Model:
    (classes+=Class)*
    (fields+=Field)*;

FieldType: Class | 'String' | 'Number';

Field:
    type=[FieldType] name=ID ";";

Class:
    "class" name=ID
    "{"
        (fields+=Field)*
    "}";

以下是我希望对上述DSL有效的示例:

Class SomeClass {

}

// This works!
SomeClass reference;

// This does not, doesn't recognise the "String" literal
String string;

请注意,我将进一步支持任务。因此,我的DSL需要包含数字/字符串文字的概念,以便它支持Number someNumber = 123;

1 个答案:

答案 0 :(得分:0)

睡着了,我认为正确的答案是改变我的方法。在上面的定义中我们有

Field:
    type=[FieldType] name=ID ";";

这定义了一个名为“Field”的规则,它由两部分组成; “类型”和“名称”。它是提出问题的类型部分。方括号表示我们期待FieldType的实例,即:

FieldType: Class | 'String' | 'Number';

现在,很明显你可以看到一个类的实例,但从语义上来说,没有办法拥有'String'或'Number'文字的实例。

我相信这就是为什么我上面的DSL不会让我宣布原语。字符串/数字“类型”不是您可以拥有实例的元素。


进一步思考,原始字段的定义与类的实例定义之间存在一些非常重要的区别。例如,您只能在类的实例上调用方法(在我的情况下,我将String视为真实的原语,因此没有方法)。

因此,拥有两种不同类型的声明可能很重要,一种用于PrimitiveField,另一种用于ObjectField。字段可以是以下任何一种:

Model:
    (classes+=Class)*
    (fields+=Field)*;

PrimitiveType: 'String' | 'Number' | 'Boolean';

Field:
    PrimitiveField | ObjectField
;

PrimitiveField:
    type=PrimitiveType name=ID ";"
;
ObjectField:
    type=[Class] name=ID ";";

Class:
    "class" name=ID
    "{"
    (fields+=Field)*
    (methods+=Method)*
    "}";