在 xtext 语法中定义原语 [英] Defining Primitives within xtext Grammar
问题描述
我想使用 xtext 创建一个非常简单的 DSL,具有以下功能:
I would like to create an incredibly simple DSL using xtext, with the following features:
- 它将有两种基本类型:数字和字符串
- 用户可以定义自己的类,这些类由字段声明组成
- 字段声明将名称与类型相关联,其中类型可以是类或原始类型
以下是我对 DSL 的尝试,类定义和引用工作正常,但我不知道如何拥有原始类型.'String' 和 'Number' 文字不起作用:
The following is my attempt at a DSL, the class definition and references work fine, but I cannot figure out how to have primitive types. The 'String' and 'Number' literals are not working:
Model:
(classes+=Class)*
(fields+=Field)*;
FieldType: Class | 'String' | 'Number';
Field:
type=[FieldType] name=ID ";";
Class:
"class" name=ID
"{"
(fields+=Field)*
"}";
这是我希望对上述 DSL 有效的示例:
Here is an example I expect to be valid against the above DSL:
Class SomeClass {
}
// This works!
SomeClass reference;
// This does not, doesn't recognise the "String" literal
String string;
请注意,接下来我将支持分配.因此,我的 DSL 需要包含数字/字符串文字的概念,以便它支持 Number someNumber = 123;
Note that further down the line I will be supporting assignment. Thus my DSL will need to incorporate the concept of number / string literals, such that it supports Number someNumber = 123;
推荐答案
睡了之后,我认为正确的答案是改变我的方法.在上面的定义中,我们有
Having slept on it, I think the right answer is to change my approach. In the above definition we have
Field:
type=[FieldType] name=ID ";";
这定义了一个名为字段"的规则,它由两部分组成;类型"和名称".出现问题的是类型部分.方括号表示我们需要一个 FieldType
的实例,即:
This defines a rule called "Field" which is made up of two parts; the "type" and the "name". It is the type part that is presenting the issue. The square brackets denote we are expecting an instance of FieldType
, which is:
FieldType: Class | 'String' | 'Number';
现在,很明显您可以拥有一个类的实例,但从语义上讲,没有办法拥有字符串"或数字"字面量的实例.
Now, it's clear to see that you can have an instance of class, but semantically there's no way to have an instance of the 'String' or 'Number' Literals.
我相信这就是为什么我上面的 DSL 不允许我声明原语的原因.字符串/数字类型"根本不是您可以拥有实例的元素.
I believe this to be why my DSL above won't let me declare the primitives. The String/Number "types" simply aren't elements that you can have an instance of.
进一步思考,原始字段的定义与作为类实例的字段的定义之间存在一些非常重要的区别.例如,您只能在类的实例上调用方法(在我的情况下,我将 String 视为真正的原语,因此没有方法).
Thinking further, there are some very important distinctions between the definitions of fields that are primitive vs. those which are instances of a class. For example, you can only invoke methods on instances of a class (in my case I am treating String as a true primitive, so no methods).
因此,拥有两种不同类型的声明可能很重要,一种用于 PrimitiveField
,另一种用于 ObjectField
.字段可以是以下之一:
Thus, it's probably important to have two different type of declarations, one for PrimitiveField
and one for ObjectField
. A field can be either of these:
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)*
"}";
这篇关于在 xtext 语法中定义原语的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!