有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在xtext语法中定义原语的java

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

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

下面是我对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;


共 (1) 个答案

  1. # 1 楼答案

    考虑到这一点,我认为正确的答案是改变我的方法。在上述定义中,我们有

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

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

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

    现在,可以清楚地看到,您可以拥有一个类的实例,但从语义上讲,无法拥有“String”或“Number”文本的实例

    我相信这就是我上面的DSL不允许我声明原语的原因。字符串/数字“类型”根本不是您可以拥有其实例的元素


    进一步思考,在原语字段和类实例字段的定义之间有一些非常重要的区别。例如,您只能在类的实例上调用方法(在我的例子中,我将字符串视为真正的原语,所以没有方法)

    因此,有两种不同类型的声明可能很重要,一种用于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)*
        "}";