我想使用xtext创建一个非常简单的DSL,具有以下功能:
以下是我对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;
答案 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)*
"}";