我想使用 xtext 创建一个极其简单的 DSL,具有以下功能:
- 它将有两种基本类型:数字和字符串
- 用户可以定义自己的类,类由字段声明组成
- 字段声明将名称与类型相关联,其中类型可以是类或基元
以下是我对 DSL 的尝试,类定义和引用工作正常,但我无法弄清楚如何拥有原始类型。 “字符串”和“数字”文字不起作用:
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;
睡过之后,我认为正确的答案是改变我的方法。在上面的定义中我们有
Field:
type=[FieldType] name=ID ";";
这定义了一个名为“Field”的规则,它由两部分组成; “类型”和“名称”。这是提出问题的类型部分。方括号表示我们期待一个实例FieldType
,即:
FieldType: Class | '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)*
"}";
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)