简体   繁体   中英

Xtext cross reference with this keyword

I am currently in the process of making a new DSL with the help op Xtext. I want to be able to define rules in my grammar, where certain values can be manipulated and refer to the current object using this . However, I cannot get the syntax right for it to work.

I have taken a bit of code from the Xtext Expressions example and modified it to be able to also put a cross-reference to the cards value. How can I use the this keyword? I understood from some other SO questions that I can use my own scoping provider for this, but do not know where to start.

See some code:

// MyDSL.xtext

Game returns Game:
    'Game'
    name=STRING
    ...
    ('Cardpropertytypes' '{' cardpropertytypes+=CardPropertyType ( "," cardpropertytypes+=CardPropertyType)* '}' )?
    cards += Card*
;

Card returns Card:
    'Card'
    name=ID
    '{'
        'type' type=[CardType]
        ('cost' '{' cost+=Cost ( "," cost+=Cost)* '}' )?
        ('properties' '{' properties+=CardProperty ( "," properties+=CardProperty)* '}' )?
        ('rules' '{' rules+=CardRule ( "," rules+=CardRule)* '}' )?
        ('actions' '{' actions+=CardAction ( "," actions+=CardAction)* '}' )?
    '}';

CardRule returns CardRule:
    {CardRule}
    '{'
        ('description' description=STRING)?
        ('requirements' requirements=Addition)?
        ('action' action=Addition)?
        ('duration' duration=Duration)?
    '}';

CardProperty returns CardProperty:
  type=[CardPropertyType] (':' value=INT)?;

Addition returns Expression:
  Multiplication ({Addition.left=current} '+' right=Multiplication)*;

Multiplication returns Expression:
  Primary ({Multiplication.left=current} '*' right=Primary)*;

Primary returns Expression:
  Literal |
  '(' Addition ')';

Literal returns Expression: 
    {Expression}
    QualifiedName |
    NumberLiteral;

QualifiedName:
    ID ('.' ID)*;

NumberLiteral:
  value=INT;

// Card.mydsl

Cardpropertytypes {
    Toughness,
    Power,
    Flying,
    Indestructible
}
Card AdantoVanguard {
    ...
    properties {
        Toughness: 1,
        Power: 1,
        Flying
    }
    rules {
        {
            //action this.properties.Toughness + 2
            action ????
        }
    }
}

Clarification: If I have a Card model, which has properties as in the code sample above, I want to be able to say in the rules section:

this.properties.propertyName + 2

How can I achieve that?

in xtext cross references look like

ref=[SomeType]

which is short for

ref=[SomeType|ID]

which means that an ID will be parsed to refer to a SomeType so by replacing ID with another rule eg

ref=[SomeType|IDORTHIS]
...
IDORTHIS: ID | "this";

you can achieve the parsing side

for the scoping side you need to implement the scope provider

inside the scope provider

  • override getScope
  • use context and reference parameter to determine which reference is scoped
  • used the context to collect the elements you want to put into scope
  • create a new Scope eg using the methods inside the Scopes class or intantiating a SimpleScope manually / EObjectDescription.create or ..... (your requirements are very vague regarding this)

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