简体   繁体   中英

Xtext cross-reference to constants of Enum

I try to write new grammar and I wrote something like Enum in Java, that enables for Var (a type in my grammar) to be a set of predefined constants.

I want it to recognize the constants that include to this Var, but I didn't find a way how to do it (although I try to read the book "Implementing Domain-Specific Languages with Xtext and Xtend", and searched a lot on the internet)

So I made a little example on the Domainmodel grammar:

Domainmodel:
    (elements+=AbstractElement)*;

PackageDeclaration:
    'package' name=QualifiedName '{'
    (elements+=AbstractElement)*
    '}';

AbstractElement:
    PackageDeclaration | Type | Import;

QualifiedName:
    ID ('.' ID)*;

Import:
    'import' importedNamespace=QualifiedNameWithWildcard;

QualifiedNameWithWildcard:
    QualifiedName '.*'?;

Type:
    DataType | Entity | Var;

DataType:
    'datatype' name=ID;

Entity:
    'entity' name=ID ('extends' superType=[Entity|QualifiedName])? '{'
    (features+=Feature)*
    '}';

Feature:
    (many?='many')? name=ID ':' type=[VarDecl |QualifiedName];

Var:
    kind='Var' var=VarDecl;

VarDecl:
    type=VarType name=SimpleVarID;

SimpleVarID:
    ID ('[' INT ']')*;

VarType:
    name='boolean'
    | '{' const+=TypeConstant (',' const+=TypeConstant)* '}';

TypeConstant:
    ID | INT | 'FALSE' | 'TRUE';

So, the example is:

Var  {LEFT,RIGHT} move

entity C {
    content: move
    side: LEFT //ERROR: couldn't resolve reference to VarDecl 'LEFT'
}

I know that LEFT isn't VarDecl, it's ID, but I don't know how to do it different. What I need to do so that LEFT would be recognize like something that include to move?
comment: in my real grammar I actually try to do move==LEFT (boolean operator) and it's not recognize LEFT as constant of move (the same error appears) .

Thanks!

i am not sure if i get you but here are some hints

first you can only reference the things you allow in the grammar

QualifiedName:
    TypeConstantLiteral ('.' TypeConstantLiteral)*;

VarType:
    name='boolean'
    | '{' const+=TypeConstant (',' const+=TypeConstant)* '}';

Feature:
    (many?='many')? name=ID ':' type=[Referrable | QualifiedName];    

Referrable:
    VarDecl | TypeConstant
;

TypeConstant:
    name=TypeConstantLiteral;

TypeConstantLiteral:ID | INT | 'FALSE' | 'TRUE';    

then you have to care about naming

class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {

    override bindIQualifiedNameProvider() {
        SimpleNameProvider
    }

}

(depending in your usecase you may use your own subclass of DefaultDeclarativeNameProvider instead

please note: this does not cover typesystem / scoping / validation yet

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM