Search code examples
dslxtext

Xtext: Error when compiling DSL when doing cross reference for 3 types of parser rules


I currently trying to create a DSL looking like the following:

    Type:
        PrimitiveField | ObjectField | EnumField
    ;

    PrimitiveField:
        type=PrimitiveType
    ;

    ObjectField:
        type=[Entity]
    ;

    EnumField:
        type=[Enum]
    ;

    enum PrimitiveType: string = 'string' | int = 'int' | float =  'float'

    Entity:
      'entity' name = ID ('extends' superType = [Entity])? '{' 
         props = String ':'type = Type
       '}'
    ;

    Enum:
        'enum' name = ID '{'
            enums += STRING ('And' enums += STRING )*
        '}'
    ;

The property in Entity should be able to reference all entity / primitive / enum created. However Xtext could not compile properly. I got the FileNotFoundException. Can anyone point me in the correct direction for this type of scenario ?

Previously it is working without the new addition of 'enum' into DSL definiton.

I have tried the following to get the compiling error gone:

    Type:
        PrimitiveField | ObjectField | Enum
    ;

    PrimitiveField:
        type=PrimitiveType
    ;

    ObjectField:
        type=[Entity]
    ;

    enum PrimitiveType: string = 'string' | int = 'int' | float =  'float'

    Entity:
      'entity' name = ID ('extends' superType = [Entity])? '{' 
         props = String ':'type = Type
       '}'
    ;

    Enum:
        'enum' name = ID '{'
            enums += STRING ('And' enums += STRING )*
        '}'
    ;

However the result is not correct because when i define :

    entity teee {
       'aper' : test 
    }

    enum test {
        'dark'
    }

Eclipse gives me error: cannot find entity 'test'


Solution

  • Your rules ObjectField and EnumField are matching the same token rule : ID. You have to merge your 2 references into one reference, look at this example:

    Type:
        PrimitiveField | ReferenceField
    ;
    
    ReferenceField:
        type=[EntityOrEnum]
    ;
    
    EntityOrEnum:
        Entity | Enum
    ;
    

    Now, referenceField can link to Entity or Enum and your test example will be ok.